diff --git a/DEPS b/DEPS
index d6d16ee..8ef6260f 100644
--- a/DEPS
+++ b/DEPS
@@ -177,7 +177,7 @@
   # luci-go CIPD package version.
   # Make sure the revision is uploaded by infra-packagers builder.
   # https://ci.chromium.org/p/infra-internal/g/infra-packagers/console
-  'luci_go': 'git_revision:d7393d163ecb11c44626b3b221f86efdd2861565',
+  'luci_go': 'git_revision:bbac8f199026d706b08e53ca46d1a9560ae580d2',
 
   # This can be overridden, e.g. with custom_vars, to build clang from HEAD
   # instead of downloading the prebuilt pinned revision.
@@ -213,7 +213,7 @@
   # 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': 'be9a3d51b07069d6d4a070209436007df9e0637b',
+  'v8_revision': '3dc1a9e8a4fbb357b5e4e9c03c03264570c61fcb',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -229,7 +229,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '8c187c36bed654f91a8913208148d499b188d901',
+  'pdfium_revision': 'eba8001b8c69a192b5ee4eaff35620e3ccc50b21',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -288,7 +288,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': '2a1eac282becd3bea1cebbeb973f39d3b8667ab7',
+  'devtools_frontend_revision': '673b759e81afe3c85197d93a3b9b2e4e1f5d9b1b',
   # 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.
@@ -328,7 +328,7 @@
   # 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': '73c0190b4d39e190e50f42c1600f11623f9863d2',
+  'dawn_revision': '5542afcd026f22a5ad5e5695215ae25f334438b6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -966,7 +966,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '47a4b0bc5937e8309f1ed9abeb02fc5423e64bb0',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '5ab2f3314cfc45bdc4957fd2a760fd1f8e96ec90',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1438,7 +1438,7 @@
       'packages': [
           {
               'package': 'fuchsia/third_party/aemu/linux-amd64',
-              'version': 'JANUSSL6vlpZwl7eeXT1Jv3TTKfhHXjW18WlDQyun4kC'
+              'version': 'ojl1grR-C0-iz7AYRyPthptXgICXaLXzUhgb05zQaVQC'
           },
       ],
       'condition': 'host_os == "linux" and checkout_fuchsia',
@@ -1574,7 +1574,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'a03bb38c0e771a0b404753b8e65250e98719870f',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '46f5c11e4f4a87ccd9c36c03d121f93ed5d4ea0e',
+    Var('webrtc_git') + '/src.git' + '@' + '3d2a3355e33732a05bd438e28c7057bc43616f1d',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1601,7 +1601,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/linux-amd64',
-          'version': 'JUdOUf3QO1PSVW0LijuPE20E8IiVUgPjyUkhri9CrosC',
+          'version': '6gOkUwwapS1GyCkAQb7-gPiKnvzdUOyDzkT4NzmnYJEC',
         },
       ],
       'dep_type': 'cipd',
@@ -1611,7 +1611,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/windows-amd64',
-          'version': 'wL8AoIO8IDH7dKheA0iZneF9sE3DamLh6bBzj6I782oC',
+          'version': 'oodEEBUIHfKw18_-31PAsu3SFiLqvtsFDgbn6ohK5R4C',
         },
       ],
       'dep_type': 'cipd',
@@ -1621,7 +1621,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/mac-amd64',
-          'version': '-HuOY2pAKikKFvM5odfgh_GYbDKBGhCeKfGoDG4W46sC',
+          'version': '43qoaMWgldhQiaXzcCNggSSWDmZQTNrK0cGEt5yysgsC',
         },
       ],
       'dep_type': 'cipd',
@@ -1635,7 +1635,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@15b0ef0e832be7b65e840f14645b2fcaa78911e0',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3927470e5020eeb1f3847a9ecbe5c43d909763a2',
     'condition': 'checkout_src_internal',
   },
 
@@ -3716,7 +3716,7 @@
     'name': 'ciopfs_linux',
     'pattern': '.',
     'condition': 'checkout_win and host_os == "linux"',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -3833,7 +3833,7 @@
     'name': 'clang_format_win',
     'pattern': '.',
     'condition': 'host_os == "win"',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -3845,7 +3845,7 @@
     'name': 'clang_format_mac',
     'pattern': '.',
     'condition': 'host_os == "mac"',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -3857,7 +3857,7 @@
     'name': 'clang_format_linux',
     'pattern': '.',
     'condition': 'host_os == "linux"',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -3870,7 +3870,7 @@
     'name': 'rc_win',
     'pattern': '.',
     'condition': 'checkout_win and host_os == "win"',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -3882,7 +3882,7 @@
     'name': 'rc_mac',
     'pattern': '.',
     'condition': 'checkout_win and host_os == "mac"',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -3894,7 +3894,7 @@
     'name': 'rc_linux',
     'pattern': '.',
     'condition': 'checkout_win and host_os == "linux"',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -3905,7 +3905,8 @@
  {
     'name': 'test_fonts',
     'pattern': '.',
-    'action': [ 'download_from_google_storage',
+    'action': [ 'python3',
+                'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--extract',
                 '--no_auth',
@@ -3917,7 +3918,8 @@
   {
     'name': 'opus_test_files',
     'pattern': '.',
-    'action': ['download_from_google_storage',
+    'action': ['python3',
+               'src/third_party/depot_tools/download_from_google_storage.py',
                '--no_auth',
                '--quiet',
                '--bucket', 'chromium-webrtc-resources',
@@ -3927,7 +3929,7 @@
     'name': 'apache_mac',
     'pattern': '\\.sha1',
     'condition': 'checkout_mac',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--directory',
@@ -3942,7 +3944,7 @@
     'name': 'apache_win32',
     'pattern': '\\.sha1',
     'condition': 'checkout_win',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--directory',
@@ -3957,7 +3959,7 @@
     'name': 'msan_chained_origins',
     'pattern': '.',
     'condition': 'checkout_instrumented_libraries',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -3969,7 +3971,7 @@
     'name': 'msan_no_origins',
     'pattern': '.',
     'condition': 'checkout_instrumented_libraries',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -3980,7 +3982,7 @@
   {
     'name': 'wasm_fuzzer',
     'pattern': '.',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -3995,7 +3997,7 @@
     'name': 'node_linux64',
     'pattern': '.',
     'condition': 'host_os == "linux"',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--extract',
@@ -4008,7 +4010,7 @@
     'name': 'node_mac',
     'pattern': '.',
     'condition': 'host_os == "mac" and host_cpu == "x64"',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--extract',
@@ -4024,7 +4026,7 @@
     'name': 'node_mac_arm64',
     'pattern': '.',
     'condition': 'host_os == "mac" and host_cpu == "arm64"',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--extract',
@@ -4037,7 +4039,7 @@
     'name': 'node_win',
     'pattern': '.',
     'condition': 'host_os == "win"',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -4050,7 +4052,7 @@
   {
     'name': 'webui_node_modules',
     'pattern': '.',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--extract',
@@ -4123,7 +4125,7 @@
     'name': 'tools_traffic_annotation_linux',
     'pattern': '.',
     'condition': 'host_os == "linux" and checkout_traffic_annotation_tools',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -4139,7 +4141,7 @@
     'name': 'tools_traffic_annotation_windows',
     'pattern': '.',
     'condition': 'host_os == "win" and checkout_traffic_annotation_tools',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -4153,7 +4155,7 @@
   {
     'name': 'zucchini_testdata',
     'pattern': '.',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -4189,7 +4191,7 @@
     'name': 'gvr_static_shim_android_arm_1',
     'pattern': '\\.sha1',
     'condition': 'checkout_android',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -4201,7 +4203,7 @@
     'name': 'gvr_static_shim_android_arm_Cr',
     'pattern': '\\.sha1',
     'condition': 'checkout_android',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -4213,7 +4215,7 @@
     'name': 'gvr_static_shim_android_arm64_1',
     'pattern': '\\.sha1',
     'condition': 'checkout_android',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -4225,7 +4227,7 @@
     'name': 'gvr_static_shim_android_arm64_Cr',
     'pattern': '\\.sha1',
     'condition': 'checkout_android',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -4237,7 +4239,7 @@
     'name': 'vr_controller_test_api',
     'pattern': '\\.sha1',
     'condition': 'checkout_android',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
@@ -4274,7 +4276,7 @@
   {
     'name': 'subresource-filter-ruleset',
     'pattern': '.',
-    'action': [ 'python',
+    'action': [ 'python3',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
                 '--no_auth',
diff --git a/android_webview/browser/aw_feature_list_creator.cc b/android_webview/browser/aw_feature_list_creator.cc
index 7e9558f..c72640df 100644
--- a/android_webview/browser/aw_feature_list_creator.cc
+++ b/android_webview/browser/aw_feature_list_creator.cc
@@ -216,8 +216,7 @@
   // downloading and disseminating seeds is handled by the WebView service,
   // which itself doesn't support variations; therefore a bad seed shouldn't be
   // able to break seed downloads. See https://crbug.com/801771 for more info.
-  variations::SafeSeedManager ignored_safe_seed_manager(true,
-                                                        local_state_.get());
+  variations::SafeSeedManager ignored_safe_seed_manager(local_state_.get());
 
   // Populate FieldTrialList. Since low_entropy_provider is null, it will fall
   // back to the provider we previously gave to FieldTrialList, which is a low
diff --git a/android_webview/browser/aw_print_manager.cc b/android_webview/browser/aw_print_manager.cc
index 6946643..d4e52de6 100644
--- a/android_webview/browser/aw_print_manager.cc
+++ b/android_webview/browser/aw_print_manager.cc
@@ -29,10 +29,8 @@
                       scoped_refptr<base::RefCountedSharedMemoryMapping> data) {
   bool result = fd > base::kInvalidFd &&
                 base::IsValueInRangeForNumericType<int>(data->size());
-  if (result) {
-    int size = data->size();
-    result = base::WriteFileDescriptor(fd, data->front_as<char>(), size);
-  }
+  if (result)
+    result = base::WriteFileDescriptor(fd, *data);
   return result ? page_count : 0;
 }
 
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 2b842dd2..984d55c 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -290,6 +290,10 @@
 const base::Feature kEnableHostnameSetting{"EnableHostnameSetting",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
 
+// If enabled, the input device cards will be shown in the diagnostics app.
+const base::Feature kEnableInputInDiagnosticsApp{
+    "EnableInputInDiagnosticsApp", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enables LocalSearchService to be initialized.
 const base::Feature kEnableLocalSearchService{"EnableLocalSearchService",
                                               base::FEATURE_ENABLED_BY_DEFAULT};
@@ -845,6 +849,10 @@
   return base::FeatureList::IsEnabled(kGaiaReauthEndpoint);
 }
 
+bool IsInputInDiagnosticsAppEnabled() {
+  return base::FeatureList::IsEnabled(kEnableInputInDiagnosticsApp);
+}
+
 bool IsInputNoiseCancellationUiEnabled() {
   return base::FeatureList::IsEnabled(kEnableInputNoiseCancellationUi);
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 1fd6479..8f95e470 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -137,6 +137,8 @@
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kEnableHostnameSetting;
 COMPONENT_EXPORT(ASH_CONSTANTS)
+extern const base::Feature kEnableInputInDiagnosticsApp;
+COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kEnableLocalSearchService;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kEnableNetworkingInDiagnosticsApp;
@@ -372,6 +374,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsGaiaReauthEndpointEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsHostnameSettingEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsImeSandboxEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool IsInputInDiagnosticsAppEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS)
 bool IsInstantTetheringBackgroundAdvertisingSupported();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsKerberosSettingsSectionEnabled();
diff --git a/ash/content/shimless_rma/resources/BUILD.gn b/ash/content/shimless_rma/resources/BUILD.gn
index e9ab8b9..ec236eb 100644
--- a/ash/content/shimless_rma/resources/BUILD.gn
+++ b/ash/content/shimless_rma/resources/BUILD.gn
@@ -14,6 +14,7 @@
 polymer_element_files = [
   "base_page.js",
   "onboarding_landing_page.js",
+  "onboarding_update_page.js",
   "shimless_rma.js",
   "shimless_rma_shared_css.js",
 ]
@@ -50,6 +51,7 @@
   deps = [
     ":mojo_interface_provider",
     ":onboarding_landing_page",
+    ":onboarding_update_page",
     ":shimless_rma_types",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_elements/cr_button:cr_button.m",
@@ -84,6 +86,14 @@
   ]
 }
 
+js_library("onboarding_update_page") {
+  deps = [
+    ":mojo_interface_provider",
+    ":shimless_rma_types",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+  ]
+}
+
 js_library("shimless_rma_types") {
 }
 
diff --git a/ash/content/shimless_rma/resources/fake_shimless_rma_service.js b/ash/content/shimless_rma/resources/fake_shimless_rma_service.js
index 93285a3..9f9f004 100644
--- a/ash/content/shimless_rma/resources/fake_shimless_rma_service.js
+++ b/ash/content/shimless_rma/resources/fake_shimless_rma_service.js
@@ -68,7 +68,7 @@
      */
     this.setSkuResult_ = RmadErrorCode.kOk;
 
-    this.reset_();
+    this.reset();
   }
 
   /**
@@ -549,9 +549,8 @@
 
   /**
    * Disables all observers and resets provider to its initial state.
-   * @private
    */
-  reset_() {
+  reset() {
     this.methods_ = new FakeMethodResolver();
     this.registerMethods_();
 
diff --git a/ash/content/shimless_rma/resources/mojo_interface_provider.js b/ash/content/shimless_rma/resources/mojo_interface_provider.js
index 6c9e05aa..7b89c39 100644
--- a/ash/content/shimless_rma/resources/mojo_interface_provider.js
+++ b/ash/content/shimless_rma/resources/mojo_interface_provider.js
@@ -29,6 +29,10 @@
   ];
   service.setStates(states);
 
+  // TODO(joonbug): Set up shimless_rma_fakes module
+  service.setGetCurrentChromeVersionResult('90.4430.0.143');
+  service.setCheckForChromeUpdatesResult(true);
+
   // Set the fake service.
   setShimlessRmaServiceForTesting(service);
 }
diff --git a/ash/content/shimless_rma/resources/onboarding_update_page.html b/ash/content/shimless_rma/resources/onboarding_update_page.html
new file mode 100644
index 0000000..c18d8da
--- /dev/null
+++ b/ash/content/shimless_rma/resources/onboarding_update_page.html
@@ -0,0 +1,27 @@
+<style include="cr-shared-style shimless-rma-shared">
+</style>
+
+<base-page orientation="column">
+  <div slot="header">
+    <!-- TODO(joonbug): Update strings for i18n -->
+    <h1>Make sure Chrome OS is up to date</h1>
+    <p>Update to the latest version of Chrome OS for an optimized repair process.</p>
+    <p id="versionInfo">{{currentVersionText_}}</p>
+    <p id="networkUnavailable" hidden$="{{networkAvailable}}">
+      To check if OS is up to date, connect to the internet in previous screen
+    </p>
+    <p hidden$="{{!checkInProgress_}}">Checking OS version...</p>
+    <cr-button disabled="{{checkInProgress_}}"
+        hidden$="{{updateCheckBtnHidden_(networkAvailable, updateAvailable_)}}"
+        id="checkUpdate" on-click="onUpdateCheckBtnClicked_">
+      Check for updates
+    </cr-button>
+    <cr-button hidden$="{{!updateAvailable_}}"
+        id="performUpdate" on-click="onUpdateBtnClicked_">
+      Update version and restart
+    </cr-button>
+  </div>
+  <div slot="body">
+    <!-- TODO(joonbug): Fill with image -->
+  </div>
+</base-page>
diff --git a/ash/content/shimless_rma/resources/onboarding_update_page.js b/ash/content/shimless_rma/resources/onboarding_update_page.js
new file mode 100644
index 0000000..6673ea6
--- /dev/null
+++ b/ash/content/shimless_rma/resources/onboarding_update_page.js
@@ -0,0 +1,135 @@
+// 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 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import './shimless_rma_shared_css.js';
+
+import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {getShimlessRmaService} from './mojo_interface_provider.js';
+import {ShimlessRmaServiceInterface} from './shimless_rma_types.js';
+
+/**
+ * @fileoverview
+ * 'onboarding-update-page' is the page that checks to see if the version is up
+ * to date before starting the rma process.
+ */
+export class OnboardingUpdatePageElement extends PolymerElement {
+  static get is() {
+    return 'onboarding-update-page';
+  }
+
+  static get template() {
+    return html`{__html_template__}`;
+  }
+
+  static get properties() {
+    return {
+      /**
+       * @protected
+       * @type {string}
+       */
+      currentVersion: {
+        type: String,
+        value: '',
+      },
+
+      /**
+       * @protected
+       * @type {string}
+       */
+      currentVersionText_: {
+        type: String,
+        value: '',
+      },
+
+      /**
+       * TODO(joonbug): populate this and make private.
+       * @type {boolean}
+       */
+      networkAvailable: {
+        type: Boolean,
+        value: true,
+      },
+
+      /**
+       * @protected
+       * @type {boolean}
+       */
+      checkInProgress_: {
+        type: Boolean,
+        value: false,
+      },
+
+      /**
+       * @private
+       * @type {?ShimlessRmaServiceInterface}
+       */
+      shimlessRmaService_: {
+        type: Object,
+        value: null,
+      },
+
+      /**
+       * @protected
+       * @type {boolean}
+       */
+      updateAvailable_: {
+        type: Boolean,
+        value: false,
+      }
+    };
+  }
+
+  /** @override */
+  ready() {
+    super.ready();
+    this.shimlessRmaService_ = getShimlessRmaService();
+    this.getCurrentVersionText_();
+  }
+
+  /**
+   * @private
+   */
+  getCurrentVersionText_() {
+    this.shimlessRmaService_.getCurrentChromeVersion().then((res) => {
+      this.currentVersion = res.version;
+      this.currentVersionText_ = `Current version ${this.currentVersion}`;
+    });
+    // TODO(joonbug): i18n string
+  }
+
+  /** @protected */
+  onUpdateCheckBtnClicked_() {
+    this.checkInProgress_ = true;
+    this.shimlessRmaService_.checkForChromeUpdates().then((res) => {
+      if (res.updateAvailable) {
+        this.updateAvailable_ = true;
+        // TODO(joonbug): i18n string
+        this.currentVersionText_ =
+            `Current version ${this.currentVersion} is out of date`;
+      } else {
+        // TODO(joonbug): i18n string
+        this.currentVersionText_ =
+            `Current version ${this.currentVersion} is up to date`;
+      }
+      this.checkInProgress_ = false;
+    });
+  }
+
+  /** @protected */
+  onUpdateBtnClicked_() {
+    // TODO(joonbug): trigger update
+  }
+
+  /**
+   * @protected
+   */
+  updateCheckBtnHidden_() {
+    return !this.networkAvailable || this.updateAvailable_;
+  }
+};
+
+customElements.define(
+    OnboardingUpdatePageElement.is, OnboardingUpdatePageElement);
diff --git a/ash/content/shimless_rma/resources/shimless_rma.js b/ash/content/shimless_rma/resources/shimless_rma.js
index 9df9cfcf..6b5a268 100644
--- a/ash/content/shimless_rma/resources/shimless_rma.js
+++ b/ash/content/shimless_rma/resources/shimless_rma.js
@@ -4,6 +4,7 @@
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import './onboarding_landing_page.js';
+import './onboarding_update_page.js';
 import './shimless_rma_shared_css.js';
 
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
@@ -28,6 +29,7 @@
 const StateComponentMapping = {
   [RmaState.kUnknown]: {componentIs: 'badcomponent'},
   [RmaState.kWelcomeScreen]: {componentIs: 'onboarding-landing-page'},
+  [RmaState.kUpdateChrome]: {componentIs: 'onboarding-update-page'},
 };
 
 /**
diff --git a/ash/wm/full_restore/full_restore_controller.cc b/ash/wm/full_restore/full_restore_controller.cc
index afabaf3..58aa1b46 100644
--- a/ash/wm/full_restore/full_restore_controller.cc
+++ b/ash/wm/full_restore/full_restore_controller.cc
@@ -225,8 +225,16 @@
 
 void FullRestoreController::OnWindowVisibilityChanged(aura::Window* window,
                                                       bool visible) {
-  if (!windows_observation_.IsObservingSource(window))
+  if (!windows_observation_.IsObservingSource(window) &&
+      !to_be_shown_windows_.contains(window)) {
     return;
+  }
+
+  to_be_shown_windows_.erase(window);
+
+  // Arc app geometry is ready at this point so restore state type.
+  if (IsArcWindow(window))
+    RestoreStateTypeAndClearLaunchedKey(window);
 
   // Early return if `window` isn't visible, we're not in tablet mode, or the
   // app list is null.
@@ -252,52 +260,9 @@
   DCHECK(window->parent());
   windows_observation_.AddObservation(window);
 
-  std::unique_ptr<full_restore::WindowInfo> window_info =
-      g_read_window_callback_for_testing
-          ? g_read_window_callback_for_testing.Run(window)
-          : full_restore::GetWindowInfo(window);
-  if (window_info) {
-    // Snap the window if necessary.
-    auto state_type = window_info->window_state_type;
-    if (state_type) {
-      // Add the window to be tracked by the tablet mode window manager
-      // manually. It is normally tracked when it becomes visible, but in snap
-      // case we want to track it before it becomes visible. This will allow us
-      // to snap the window before it is shown and skip first showing the window
-      // in normal or maximized state.
-      // TODO(crbug.com/1164472): Investigate splitview for ARC apps, which
-      // are not managed by TabletModeWindowManager.
-      if (Shell::Get()->tablet_mode_controller()->InTabletMode())
-        Shell::Get()->tablet_mode_controller()->AddWindow(window);
-
-      if (*state_type == chromeos::WindowStateType::kLeftSnapped ||
-          *state_type == chromeos::WindowStateType::kRightSnapped) {
-        base::AutoReset<bool> auto_reset_is_restoring_snap_state(
-            &is_restoring_snap_state_, true);
-        const WMEvent snap_event(*state_type ==
-                                         chromeos::WindowStateType::kLeftSnapped
-                                     ? WM_EVENT_SNAP_LEFT
-                                     : WM_EVENT_SNAP_RIGHT);
-        WindowState::Get(window)->OnWMEvent(&snap_event);
-      }
-    }
-  }
-
-  // Window that are launched from full restore are not activatable initially to
-  // prevent them from taking activation when Widget::Show() is called. Make
-  // these windows activatable once they are launched. Use a post task since it
-  // is quite common for some widgets to explicitly call Show() after
-  // initialized.
-  // TODO(sammiequon): Instead of disabling activation when creating the widget
-  // and enabling it here, use ShowInactive() instead of Show() when the widget
-  // is created.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(
-                     [](aura::Window* window) {
-                       window->SetProperty(
-                           full_restore::kLaunchedFromFullRestoreKey, false);
-                     },
-                     window));
+  // Only restore state type for arc apps once their geometry is ready.
+  if (!IsArcWindow(window))
+    RestoreStateTypeAndClearLaunchedKey(window);
 
   int32_t* activation_index =
       window->GetProperty(full_restore::kActivationIndexKey);
@@ -417,6 +382,62 @@
     g_save_window_callback_for_testing.Run(window_info);
 }
 
+void FullRestoreController::RestoreStateTypeAndClearLaunchedKey(
+    aura::Window* window) {
+  std::unique_ptr<full_restore::WindowInfo> window_info =
+      g_read_window_callback_for_testing
+          ? g_read_window_callback_for_testing.Run(window)
+          : full_restore::GetWindowInfo(window);
+  if (window_info) {
+    // Snap the window if necessary.
+    auto state_type = window_info->window_state_type;
+    if (state_type) {
+      // Add the window to be tracked by the tablet mode window manager
+      // manually. It is normally tracked when it becomes visible, but in snap
+      // case we want to track it before it becomes visible. This will allow us
+      // to snap the window before it is shown and skip first showing the window
+      // in normal or maximized state.
+      // TODO(crbug.com/1164472): Investigate splitview for ARC apps, which
+      // are not managed by TabletModeWindowManager.
+      if (Shell::Get()->tablet_mode_controller()->InTabletMode())
+        Shell::Get()->tablet_mode_controller()->AddWindow(window);
+
+      if (*state_type == chromeos::WindowStateType::kLeftSnapped ||
+          *state_type == chromeos::WindowStateType::kRightSnapped) {
+        base::AutoReset<bool> auto_reset_is_restoring_snap_state(
+            &is_restoring_snap_state_, true);
+        const WMEvent snap_event(*state_type ==
+                                         chromeos::WindowStateType::kLeftSnapped
+                                     ? WM_EVENT_SNAP_LEFT
+                                     : WM_EVENT_SNAP_RIGHT);
+        WindowState::Get(window)->OnWMEvent(&snap_event);
+      }
+    }
+  }
+
+  // Window that are launched from full restore are not activatable initially to
+  // prevent them from taking activation when Widget::Show() is called. Make
+  // these windows activatable once they are launched. Use a post task since it
+  // is quite common for some widgets to explicitly call Show() after
+  // initialized.
+  // TODO(sammiequon): Instead of disabling activation when creating the widget
+  // and enabling it here, use ShowInactive() instead of Show() when the widget
+  // is created.
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(
+                     [](aura::Window* window) {
+                       // Since this an asynchronous task, `window` can be null
+                       // or destroying by the time the task is run so early
+                       // return in those cases.
+                       if (!window || window->is_destroying())
+                         return;
+
+                       window->SetProperty(
+                           full_restore::kLaunchedFromFullRestoreKey, false);
+                     },
+                     window));
+}
+
 void FullRestoreController::SetReadWindowCallbackForTesting(
     ReadWindowCallback callback) {
   g_read_window_callback_for_testing = std::move(callback);
diff --git a/ash/wm/full_restore/full_restore_controller.h b/ash/wm/full_restore/full_restore_controller.h
index 64ed1c1..5a67a5a 100644
--- a/ash/wm/full_restore/full_restore_controller.h
+++ b/ash/wm/full_restore/full_restore_controller.h
@@ -9,6 +9,7 @@
 #include "ash/public/cpp/session/session_observer.h"
 #include "ash/public/cpp/tablet_mode_observer.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
+#include "base/containers/flat_set.h"
 #include "base/scoped_multi_source_observation.h"
 #include "base/scoped_observation.h"
 #include "components/full_restore/full_restore_info.h"
@@ -108,6 +109,11 @@
   void SaveWindowImpl(WindowState* window_state,
                       base::Optional<int> activation_index);
 
+  // Retrieves the saved `WindowInfo` of `window` and restores its
+  // `WindowStateType`. Also creates a post task to clear `window`s
+  // `full_restore::kLaunchedFromFullRestoreKey`.
+  void RestoreStateTypeAndClearLaunchedKey(aura::Window* window);
+
   // Sets a callback for testing that will be read from in
   // `OnWidgetInitialized()`.
   void SetReadWindowCallbackForTesting(ReadWindowCallback callback);
@@ -123,6 +129,10 @@
   // True whenever we are stacking windows to match saved activation order.
   bool is_stacking_ = false;
 
+  // The set of windows that have had their widgets initialized and will be
+  // shown later.
+  base::flat_set<aura::Window*> to_be_shown_windows_;
+
   ScopedSessionObserver scoped_session_observer_{this};
 
   base::ScopedObservation<TabletModeController, TabletModeObserver>
diff --git a/base/files/file_descriptor_watcher_posix_unittest.cc b/base/files/file_descriptor_watcher_posix_unittest.cc
index 9b04cfb..f02675c 100644
--- a/base/files/file_descriptor_watcher_posix_unittest.cc
+++ b/base/files/file_descriptor_watcher_posix_unittest.cc
@@ -9,6 +9,7 @@
 #include <memory>
 
 #include "base/bind.h"
+#include "base/containers/span.h"
 #include "base/files/file_util.h"
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_pump_type.h"
@@ -126,8 +127,8 @@
 
   void WriteByte() {
     constexpr char kByte = '!';
-    ASSERT_TRUE(
-        WriteFileDescriptor(write_file_descriptor(), &kByte, sizeof(kByte)));
+    ASSERT_TRUE(WriteFileDescriptor(write_file_descriptor(),
+                                    as_bytes(make_span(&kByte, 1))));
   }
 
   void ReadByte() {
diff --git a/base/files/file_util.h b/base/files/file_util.h
index bd987501..f6cacc86 100644
--- a/base/files/file_util.h
+++ b/base/files/file_util.h
@@ -458,9 +458,13 @@
 BASE_EXPORT bool WriteFile(const FilePath& filename, StringPiece data);
 
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
-// Appends |data| to |fd|. Does not close |fd| when done.  Returns true iff
-// |size| bytes of |data| were written to |fd|.
-BASE_EXPORT bool WriteFileDescriptor(const int fd, const char* data, int size);
+// Appends |data| to |fd|. Does not close |fd| when done.  Returns true iff all
+// of |data| were written to |fd|.
+BASE_EXPORT bool WriteFileDescriptor(int fd, span<const uint8_t> data);
+
+// WriteFileDescriptor() variant that takes a StringPiece so callers don't have
+// to do manual conversions from a char span to a uint8_t span.
+BASE_EXPORT bool WriteFileDescriptor(int fd, StringPiece data);
 
 // Allocates disk space for the file referred to by |fd| for the byte range
 // starting at |offset| and continuing for |size| bytes. The file size will be
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc
index d1977e4..ef5fa18a 100644
--- a/base/files/file_util_posix.cc
+++ b/base/files/file_util_posix.cc
@@ -882,20 +882,26 @@
   if (fd < 0)
     return -1;
 
-  int bytes_written = WriteFileDescriptor(fd, data, size) ? size : -1;
+  int bytes_written =
+      WriteFileDescriptor(fd, StringPiece(data, size)) ? size : -1;
   if (IGNORE_EINTR(close(fd)) < 0)
     return -1;
   return bytes_written;
 }
 
-bool WriteFileDescriptor(const int fd, const char* data, int size) {
+bool WriteFileDescriptor(int fd, span<const uint8_t> data) {
+  return WriteFileDescriptor(
+      fd, StringPiece(reinterpret_cast<const char*>(data.data()), data.size()));
+}
+
+bool WriteFileDescriptor(int fd, StringPiece data) {
   // Allow for partial writes.
   ssize_t bytes_written_total = 0;
+  ssize_t size = checked_cast<ssize_t>(data.size());
   for (ssize_t bytes_written_partial = 0; bytes_written_total < size;
        bytes_written_total += bytes_written_partial) {
-    bytes_written_partial =
-        HANDLE_EINTR(write(fd, data + bytes_written_total,
-                           size - bytes_written_total));
+    bytes_written_partial = HANDLE_EINTR(write(
+        fd, data.data() + bytes_written_total, size - bytes_written_total));
     if (bytes_written_partial < 0)
       return false;
   }
@@ -993,8 +999,7 @@
   }
 
   // This call will either write all of the data or return false.
-  int size = checked_cast<int>(data.size());
-  if (!WriteFileDescriptor(fd, data.data(), size)) {
+  if (!WriteFileDescriptor(fd, data)) {
     VPLOG(1) << "Error while writing to file " << filename.value();
     ret = false;
   }
diff --git a/base/message_loop/message_pump_glib_unittest.cc b/base/message_loop/message_pump_glib_unittest.cc
index 951176e..3d0f941 100644
--- a/base/message_loop/message_pump_glib_unittest.cc
+++ b/base/message_loop/message_pump_glib_unittest.cc
@@ -673,7 +673,7 @@
                     const char* buf,
                     int size,
                     WaitableEvent* event) {
-  ASSERT_TRUE(WriteFileDescriptor(fd, buf, size));
+  ASSERT_TRUE(WriteFileDescriptor(fd, StringPiece(buf, size)));
 }
 
 }  // namespace
diff --git a/base/message_loop/message_pump_libevent_unittest.cc b/base/message_loop/message_pump_libevent_unittest.cc
index 06009b6..46db2ac8 100644
--- a/base/message_loop/message_pump_libevent_unittest.cc
+++ b/base/message_loop/message_pump_libevent_unittest.cc
@@ -11,6 +11,7 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/containers/span.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
@@ -222,7 +223,7 @@
                     const char* buf,
                     int size,
                     WaitableEvent* event) {
-  ASSERT_TRUE(WriteFileDescriptor(fd, buf, size));
+  ASSERT_TRUE(WriteFileDescriptor(fd, StringPiece(buf, size)));
 }
 
 // Tests that MessagePumpLibevent quits immediately when it is quit from
diff --git a/base/sync_socket_posix.cc b/base/sync_socket_posix.cc
index 35d290a7..86a47b5 100644
--- a/base/sync_socket_posix.cc
+++ b/base/sync_socket_posix.cc
@@ -19,6 +19,7 @@
 #endif
 
 #include "base/check_op.h"
+#include "base/containers/span.h"
 #include "base/files/file_util.h"
 #include "base/threading/scoped_blocking_call.h"
 #include "build/build_config.h"
@@ -38,9 +39,9 @@
   DCHECK_GT(length, 0u);
   DCHECK_LE(length, kMaxMessageLength);
   DCHECK_NE(handle, SyncSocket::kInvalidHandle);
-  const char* charbuffer = static_cast<const char*>(buffer);
-  return WriteFileDescriptor(handle, charbuffer, length)
-             ? static_cast<size_t>(length)
+  return WriteFileDescriptor(
+             handle, make_span(static_cast<const uint8_t*>(buffer), length))
+             ? length
              : 0;
 }
 
diff --git a/base/task/thread_pool/thread_pool_impl_unittest.cc b/base/task/thread_pool/thread_pool_impl_unittest.cc
index da9129dd..f07c98cb 100644
--- a/base/task/thread_pool/thread_pool_impl_unittest.cc
+++ b/base/task/thread_pool/thread_pool_impl_unittest.cc
@@ -17,6 +17,7 @@
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/cfi_buildflags.h"
+#include "base/containers/span.h"
 #include "base/debug/stack_trace.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/field_trial_params.h"
@@ -913,7 +914,7 @@
   thread_pool_->Shutdown();
 
   constexpr char kByte = '!';
-  ASSERT_TRUE(WriteFileDescriptor(pipes[1], &kByte, sizeof(kByte)));
+  ASSERT_TRUE(WriteFileDescriptor(pipes[1], as_bytes(make_span(&kByte, 1))));
 
   // Give a chance for the file watcher to fire before closing the handles.
   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 76f0ea07..53b8ef18 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-4.20210513.3.1
+4.20210514.0.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 76f0ea07..53b8ef18 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-4.20210513.3.1
+4.20210514.0.1
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java
index 9228d7b..954588b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java
@@ -18,7 +18,6 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.IntentUtils;
 import org.chromium.base.annotations.NativeMethods;
-import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.customtabs.CustomTabIncognitoManager;
@@ -53,16 +52,6 @@
     @SuppressLint("NewApi")
     public static boolean shouldDestroyIncognitoProfileOnStartup(
             boolean selectedTabModelIsIncognito) {
-        boolean result =
-                shouldDestroyIncognitoProfileOnStartupInternal(selectedTabModelIsIncognito);
-        RecordHistogram.recordBooleanHistogram(
-                "Android.ShouldDestroyIncognitoProfileOnStartup", result);
-        return result;
-    }
-
-    @SuppressLint("NewApi")
-    public static boolean shouldDestroyIncognitoProfileOnStartupInternal(
-            boolean selectedTabModelIsIncognito) {
         if (!Profile.getLastUsedRegularProfile().hasPrimaryOTRProfile()) {
             return false;
         }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 335a41b..88ba7c2 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -367,7 +367,7 @@
     Your device EID
   </message>
   <message name="IDS_CELLULAR_SETUP_EID_POPUP_DESCRIPTION" desc="Label shown when veiwing EID and QR code popup describing what an EID number is used for">
-    A customer service rep can use the EID number to help you activate service.
+    A customer service rep can use this EID number to help you activate service
   </message>
   <message name="IDS_CELLULAR_SETUP_EID_POPUP_A11Y_LABEL" desc="A11y label for EID and QR code dialog describing what the device's EID number is and what it's used for">
     Your device EID is <ph name="EID_NUMBER">$1<ex>123456789</ex></ph>. A customer service rep can use the EID number to help you activate service.
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_EID_POPUP_DESCRIPTION.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_EID_POPUP_DESCRIPTION.png.sha1
index d9e46c6d..7c2a2efa 100644
--- a/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_EID_POPUP_DESCRIPTION.png.sha1
+++ b/chrome/app/chromeos_strings_grdp/IDS_CELLULAR_SETUP_EID_POPUP_DESCRIPTION.png.sha1
@@ -1 +1 @@
-1370c675688d4ed5f806cfff35f05c1b16283fcf
\ No newline at end of file
+6c428ac447f4800ab02a6e7ec9a0d0a5bf5c87bc
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index 83d05fe4..dd68e14 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -300,6 +300,9 @@
   <message name="IDS_OS_SETTINGS_LANGUAGES_INPUT_PAGE_TITLE" desc="A page under “Languages and inputs” section in the OS settings page that users can add, remove and manage input methods.">
     Inputs
   </message>
+  <message name="IDS_OS_SETTINGS_LANGUAGES_INPUT_PAGE_TITLE_V2" desc="A page under “Languages and inputs” section in the OS settings page that users can add, remove and manage input methods.">
+    Inputs and keyboards
+  </message>
   <message name="IDS_OS_SETTINGS_LANGUAGES_DEVICE_LANGUAGE_TITLE" desc="The label for the section where users can see their device language. This language will be used for system surfaces (launcher, shelf, and notifications etc.).">
     Device language
   </message>
@@ -453,46 +456,18 @@
   <message name="IDS_OS_SETTINGS_LANGUAGES_NO_DICTIONARY_WORDS_LABEL" desc="Placeholder that is shown when there are no custom words in the list of saved custom words dictionary.">
     Saved custom words will appear here
   </message>
-  <message name="IDS_OS_SETTINGS_LANGUAGES_LIST_TITLE" desc="Title for the list of the user's preferred written languages.">
-    Languages
-  </message>
-  <message name="IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_ORDERING_INSTRUCTIONS" desc="Explanatory message about ordering the list of languages.">
-    Add languages or reorder list. <ph name="BEGIN_LINK">&lt;a&gt;</ph>Learn more<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>
-  </message>
-  <message name="IDS_SETTINGS_LANGUAGES_INPUT_METHODS_LIST_TITLE" desc="Title for the current input method in the header for the collapsible list of enabled input methods (keyboard layouts and input method editors).">
-    Input method
-  </message>
   <message name="IDS_SETTINGS_LANGUAGES_INPUT_METHOD_ENABLED" desc="Label underneath the currently active input method in the list of enabled input methods.">
     Enabled
   </message>
-  <message name="IDS_SETTINGS_LANGUAGES_INPUT_METHODS_EXPAND_ACCESSIBILITY_LABEL" desc="Label for the button that toggles showing the input options (keyboard and keyboard layouts). Only visible by screen reader software.">
-    Show input options
-  </message>
   <message name="IDS_SETTINGS_LANGUAGES_INPUT_METHODS_MANAGED_BY_POLICY" desc="Label which is shown on the manage input methods page if input methods are managed by policy.">
     Your administrator has limited the available input methods.
   </message>
-  <message name="IDS_SETTINGS_LANGUAGES_INPUT_METHODS_MANAGE" desc="Button under the list of input methods which opens a sub-page that lets the user enable or disable keyboard layouts and input method editors.">
-    Manage input methods
-  </message>
-  <message name="IDS_SETTINGS_LANGUAGES_MANAGE_INPUT_METHODS_TITLE" desc="Name of the settings sub-page which allows enabling and disabling input methods.">
-    Manage input methods
-  </message>
   <message name="IDS_SETTINGS_LANGUAGES_INPUT_METHOD_OPTIONS_TITLE" translateable="false" desc="Name of the settings sub-page which allows changing input method options.">
     Input method options
   </message>
   <message name="IDS_SETTINGS_LANGUAGES_SHOW_IME_MENU" desc="The label for the toggle button controlling showing the IME menu in the shelf.">
     Show input options in the shelf
   </message>
-  <message name="IDS_SETTINGS_LANGUAGES_RESTART_TO_DISPLAY_LANGUAGE" desc="The aria label to be read aloud to describe a button for restarting the device to change the device's UI language.">
-    Restart device to show system text in <ph name="LANGUAGE">$1<ex>English</ex></ph>
-  </message>
-  <message name="IDS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE" desc="The label used for a button that changes the UI language.">
-    Show system text in this language
-  </message>
-  <!-- The non-Chrome OS string is in settings_google_chrome_strings.grdp -->
-  <message name="IDS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE" desc="The label for a language that is currently used as the UI display language.">
-    System text is shown in this language
-  </message>
 
   <!-- Suggestions Section -->
   <message name="IDS_SETTINGS_SUGGESTIONS_TITLE" desc="The label for the suggestions section, which contains features to help users type faster or more expressively such as suggesting personal information or suggesting emoji to use.">
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_LANGUAGES_INPUT_PAGE_TITLE_V2.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_LANGUAGES_INPUT_PAGE_TITLE_V2.png.sha1
new file mode 100644
index 0000000..69828c8
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_LANGUAGES_INPUT_PAGE_TITLE_V2.png.sha1
@@ -0,0 +1 @@
+3065cdb2b22150d35d068beb1e801af4f038ed0f
\ No newline at end of file
diff --git a/chrome/app/settings_chromium_strings.grdp b/chrome/app/settings_chromium_strings.grdp
index 930da9f..f35f632 100644
--- a/chrome/app/settings_chromium_strings.grdp
+++ b/chrome/app/settings_chromium_strings.grdp
@@ -188,8 +188,7 @@
   </message>
 
   <!-- Languages Page -->
-  <!-- Chrome OS string is in settings_strings.grdp. -->
-  <if expr="not chromeos">
+  <if expr="is_win">
     <message name="IDS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE" desc="The label for a language that is currently used as the UI display language.">
       This language is used to display the Chromium UI
     </message>
diff --git a/chrome/app/settings_google_chrome_strings.grdp b/chrome/app/settings_google_chrome_strings.grdp
index cba55f6..0d669aa 100644
--- a/chrome/app/settings_google_chrome_strings.grdp
+++ b/chrome/app/settings_google_chrome_strings.grdp
@@ -189,8 +189,7 @@
   </message>
 
   <!-- Languages Page -->
-  <!-- Chrome OS string is in settings_strings.grdp. -->
-  <if expr="not chromeos">
+  <if expr="is_win">
     <message name="IDS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE" desc="The label for a language that is currently used as the UI display language.">
       This language is used to display the Google Chrome UI
     </message>
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn
index 3f633b2..a4a5151e 100644
--- a/chrome/app/vector_icons/BUILD.gn
+++ b/chrome/app/vector_icons/BUILD.gn
@@ -206,6 +206,8 @@
       "notification_wifi.icon",
       "notification_wifi_off.icon",
       "person_add.icon",
+      "sharesheet_link.icon",
+      "sharesheet_text.icon",
       "shutdown_guest_os.icon",
       "warning_badge_circle.icon",
     ]
diff --git a/chrome/app/vector_icons/sharesheet_link.icon b/chrome/app/vector_icons/sharesheet_link.icon
new file mode 100644
index 0000000..144b0b3
--- /dev/null
+++ b/chrome/app/vector_icons/sharesheet_link.icon
@@ -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.
+
+CANVAS_DIMENSIONS, 20,
+MOVE_TO, 14, 8,
+H_LINE_TO, 12,
+V_LINE_TO, 6,
+H_LINE_TO, 14,
+CUBIC_TO, 16.21f, 6, 18, 7.79f, 18, 10,
+CUBIC_TO, 18, 12.21f, 16.21f, 14, 14, 14,
+H_LINE_TO, 12,
+V_LINE_TO, 12,
+H_LINE_TO, 14,
+CUBIC_TO, 15.1f, 12, 16, 11.1f, 16, 10,
+CUBIC_TO, 16, 8.9f, 15.1f, 8, 14, 8,
+CLOSE,
+MOVE_TO, 8, 6,
+V_LINE_TO, 8,
+H_LINE_TO, 6,
+CUBIC_TO, 4.9f, 8, 4, 8.9f, 4, 10,
+CUBIC_TO, 4, 11.1f, 4.9f, 12, 6, 12,
+H_LINE_TO, 8,
+V_LINE_TO, 14,
+H_LINE_TO, 6,
+CUBIC_TO, 3.79f, 14, 2, 12.21f, 2, 10,
+CUBIC_TO, 2, 7.79f, 3.79f, 6, 6, 6,
+H_LINE_TO, 8,
+CLOSE,
+MOVE_TO, 13, 9,
+H_LINE_TO, 7,
+V_LINE_TO, 11,
+H_LINE_TO, 13,
+V_LINE_TO, 9,
+CLOSE
diff --git a/chrome/app/vector_icons/sharesheet_text.icon b/chrome/app/vector_icons/sharesheet_text.icon
new file mode 100644
index 0000000..3749d28
--- /dev/null
+++ b/chrome/app/vector_icons/sharesheet_text.icon
@@ -0,0 +1,25 @@
+// 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.
+
+CANVAS_DIMENSIONS, 20,
+MOVE_TO, 13, 4,
+H_LINE_TO, 3,
+R_V_LINE_TO, 2,
+R_H_LINE_TO, 4,
+R_V_LINE_TO, 10,
+R_H_LINE_TO, 2,
+V_LINE_TO, 6,
+R_H_LINE_TO, 4,
+V_LINE_TO, 4,
+CLOSE,
+MOVE_TO, 11, 8,
+R_H_LINE_TO, 6,
+R_V_LINE_TO, 2,
+R_H_LINE_TO, -2,
+R_V_LINE_TO, 6,
+R_H_LINE_TO, -2,
+R_V_LINE_TO, -6,
+R_H_LINE_TO, -2,
+V_LINE_TO, 8,
+CLOSE
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 0c53e8d..c9e119e6 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2797,9 +2797,6 @@
     {"enable-webassembly-simd", flag_descriptions::kEnableWasmSimdName,
      flag_descriptions::kEnableWasmSimdDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kWebAssemblySimd)},
-    {"enable-webassembly-threads", flag_descriptions::kEnableWasmThreadsName,
-     flag_descriptions::kEnableWasmThreadsDescription, kOsAll,
-     FEATURE_VALUE_TYPE(features::kWebAssemblyThreads)},
     {"enable-webassembly-tiering", flag_descriptions::kEnableWasmTieringName,
      flag_descriptions::kEnableWasmTieringDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kWebAssemblyTiering)},
@@ -7212,7 +7209,14 @@
      kOsDesktop | kOsAndroid,
      FEATURE_VALUE_TYPE(
          blink::features::
-             kThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframes)}
+             kThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframes)},
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+    {"enable-input-in-diagnostics-app",
+     flag_descriptions::kEnableInputInDiagnosticsAppName,
+     flag_descriptions::kEnableInputInDiagnosticsAppDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(chromeos::features::kEnableInputInDiagnosticsApp)},
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
     // NOTE: Adding a new flag requires adding a corresponding entry to enum
     // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag
diff --git a/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
index 2a8dfa9..851524d 100644
--- a/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
+++ b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
@@ -242,7 +242,7 @@
             // about:blank we should remove it to avoid leaving behind a blank
             // tab.
             if (tab_helper && !tab_helper->HasLoadedNonAboutBlankPage())
-              web_contents->Close();
+              web_contents->ClosePage();
 
             return content::NavigationThrottle::CANCEL_AND_IGNORE;
           }
diff --git a/chrome/browser/ash/arc/fileapi/file_stream_forwarder.cc b/chrome/browser/ash/arc/fileapi/file_stream_forwarder.cc
index e3bd6992..6e0535c 100644
--- a/chrome/browser/ash/arc/fileapi/file_stream_forwarder.cc
+++ b/chrome/browser/ash/arc/fileapi/file_stream_forwarder.cc
@@ -9,6 +9,7 @@
 
 #include "base/bind.h"
 #include "base/files/file_util.h"
+#include "base/strings/string_piece.h"
 #include "base/task/post_task.h"
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
@@ -118,8 +119,8 @@
       task_runner_.get(), FROM_HERE,
       base::BindOnce(
           [](int fd, scoped_refptr<net::IOBuffer> buf, int size) {
-            const bool result =
-                base::WriteFileDescriptor(fd, buf->data(), size);
+            const bool result = base::WriteFileDescriptor(
+                fd, base::StringPiece(buf->data(), size));
             PLOG_IF(ERROR, !result) << "Write failed.";
             return result;
           },
diff --git a/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc b/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
index 8b3093b..4aac762 100644
--- a/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
+++ b/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
@@ -1643,7 +1643,7 @@
 
   void Hide() override {}
 
-  void Bind(chromeos::ArcTermsOfServiceScreen* screen) override {}
+  void Bind(ash::ArcTermsOfServiceScreen* screen) override {}
 
   base::ObserverList<chromeos::ArcTermsOfServiceScreenViewObserver>::Unchecked
       observer_list_;
diff --git a/chrome/browser/ash/authpolicy/data_pipe_utils.cc b/chrome/browser/ash/authpolicy/data_pipe_utils.cc
index d4c956a2e..8684a03 100644
--- a/chrome/browser/ash/authpolicy/data_pipe_utils.cc
+++ b/chrome/browser/ash/authpolicy/data_pipe_utils.cc
@@ -19,8 +19,7 @@
   base::ScopedFD pipe_read_end(pipe_fds[0]);
   base::ScopedFD pipe_write_end(pipe_fds[1]);
 
-  if (!base::WriteFileDescriptor(pipe_write_end.get(), data.c_str(),
-                                 data.size())) {
+  if (!base::WriteFileDescriptor(pipe_write_end.get(), data)) {
     DLOG(ERROR) << "Failed to write to pipe";
     return base::ScopedFD();
   }
diff --git a/chrome/browser/ash/borealis/borealis_disk_manager.h b/chrome/browser/ash/borealis/borealis_disk_manager.h
new file mode 100644
index 0000000..7936cac
--- /dev/null
+++ b/chrome/browser/ash/borealis/borealis_disk_manager.h
@@ -0,0 +1,52 @@
+// 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 CHROME_BROWSER_ASH_BOREALIS_BOREALIS_DISK_MANAGER_H_
+#define CHROME_BROWSER_ASH_BOREALIS_BOREALIS_DISK_MANAGER_H_
+
+#include "base/callback.h"
+#include "chrome/browser/ash/borealis/infra/expected.h"
+
+namespace borealis {
+
+class BorealisContext;
+
+// Service responsible for managing borealis' disk space.
+class BorealisDiskManager {
+ public:
+  // Struct for storing the response of a GetDiskInfoRequest.
+  struct GetDiskInfoResponse {
+    // The number of bytes available for the client to use on the VM's disk.
+    // (This is the true amount of available space on the disk minus any space
+    // that is reserved for the buffer)
+    uint64_t available_bytes = 0;
+    // The number of bytes that the VM disk can be expanded by.
+    uint64_t expandable_bytes = 0;
+  };
+
+  BorealisDiskManager() = default;
+  ~BorealisDiskManager() = default;
+
+  // Gets information about the borealis disk and the host device, returns
+  // information about how the disk could be resized or an error.
+  virtual void GetDiskInfo(
+      base::OnceCallback<void(Expected<GetDiskInfoResponse, std::string>)>
+          callback) = 0;
+
+  // Attempt to expand the VM disk by the number of bytes specified. Returns the
+  // actual size increase in bytes, or an error.
+  virtual void RequestSpace(
+      uint64_t bytes_requested,
+      base::OnceCallback<void(Expected<uint64_t, std::string>)> callback) = 0;
+
+  // Attempt to shrink the VM disk by the number of bytes specified. Returns the
+  // actual size decrease in bytes, or an error.
+  virtual void ReleaseSpace(
+      uint64_t bytes_to_release,
+      base::OnceCallback<void(Expected<uint64_t, std::string>)> callback) = 0;
+};
+
+}  // namespace borealis
+
+#endif  // CHROME_BROWSER_ASH_BOREALIS_BOREALIS_DISK_MANAGER_H_
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc
index 78daa7f..adb6a4e1 100644
--- a/chrome/browser/ash/crosapi/browser_util.cc
+++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -559,9 +559,7 @@
     return base::ScopedFD();
   }
 
-  if (!base::WriteFileDescriptor(
-          fd.get(), reinterpret_cast<const char*>(serialized.data()),
-          serialized.size())) {
+  if (!base::WriteFileDescriptor(fd.get(), serialized)) {
     LOG(ERROR) << "Failed to dump the serialized startup data";
     return base::ScopedFD();
   }
diff --git a/chrome/browser/ash/login/configuration_keys.h b/chrome/browser/ash/login/configuration_keys.h
index befd06c7..1889065 100644
--- a/chrome/browser/ash/login/configuration_keys.h
+++ b/chrome/browser/ash/login/configuration_keys.h
@@ -65,6 +65,7 @@
 // source migration is finished.
 namespace ash {
 namespace configuration {
+using ::chromeos::configuration::kEnableDemoMode;
 using ::chromeos::configuration::kEnrollmentAssetId;
 using ::chromeos::configuration::kEnrollmentAutoAttributes;
 using ::chromeos::configuration::kEnrollmentLocation;
diff --git a/chrome/browser/ash/login/lock/views_screen_locker.h b/chrome/browser/ash/login/lock/views_screen_locker.h
index b91f0199..4210d157 100644
--- a/chrome/browser/ash/login/lock/views_screen_locker.h
+++ b/chrome/browser/ash/login/lock/views_screen_locker.h
@@ -10,13 +10,14 @@
 #include "base/time/time.h"
 #include "chrome/browser/ash/lock_screen_apps/focus_cycler_delegate.h"
 #include "chrome/browser/ash/login/lock/screen_locker.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ash/login/screens/user_selection_screen.h"
 #include "chrome/browser/ui/ash/login_screen_client_impl.h"
 #include "chromeos/dbus/power/power_manager_client.h"
 
 namespace chromeos {
 
 class UserBoardViewMojo;
-class UserSelectionScreen;
 class MojoSystemInfoDispatcher;
 
 // ViewsScreenLocker acts like LoginScreenClientImpl::Delegate which handles
diff --git a/chrome/browser/ash/login/lock_screen_utils.h b/chrome/browser/ash/login/lock_screen_utils.h
index 5125b91..41dea6fb 100644
--- a/chrome/browser/ash/login/lock_screen_utils.h
+++ b/chrome/browser/ash/login/lock_screen_utils.h
@@ -43,4 +43,16 @@
 }  // namespace lock_screen_utils
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+namespace lock_screen_utils {
+using ::chromeos::lock_screen_utils::EnforceDevicePolicyInputMethods;
+using ::chromeos::lock_screen_utils::FromListValueToLocaleItem;
+using ::chromeos::lock_screen_utils::GetUserLastInputMethod;
+using ::chromeos::lock_screen_utils::SetKeyboardSettings;
+using ::chromeos::lock_screen_utils::SetUserInputMethod;
+}  // namespace lock_screen_utils
+}  // namespace ash
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_LOCK_SCREEN_UTILS_H_
diff --git a/chrome/browser/ash/login/quick_unlock/quick_unlock_factory.h b/chrome/browser/ash/login/quick_unlock/quick_unlock_factory.h
index 9c3cea8b..073c7b1 100644
--- a/chrome/browser/ash/login/quick_unlock/quick_unlock_factory.h
+++ b/chrome/browser/ash/login/quick_unlock/quick_unlock_factory.h
@@ -55,4 +55,12 @@
 }  // namespace quick_unlock
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+namespace quick_unlock {
+using ::chromeos::quick_unlock::QuickUnlockFactory;
+}
+}  // namespace ash
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_QUICK_UNLOCK_QUICK_UNLOCK_FACTORY_H_
diff --git a/chrome/browser/ash/login/quick_unlock/quick_unlock_storage.h b/chrome/browser/ash/login/quick_unlock/quick_unlock_storage.h
index b2265da..af04767 100644
--- a/chrome/browser/ash/login/quick_unlock/quick_unlock_storage.h
+++ b/chrome/browser/ash/login/quick_unlock/quick_unlock_storage.h
@@ -104,4 +104,12 @@
 }  // namespace quick_unlock
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+namespace quick_unlock {
+using ::chromeos::quick_unlock::QuickUnlockStorage;
+}
+}  // namespace ash
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_QUICK_UNLOCK_QUICK_UNLOCK_STORAGE_H_
diff --git a/chrome/browser/ash/login/reauth_stats.h b/chrome/browser/ash/login/reauth_stats.h
index 2b63166..b2ccd9b 100644
--- a/chrome/browser/ash/login/reauth_stats.h
+++ b/chrome/browser/ash/login/reauth_stats.h
@@ -74,4 +74,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::ReauthReason;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_REAUTH_STATS_H_
diff --git a/chrome/browser/ash/login/saml/password_sync_token_checkers_collection.h b/chrome/browser/ash/login/saml/password_sync_token_checkers_collection.h
index 0905c01e..605ea40 100644
--- a/chrome/browser/ash/login/saml/password_sync_token_checkers_collection.h
+++ b/chrome/browser/ash/login/saml/password_sync_token_checkers_collection.h
@@ -52,4 +52,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::PasswordSyncTokenCheckersCollection;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_SAML_PASSWORD_SYNC_TOKEN_CHECKERS_COLLECTION_H_
diff --git a/chrome/browser/ash/login/saml/password_sync_token_login_checker.h b/chrome/browser/ash/login/saml/password_sync_token_login_checker.h
index 018d670..8eed68f 100644
--- a/chrome/browser/ash/login/saml/password_sync_token_login_checker.h
+++ b/chrome/browser/ash/login/saml/password_sync_token_login_checker.h
@@ -80,4 +80,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::PasswordSyncTokenLoginChecker;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_SAML_PASSWORD_SYNC_TOKEN_LOGIN_CHECKER_H_
diff --git a/chrome/browser/ash/login/screen_manager.h b/chrome/browser/ash/login/screen_manager.h
index cf6229e1..49938682 100644
--- a/chrome/browser/ash/login/screen_manager.h
+++ b/chrome/browser/ash/login/screen_manager.h
@@ -12,11 +12,11 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "chrome/browser/ash/login/oobe_screen.h"
+// TODO(https://crbug.com/1164001): move to forward declaration
+#include "chrome/browser/ash/login/screens/base_screen.h"
 
 namespace chromeos {
 
-class BaseScreen;
-
 // Class that manages creation and ownership of screens.
 class ScreenManager {
  public:
diff --git a/chrome/browser/ash/login/screens/active_directory_login_screen.cc b/chrome/browser/ash/login/screens/active_directory_login_screen.cc
index b98ae20..f4c445f3 100644
--- a/chrome/browser/ash/login/screens/active_directory_login_screen.cc
+++ b/chrome/browser/ash/login/screens/active_directory_login_screen.cc
@@ -19,6 +19,7 @@
 #include "components/user_manager/known_user.h"
 #include "ui/base/l10n/l10n_util.h"
 
+namespace ash {
 namespace {
 
 constexpr char kUserActionCancel[] = "cancel";
@@ -37,8 +38,6 @@
 
 }  // namespace
 
-namespace chromeos {
-
 ActiveDirectoryLoginScreen::ActiveDirectoryLoginScreen(
     ActiveDirectoryLoginView* view,
     ErrorScreen* error_screen,
@@ -93,8 +92,8 @@
 }
 
 bool ActiveDirectoryLoginScreen::HandleAccelerator(
-    ash::LoginAcceleratorAction action) {
-  if (action == ash::LoginAcceleratorAction::kCancelScreenAction) {
+    LoginAcceleratorAction action) {
+  if (action == LoginAcceleratorAction::kCancelScreenAction) {
     HandleCancel();
     return true;
   }
@@ -192,4 +191,4 @@
   }
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/active_directory_login_screen.h b/chrome/browser/ash/login/screens/active_directory_login_screen.h
index 5704a5f..16c4c99 100644
--- a/chrome/browser/ash/login/screens/active_directory_login_screen.h
+++ b/chrome/browser/ash/login/screens/active_directory_login_screen.h
@@ -13,12 +13,13 @@
 #include "chrome/browser/ash/authpolicy/authpolicy_helper.h"
 #include "chrome/browser/ash/login/screens/base_screen.h"
 #include "chrome/browser/ash/login/screens/error_screen.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chromeos/login/auth/key.h"
 
-namespace chromeos {
-
-class ActiveDirectoryLoginView;
-class Key;
+namespace ash {
 
 // Controller for the active directory login screen.
 class ActiveDirectoryLoginScreen
@@ -59,7 +60,7 @@
   void ShowImpl() override;
   void HideImpl() override;
   void OnUserAction(const std::string& action_id) override;
-  bool HandleAccelerator(ash::LoginAcceleratorAction action) override;
+  bool HandleAccelerator(LoginAcceleratorAction action) override;
 
   void ShowOfflineMessage(NetworkStateInformer::State state,
                           NetworkError::ErrorReason reason);
@@ -86,6 +87,12 @@
   base::WeakPtrFactory<ActiveDirectoryLoginScreen> weak_factory_{this};
 };
 
-}  // namespace chromeos
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace chromeos {
+using ::ash::ActiveDirectoryLoginScreen;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_ACTIVE_DIRECTORY_LOGIN_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/active_directory_password_change_screen.cc b/chrome/browser/ash/login/screens/active_directory_password_change_screen.cc
index c2bcfb9..b63514f1 100644
--- a/chrome/browser/ash/login/screens/active_directory_password_change_screen.cc
+++ b/chrome/browser/ash/login/screens/active_directory_password_change_screen.cc
@@ -15,7 +15,9 @@
 #include "components/user_manager/known_user.h"
 #include "ui/base/l10n/l10n_util.h"
 
+namespace ash {
 namespace {
+
 constexpr char kUserActionCancel[] = "cancel";
 
 // Possible error states of the Active Directory password change screen. Must be
@@ -26,9 +28,8 @@
   WRONG_OLD_PASSWORD = 1,
   NEW_PASSWORD_REJECTED = 2,
 };
-}  // namespace
 
-namespace chromeos {
+}  // namespace
 
 ActiveDirectoryPasswordChangeScreen::ActiveDirectoryPasswordChangeScreen(
     ActiveDirectoryPasswordChangeView* view,
@@ -139,4 +140,4 @@
   }
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/active_directory_password_change_screen.h b/chrome/browser/ash/login/screens/active_directory_password_change_screen.h
index d5a7b337..e147a5a0 100644
--- a/chrome/browser/ash/login/screens/active_directory_password_change_screen.h
+++ b/chrome/browser/ash/login/screens/active_directory_password_change_screen.h
@@ -11,15 +11,16 @@
 #include "chrome/browser/ash/authpolicy/authpolicy_helper.h"
 #include "chrome/browser/ash/login/screen_manager.h"
 #include "chrome/browser/ash/login/screens/base_screen.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chromeos/login/auth/key.h"
 
 namespace authpolicy {
 class ActiveDirectoryAccountInfo;
 }
 
-namespace chromeos {
-
-class ActiveDirectoryPasswordChangeView;
-class Key;
+namespace ash {
 
 // Controller for the active directory password change screen.
 class ActiveDirectoryPasswordChangeScreen : public BaseScreen {
@@ -76,6 +77,12 @@
   base::WeakPtrFactory<ActiveDirectoryPasswordChangeScreen> weak_factory_{this};
 };
 
-}  // namespace chromeos
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace chromeos {
+using ::ash::ActiveDirectoryPasswordChangeScreen;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_ACTIVE_DIRECTORY_PASSWORD_CHANGE_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/app_downloading_screen.cc b/chrome/browser/ash/login/screens/app_downloading_screen.cc
index 395e83e..da2d4e44 100644
--- a/chrome/browser/ash/login/screens/app_downloading_screen.cc
+++ b/chrome/browser/ash/login/screens/app_downloading_screen.cc
@@ -6,7 +6,7 @@
 
 #include "chrome/browser/ui/webui/chromeos/login/app_downloading_screen_handler.h"
 
-namespace chromeos {
+namespace ash {
 namespace {
 
 // When user clicks "Continue setup", this will be sent to chrome to indicate
@@ -49,4 +49,4 @@
   BaseScreen::OnUserAction(action_id);
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/app_downloading_screen.h b/chrome/browser/ash/login/screens/app_downloading_screen.h
index f363cc71..351e2bc 100644
--- a/chrome/browser/ash/login/screens/app_downloading_screen.h
+++ b/chrome/browser/ash/login/screens/app_downloading_screen.h
@@ -10,10 +10,10 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "chrome/browser/ash/login/screens/base_screen.h"
+// TODO(https://crbug.com/1164001): move to forward declaration
+#include "chrome/browser/ui/webui/chromeos/login/app_downloading_screen_handler.h"
 
-namespace chromeos {
-
-class AppDownloadingScreenView;
+namespace ash {
 
 // This is App Downloading screen that tells the user the selected Android apps
 // are being downloaded.
@@ -42,6 +42,12 @@
   DISALLOW_COPY_AND_ASSIGN(AppDownloadingScreen);
 };
 
-}  // namespace chromeos
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// migration is finished.
+namespace chromeos {
+using ::ash::AppDownloadingScreen;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_APP_DOWNLOADING_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/app_downloading_screen_browsertest.cc b/chrome/browser/ash/login/screens/app_downloading_screen_browsertest.cc
index a5233ea..c80e03e 100644
--- a/chrome/browser/ash/login/screens/app_downloading_screen_browsertest.cc
+++ b/chrome/browser/ash/login/screens/app_downloading_screen_browsertest.cc
@@ -31,8 +31,7 @@
 #include "content/public/test/browser_test.h"
 #include "ui/base/l10n/l10n_util.h"
 
-namespace chromeos {
-
+namespace ash {
 namespace {
 
 constexpr char kAppDownloadingId[] = "app-downloading";
@@ -43,8 +42,6 @@
 const test::UIPath kContinueSetupButton = {kAppDownloadingId,
                                            "continue-setup-button"};
 
-}  // namespace
-
 class AppDownloadingScreenTest : public OobeBaseTest {
  public:
   AppDownloadingScreenTest() = default;
@@ -178,4 +175,5 @@
   WaitForScreenExit();
 }
 
-}  // namespace chromeos
+}  // namespace
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/arc_terms_of_service_screen.cc b/chrome/browser/ash/login/screens/arc_terms_of_service_screen.cc
index 4b90905..b055c32 100644
--- a/chrome/browser/ash/login/screens/arc_terms_of_service_screen.cc
+++ b/chrome/browser/ash/login/screens/arc_terms_of_service_screen.cc
@@ -19,7 +19,7 @@
 #include "components/arc/arc_prefs.h"
 #include "components/prefs/pref_service.h"
 
-namespace chromeos {
+namespace ash {
 namespace {
 
 constexpr char kUserActionAcceptButtonClicked[] = "accept";
@@ -189,4 +189,4 @@
   view_ = nullptr;
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/arc_terms_of_service_screen.h b/chrome/browser/ash/login/screens/arc_terms_of_service_screen.h
index c1bf37d..05661aa8 100644
--- a/chrome/browser/ash/login/screens/arc_terms_of_service_screen.h
+++ b/chrome/browser/ash/login/screens/arc_terms_of_service_screen.h
@@ -14,9 +14,7 @@
 
 class Profile;
 
-namespace chromeos {
-
-class ArcTermsOfServiceScreenView;
+namespace ash {
 
 class ArcTermsOfServiceScreen : public BaseScreen,
                                 public ArcTermsOfServiceScreenViewObserver {
@@ -79,12 +77,12 @@
   DISALLOW_COPY_AND_ASSIGN(ArcTermsOfServiceScreen);
 };
 
-}  // namespace chromeos
+}  // namespace ash
 
 // TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
 // source migration is finished.
-namespace ash {
-using ::chromeos::ArcTermsOfServiceScreen;
+namespace chromeos {
+using ::ash ::ArcTermsOfServiceScreen;
 }
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_ARC_TERMS_OF_SERVICE_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/assistant_optin_flow_screen.cc b/chrome/browser/ash/login/screens/assistant_optin_flow_screen.cc
index 230b6f6..7460796 100644
--- a/chrome/browser/ash/login/screens/assistant_optin_flow_screen.cc
+++ b/chrome/browser/ash/login/screens/assistant_optin_flow_screen.cc
@@ -13,7 +13,7 @@
 #include "chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h"
 #include "chromeos/assistant/buildflags.h"
 
-namespace chromeos {
+namespace ash {
 namespace {
 
 constexpr const char kFlowFinished[] = "flow-finished";
@@ -100,4 +100,4 @@
     BaseScreen::OnUserAction(action_id);
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/assistant_optin_flow_screen.h b/chrome/browser/ash/login/screens/assistant_optin_flow_screen.h
index 5f572229..b2b3204 100644
--- a/chrome/browser/ash/login/screens/assistant_optin_flow_screen.h
+++ b/chrome/browser/ash/login/screens/assistant_optin_flow_screen.h
@@ -12,10 +12,10 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "chrome/browser/ash/login/screens/base_screen.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h"
 
-namespace chromeos {
-
-class AssistantOptInFlowScreenView;
+namespace ash {
 
 class AssistantOptInFlowScreen : public BaseScreen {
  public:
@@ -59,6 +59,12 @@
   DISALLOW_COPY_AND_ASSIGN(AssistantOptInFlowScreen);
 };
 
-}  // namespace chromeos
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace chromeos {
+using ::ash ::AssistantOptInFlowScreen;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_ASSISTANT_OPTIN_FLOW_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc b/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc
index cb8f4e0..0a172b0 100644
--- a/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc
+++ b/chrome/browser/ash/login/screens/assistant_optin_flow_screen_browsertest.cc
@@ -45,14 +45,17 @@
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
 
-using net::test_server::BasicHttpResponse;
-using net::test_server::HttpRequest;
-using net::test_server::HttpResponse;
+namespace ash {
 
-namespace chromeos {
+// TODO(https://crbug.com/1164001): remove when migrated to ash::
+namespace assistant = ::chromeos::assistant;
 
 namespace {
 
+using ::net::test_server::BasicHttpResponse;
+using ::net::test_server::HttpRequest;
+using ::net::test_server::HttpResponse;
+
 constexpr char kTestUser[] = "test-user1@gmail.com";
 
 constexpr char kAssistantConsentToken[] = "consent_token";
@@ -354,8 +357,6 @@
   DISALLOW_COPY_AND_ASSIGN(ScopedAssistantSettings);
 };
 
-}  // namespace
-
 class AssistantOptInFlowTest : public OobeBaseTest {
  public:
   AssistantOptInFlowTest() {
@@ -505,7 +506,7 @@
 IN_PROC_BROWSER_TEST_F(AssistantOptInFlowTest, Basic) {
   auto force_lib_assistant_enabled =
       AssistantOptInFlowScreen::ForceLibAssistantEnabledForTesting(true);
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   SetUpAssistantScreensForTest();
@@ -541,7 +542,7 @@
 IN_PROC_BROWSER_TEST_F(AssistantOptInFlowTest, DisableScreenContext) {
   auto force_lib_assistant_enabled =
       AssistantOptInFlowScreen::ForceLibAssistantEnabledForTesting(true);
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   SetUpAssistantScreensForTest();
@@ -584,7 +585,7 @@
   screen_waiter.set_assert_next_screen();
   screen_waiter.Wait();
 
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   test::OobeJS().CreateVisibilityWaiter(true, kAssistantValueProp)->Wait();
@@ -618,7 +619,7 @@
 
   ShowAssistantOptInFlowScreen();
 
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   OobeScreenWaiter screen_waiter(AssistantOptInFlowScreenView::kScreenId);
@@ -657,7 +658,7 @@
   auto force_lib_assistant_enabled =
       AssistantOptInFlowScreen::ForceLibAssistantEnabledForTesting(true);
   SetUpAssistantScreensForTest();
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   ShowAssistantOptInFlowScreen();
@@ -689,7 +690,7 @@
       AssistantOptInFlowScreen::ForceLibAssistantEnabledForTesting(true);
   assistant_settings_->set_consent_ui_flags(
       ScopedAssistantSettings::CONSENT_UI_FLAG_ASK_EMAIL_OPT_IN);
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   SetUpAssistantScreensForTest();
@@ -735,7 +736,7 @@
       AssistantOptInFlowScreen::ForceLibAssistantEnabledForTesting(true);
   assistant_settings_->set_consent_ui_flags(
       ScopedAssistantSettings::CONSENT_UI_FLAG_ASK_EMAIL_OPT_IN);
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   SetUpAssistantScreensForTest();
@@ -782,7 +783,7 @@
       ScopedAssistantSettings::CONSENT_UI_FLAG_SKIP_ACTIVITY_CONTROL);
 
   SetUpAssistantScreensForTest();
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   ShowAssistantOptInFlowScreen();
@@ -820,7 +821,7 @@
       ScopedAssistantSettings::CONSENT_UI_FLAG_SKIP_THIRD_PARTY_DISCLOSURE);
 
   SetUpAssistantScreensForTest();
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   ShowAssistantOptInFlowScreen();
@@ -858,7 +859,7 @@
       ScopedAssistantSettings::SpeakerIdEnrollmentMode::STEP_BY_STEP);
 
   SetUpAssistantScreensForTest();
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   ShowAssistantOptInFlowScreen();
@@ -929,7 +930,7 @@
       ScopedAssistantSettings::SpeakerIdEnrollmentMode::STEP_BY_STEP);
 
   SetUpAssistantScreensForTest();
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   ShowAssistantOptInFlowScreen();
@@ -978,7 +979,7 @@
       ScopedAssistantSettings::SpeakerIdEnrollmentMode::STEP_BY_STEP);
 
   SetUpAssistantScreensForTest();
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
 
   ShowAssistantOptInFlowScreen();
@@ -1032,7 +1033,7 @@
   assistant_settings_->set_consent_ui_flags(
       ScopedAssistantSettings::CONSENT_UI_FLAG_WAA_DISABLED_BY_POLICY);
 
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
   SetUpAssistantScreensForTest();
   ShowAssistantOptInFlowScreen();
@@ -1056,7 +1057,7 @@
   assistant_settings_->set_consent_ui_flags(
       ScopedAssistantSettings::CONSENT_UI_FLAG_ASSISTANT_DISABLED_BY_POLICY);
 
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
   SetUpAssistantScreensForTest();
   ShowAssistantOptInFlowScreen();
@@ -1078,7 +1079,7 @@
 IN_PROC_BROWSER_TEST_F(AssistantOptInFlowTest, AssistantSkippedNoLib) {
   auto force_lib_assistant_disabled =
       AssistantOptInFlowScreen::ForceLibAssistantEnabledForTesting(false);
-  ash::AssistantState::Get()->NotifyStatusChanged(
+  AssistantState::Get()->NotifyStatusChanged(
       chromeos::assistant::AssistantStatus::READY);
   SetUpAssistantScreensForTest();
   ShowAssistantOptInFlowScreen();
@@ -1093,4 +1094,5 @@
                                      0);
 }
 
-}  // namespace chromeos
+}  // namespace
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/base_screen.cc b/chrome/browser/ash/login/screens/base_screen.cc
index 5ebd57de..83f0bad 100644
--- a/chrome/browser/ash/login/screens/base_screen.cc
+++ b/chrome/browser/ash/login/screens/base_screen.cc
@@ -8,7 +8,7 @@
 #include "base/command_line.h"
 #include "base/logging.h"
 
-namespace chromeos {
+namespace ash {
 
 constexpr char BaseScreen::kNotApplicable[];
 
@@ -50,7 +50,7 @@
   OnUserAction(action_id);
 }
 
-bool BaseScreen::HandleAccelerator(ash::LoginAcceleratorAction action) {
+bool BaseScreen::HandleAccelerator(LoginAcceleratorAction action) {
   return false;
 }
 
@@ -58,4 +58,4 @@
   LOG(WARNING) << "Unhandled user action: action_id=" << action_id;
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/base_screen.h b/chrome/browser/ash/login/screens/base_screen.h
index 73c74c8..3d86135c 100644
--- a/chrome/browser/ash/login/screens/base_screen.h
+++ b/chrome/browser/ash/login/screens/base_screen.h
@@ -12,11 +12,11 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "chrome/browser/ash/login/oobe_screen.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ash/login/wizard_context.h"
 #include "components/login/base_screen_handler_utils.h"
 
-namespace chromeos {
-
-class WizardContext;
+namespace ash {
 
 // Base class for the all OOBE/login/before-session screens.
 // Screens are identified by ID, screen and it's JS counterpart must have same
@@ -46,7 +46,7 @@
   void HandleUserAction(const std::string& action_id);
 
   // Returns `true` if `action` was handled by the screen.
-  virtual bool HandleAccelerator(ash::LoginAcceleratorAction action);
+  virtual bool HandleAccelerator(LoginAcceleratorAction action);
 
   // Returns the identifier of the screen.
   OobeScreenId screen_id() const { return screen_id_; }
@@ -81,7 +81,13 @@
   DISALLOW_COPY_AND_ASSIGN(BaseScreen);
 };
 
-}  // namespace chromeos
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace chromeos {
+using ::ash::BaseScreen;
+}
 
 // TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
 // source migration is finished.
diff --git a/chrome/browser/ash/login/screens/chrome_user_selection_screen.cc b/chrome/browser/ash/login/screens/chrome_user_selection_screen.cc
index d282f68..d0aeecb95 100644
--- a/chrome/browser/ash/login/screens/chrome_user_selection_screen.cc
+++ b/chrome/browser/ash/login/screens/chrome_user_selection_screen.cc
@@ -33,7 +33,7 @@
 #include "components/user_manager/user_manager.h"
 #include "components/user_manager/user_type.h"
 
-namespace chromeos {
+namespace ash {
 
 ChromeUserSelectionScreen::ChromeUserSelectionScreen(
     DisplayedScreen display_type)
@@ -199,4 +199,4 @@
       show_full_management_disclosure);
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/chrome_user_selection_screen.h b/chrome/browser/ash/login/screens/chrome_user_selection_screen.h
index 8ebc72dc..5852e0a 100644
--- a/chrome/browser/ash/login/screens/chrome_user_selection_screen.h
+++ b/chrome/browser/ash/login/screens/chrome_user_selection_screen.h
@@ -17,7 +17,7 @@
 
 class AccountId;
 
-namespace chromeos {
+namespace ash {
 
 class ChromeUserSelectionScreen
     : public UserSelectionScreen,
@@ -75,6 +75,12 @@
   DISALLOW_COPY_AND_ASSIGN(ChromeUserSelectionScreen);
 };
 
-}  // namespace chromeos
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace chromeos {
+using ::ash::ChromeUserSelectionScreen;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_CHROME_USER_SELECTION_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector.cc b/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector.cc
index d0889c6..aa0c212 100644
--- a/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector.cc
+++ b/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector.cc
@@ -12,12 +12,13 @@
 #include "chrome/browser/chromeos/idle_detector.h"
 #include "chromeos/dbus/constants/dbus_switches.h"
 
-namespace chromeos {
-
+namespace ash {
 namespace {
+
 // Amount of time the user has to be idle for before giving the ChromeVox hint.
 const base::TimeDelta kChromeVoxHintIdleDuration =
     base::TimeDelta::FromSeconds(20);
+
 }  // namespace
 
 ChromeVoxHintDetector::ChromeVoxHintDetector(const base::TickClock* clock,
@@ -31,7 +32,7 @@
 
 void ChromeVoxHintDetector::StartIdleDetection() {
   if (!features::IsOobeChromeVoxHintEnabled() ||
-      chromeos::switches::IsOOBEChromeVoxHintTimerDisabledForTesting()) {
+      switches::IsOOBEChromeVoxHintTimerDisabledForTesting()) {
     return;
   }
 
@@ -39,7 +40,7 @@
   // the hint when flashing.
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kSystemDevMode) &&
-      !chromeos::switches::IsOOBEChromeVoxHintEnabledForDevMode()) {
+      !switches::IsOOBEChromeVoxHintEnabledForDevMode()) {
     return;
   }
 
@@ -62,4 +63,4 @@
   observer_->OnShouldGiveChromeVoxHint();
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector.h b/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector.h
index 399818b3..d73a4e36 100644
--- a/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector.h
+++ b/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector.h
@@ -8,13 +8,14 @@
 #include <memory>
 
 #include "base/memory/weak_ptr.h"
+// TODO(https://crbug.com/1164001): move to forward declaration
+#include "chrome/browser/chromeos/idle_detector.h"
 
 namespace base {
 class TickClock;
 }  // namespace base
 
-namespace chromeos {
-class IdleDetector;
+namespace ash {
 
 // Helper for ChromeVox hint idle detection.
 class ChromeVoxHintDetector {
@@ -50,6 +51,6 @@
   base::WeakPtrFactory<ChromeVoxHintDetector> weak_ptr_factory_{this};
 };
 
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_CHROMEVOX_HINT_CHROMEVOX_HINT_DETECTOR_H_
diff --git a/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector_unittest.cc b/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector_unittest.cc
index af4b67f..c53408e 100644
--- a/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector_unittest.cc
+++ b/chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector_unittest.cc
@@ -12,8 +12,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "ui/base/user_activity/user_activity_detector.h"
 
-namespace chromeos {
-
+namespace ash {
 namespace {
 
 // The ChromeVox hint idle duration is 20s. We set this to 25s, since it's safer
@@ -30,8 +29,6 @@
   MOCK_METHOD(void, OnShouldGiveChromeVoxHint, (), (override));
 };
 
-}  // namespace
-
 class ChromeVoxHintDetectorTest : public testing::Test {
  protected:
   ChromeVoxHintDetectorTest();
@@ -153,4 +150,5 @@
   runner_->FastForwardBy(kFullIdleDuration);
 }
 
-}  // namespace chromeos
+}  // namespace
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/demo_preferences_screen.cc b/chrome/browser/ash/login/screens/demo_preferences_screen.cc
index ea50327..2645b65 100644
--- a/chrome/browser/ash/login/screens/demo_preferences_screen.cc
+++ b/chrome/browser/ash/login/screens/demo_preferences_screen.cc
@@ -13,8 +13,7 @@
 #include "components/prefs/pref_service.h"
 #include "ui/base/ime/chromeos/input_method_descriptor.h"
 
-namespace chromeos {
-
+namespace ash {
 namespace {
 
 constexpr char kUserActionContinue[] = "continue-setup";
@@ -137,4 +136,4 @@
   }
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/demo_preferences_screen.h b/chrome/browser/ash/login/screens/demo_preferences_screen.h
index f757033..633843a 100644
--- a/chrome/browser/ash/login/screens/demo_preferences_screen.h
+++ b/chrome/browser/ash/login/screens/demo_preferences_screen.h
@@ -11,11 +11,11 @@
 #include "base/macros.h"
 #include "base/scoped_observation.h"
 #include "chrome/browser/ash/login/screens/base_screen.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ui/webui/chromeos/login/demo_preferences_screen_handler.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
 
-namespace chromeos {
-
-class DemoPreferencesScreenView;
+namespace ash {
 
 // Controls demo mode preferences. The screen can be shown during OOBE. It
 // allows user to choose preferences for retail demo mode.
@@ -75,6 +75,12 @@
   DISALLOW_COPY_AND_ASSIGN(DemoPreferencesScreen);
 };
 
-}  // namespace chromeos
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace chromeos {
+using ::ash::DemoPreferencesScreen;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_DEMO_PREFERENCES_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/demo_setup_screen.cc b/chrome/browser/ash/login/screens/demo_setup_screen.cc
index 4657c79..a0ca9eb 100644
--- a/chrome/browser/ash/login/screens/demo_setup_screen.cc
+++ b/chrome/browser/ash/login/screens/demo_setup_screen.cc
@@ -17,7 +17,7 @@
 
 }  // namespace
 
-namespace chromeos {
+namespace ash {
 
 // static
 std::string DemoSetupScreen::GetResultString(Result result) {
@@ -104,4 +104,4 @@
     view_ = nullptr;
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/demo_setup_screen.h b/chrome/browser/ash/login/screens/demo_setup_screen.h
index 098426f..de3a7534 100644
--- a/chrome/browser/ash/login/screens/demo_setup_screen.h
+++ b/chrome/browser/ash/login/screens/demo_setup_screen.h
@@ -12,10 +12,10 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ash/login/demo_mode/demo_setup_controller.h"
 #include "chrome/browser/ash/login/screens/base_screen.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ui/webui/chromeos/login/demo_setup_screen_handler.h"
 
-namespace chromeos {
-
-class DemoSetupScreenView;
+namespace ash {
 
 // Controls demo mode setup. The screen can be shown during OOBE. It allows
 // user to setup retail demo mode on the device.
@@ -67,12 +67,12 @@
   DISALLOW_COPY_AND_ASSIGN(DemoSetupScreen);
 };
 
-}  // namespace chromeos
+}  // namespace ash
 
 // TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
 // source migration is finished.
-namespace ash {
-using ::chromeos::DemoSetupScreen;
+namespace chromeos {
+using ::ash::DemoSetupScreen;
 }
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_DEMO_SETUP_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/device_disabled_screen.cc b/chrome/browser/ash/login/screens/device_disabled_screen.cc
index b6ae5af..85cf18e 100644
--- a/chrome/browser/ash/login/screens/device_disabled_screen.cc
+++ b/chrome/browser/ash/login/screens/device_disabled_screen.cc
@@ -11,12 +11,13 @@
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h"
 
-namespace chromeos {
-
+namespace ash {
 namespace {
+
 system::DeviceDisablingManager* DeviceDisablingManager() {
   return g_browser_process->platform_part()->device_disabling_manager();
 }
+
 }  // namespace
 
 DeviceDisabledScreen::DeviceDisabledScreen(DeviceDisabledScreenView* view)
@@ -61,4 +62,4 @@
     view_->UpdateMessage(disabled_message);
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/device_disabled_screen.h b/chrome/browser/ash/login/screens/device_disabled_screen.h
index f96b8f15..54ea442 100644
--- a/chrome/browser/ash/login/screens/device_disabled_screen.h
+++ b/chrome/browser/ash/login/screens/device_disabled_screen.h
@@ -8,10 +8,10 @@
 #include "base/macros.h"
 #include "chrome/browser/ash/login/screens/base_screen.h"
 #include "chrome/browser/ash/system/device_disabling_manager.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h"
 
-namespace chromeos {
-
-class DeviceDisabledScreenView;
+namespace ash {
 
 // Screen informing the user that the device has been disabled by its owner.
 class DeviceDisabledScreen : public BaseScreen,
@@ -37,6 +37,12 @@
   DISALLOW_COPY_AND_ASSIGN(DeviceDisabledScreen);
 };
 
-}  // namespace chromeos
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace chromeos {
+using ::ash::DeviceDisabledScreen;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_DEVICE_DISABLED_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/mock_device_disabled_screen_view.cc b/chrome/browser/ash/login/screens/mock_device_disabled_screen_view.cc
index 07e2ac0c..0877635e 100644
--- a/chrome/browser/ash/login/screens/mock_device_disabled_screen_view.cc
+++ b/chrome/browser/ash/login/screens/mock_device_disabled_screen_view.cc
@@ -10,7 +10,7 @@
 using ::testing::AtMost;
 using ::testing::NotNull;
 
-namespace chromeos {
+namespace ash {
 
 MockDeviceDisabledScreenView::MockDeviceDisabledScreenView()
     : screen_(nullptr) {
@@ -28,4 +28,4 @@
   MockBind(screen);
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/mock_device_disabled_screen_view.h b/chrome/browser/ash/login/screens/mock_device_disabled_screen_view.h
index a88ae2c..296e3b6 100644
--- a/chrome/browser/ash/login/screens/mock_device_disabled_screen_view.h
+++ b/chrome/browser/ash/login/screens/mock_device_disabled_screen_view.h
@@ -8,7 +8,7 @@
 #include "chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
-namespace chromeos {
+namespace ash {
 
 class MockDeviceDisabledScreenView : public DeviceDisabledScreenView {
  public:
@@ -30,6 +30,12 @@
   DeviceDisabledScreen* screen_;
 };
 
-}  // namespace chromeos
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace chromeos {
+using ::ash::MockDeviceDisabledScreenView;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_MOCK_DEVICE_DISABLED_SCREEN_VIEW_H_
diff --git a/chrome/browser/ash/login/screens/update_screen.cc b/chrome/browser/ash/login/screens/update_screen.cc
index 1d0218e..7022db7 100644
--- a/chrome/browser/ash/login/screens/update_screen.cc
+++ b/chrome/browser/ash/login/screens/update_screen.cc
@@ -94,7 +94,7 @@
     case Result::UPDATE_ERROR:
       return "UpdateError";
     case Result::UPDATE_SKIPPED:
-      return chromeos::BaseScreen::kNotApplicable;
+      return BaseScreen::kNotApplicable;
   }
 }
 
diff --git a/chrome/browser/ash/login/screens/user_selection_screen.cc b/chrome/browser/ash/login/screens/user_selection_screen.cc
index 02e222ae..f1142844 100644
--- a/chrome/browser/ash/login/screens/user_selection_screen.cc
+++ b/chrome/browser/ash/login/screens/user_selection_screen.cc
@@ -68,8 +68,7 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
 
-namespace chromeos {
-
+namespace ash {
 namespace {
 
 const char kWakeLockReason[] = "TPMLockedIssue";
@@ -124,21 +123,20 @@
 }
 
 // Determines the initial fingerprint state for the given user.
-ash::FingerprintState GetInitialFingerprintState(
-    const user_manager::User* user) {
+FingerprintState GetInitialFingerprintState(const user_manager::User* user) {
   // User must be logged in.
   if (!user->is_logged_in())
-    return ash::FingerprintState::UNAVAILABLE;
+    return FingerprintState::UNAVAILABLE;
 
   // Quick unlock storage must be available.
   quick_unlock::QuickUnlockStorage* quick_unlock_storage =
       quick_unlock::QuickUnlockFactory::GetForUser(user);
   if (!quick_unlock_storage)
-    return ash::FingerprintState::UNAVAILABLE;
+    return FingerprintState::UNAVAILABLE;
 
   // Fingerprint is not registered for this account.
   if (!quick_unlock_storage->fingerprint_storage()->HasRecord())
-    return ash::FingerprintState::UNAVAILABLE;
+    return FingerprintState::UNAVAILABLE;
 
   // Fingerprint unlock attempts should not be exceeded, as the lock screen has
   // not been displayed yet.
@@ -147,14 +145,14 @@
 
   // It has been too long since the last authentication.
   if (!quick_unlock_storage->HasStrongAuth())
-    return ash::FingerprintState::DISABLED_FROM_TIMEOUT;
+    return FingerprintState::DISABLED_FROM_TIMEOUT;
 
   // Auth is available.
   if (quick_unlock_storage->IsFingerprintAuthenticationAvailable())
-    return ash::FingerprintState::AVAILABLE_DEFAULT;
+    return FingerprintState::AVAILABLE_DEFAULT;
 
   // Default to unavailabe.
-  return ash::FingerprintState::UNAVAILABLE;
+  return FingerprintState::UNAVAILABLE;
 }
 
 // Returns true if dircrypto migration check should be performed.
@@ -213,7 +211,7 @@
 
 void GetMultiProfilePolicy(const user_manager::User* user,
                            bool* out_is_allowed,
-                           ash::MultiProfileUserBehavior* out_policy) {
+                           MultiProfileUserBehavior* out_policy) {
   const std::string& user_id = user->GetAccountId().GetUserEmail();
   MultiProfileUserController* multi_profile_user_controller =
       ChromeUserManager::Get()->GetMultiProfileUserController();
@@ -530,9 +528,9 @@
 }
 
 // static
-ash::UserAvatar UserSelectionScreen::BuildAshUserAvatarForUser(
+UserAvatar UserSelectionScreen::BuildAshUserAvatarForUser(
     const user_manager::User& user) {
-  ash::UserAvatar avatar;
+  UserAvatar avatar;
   avatar.image = user.GetImage();
   if (avatar.image.isNull()) {
     avatar.image = *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
@@ -639,9 +637,7 @@
   if (token_handle_util_->HasToken(account_id)) {
     token_handle_util_->CheckToken(
         account_id,
-        chromeos::ProfileHelper::Get()
-            ->GetSigninProfile()
-            ->GetURLLoaderFactory(),
+        ProfileHelper::Get()->GetSigninProfile()->GetURLLoaderFactory(),
         base::BindOnce(&UserSelectionScreen::OnUserStatusChecked,
                        weak_factory_.GetWeakPtr()));
   }
@@ -857,9 +853,9 @@
   service->AttemptAuth(account_id);
 }
 
-std::vector<ash::LoginUserInfo>
+std::vector<LoginUserInfo>
 UserSelectionScreen::UpdateAndReturnUserListForAsh() {
-  std::vector<ash::LoginUserInfo> user_info_list;
+  std::vector<LoginUserInfo> user_info_list;
 
   const AccountId owner = GetOwnerAccountId();
   const bool is_signin_to_add = IsSigninToAdd();
@@ -880,7 +876,7 @@
                    : proximity_auth::mojom::AuthType::OFFLINE_PASSWORD);
     user_auth_type_map_[account_id] = initial_auth_type;
 
-    ash::LoginUserInfo user_info;
+    LoginUserInfo user_info;
     user_info.basic_user_info.type = user->GetType();
     user_info.basic_user_info.account_id = user->GetAccountId();
 
@@ -1005,4 +1001,4 @@
   return EasyUnlockService::Get(profile);
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/user_selection_screen.h b/chrome/browser/ash/login/screens/user_selection_screen.h
index 3fb1f45d..4854559 100644
--- a/chrome/browser/ash/login/screens/user_selection_screen.h
+++ b/chrome/browser/ash/login/screens/user_selection_screen.h
@@ -35,6 +35,9 @@
 
 namespace chromeos {
 class UserBoardView;
+}
+
+namespace ash {
 
 enum class DisplayedScreen { SIGN_IN_SCREEN, USER_ADDING_SCREEN, LOCK_SCREEN };
 
@@ -48,7 +51,7 @@
   explicit UserSelectionScreen(DisplayedScreen display_type);
   ~UserSelectionScreen() override;
 
-  void SetView(UserBoardView* view);
+  void SetView(chromeos::UserBoardView* view);
 
   static const user_manager::UserList PrepareUserListForSending(
       const user_manager::UserList& users,
@@ -105,14 +108,13 @@
   static bool ShouldForceOnlineSignIn(const user_manager::User* user);
 
   // Builds a `UserAvatar` instance which contains the current image for `user`.
-  static ash::UserAvatar BuildAshUserAvatarForUser(
-      const user_manager::User& user);
+  static UserAvatar BuildAshUserAvatarForUser(const user_manager::User& user);
 
-  std::vector<ash::LoginUserInfo> UpdateAndReturnUserListForAsh();
+  std::vector<LoginUserInfo> UpdateAndReturnUserListForAsh();
   void SetUsersLoaded(bool loaded);
 
  protected:
-  UserBoardView* view_ = nullptr;
+  chromeos::UserBoardView* view_ = nullptr;
 
   // Map from public session account IDs to recommended locales set by policy.
   std::map<AccountId, std::vector<std::string>>
@@ -186,6 +188,13 @@
   DISALLOW_COPY_AND_ASSIGN(UserSelectionScreen);
 };
 
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace chromeos {
+using ::ash::DisplayedScreen;
+using ::ash::UserSelectionScreen;
 }  // namespace chromeos
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_USER_SELECTION_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/user_selection_screen_browsertest.cc b/chrome/browser/ash/login/screens/user_selection_screen_browsertest.cc
index 5405a5e..937b3a92 100644
--- a/chrome/browser/ash/login/screens/user_selection_screen_browsertest.cc
+++ b/chrome/browser/ash/login/screens/user_selection_screen_browsertest.cc
@@ -25,9 +25,9 @@
 #include "components/user_manager/known_user.h"
 #include "content/public/test/browser_test.h"
 
-namespace chromeos {
-
+namespace ash {
 namespace {
+
 constexpr char kUser1Email[] = "test-user1@gmail.com";
 constexpr char kGaia1ID[] = "111111";
 
@@ -47,8 +47,6 @@
 const test::UIPath kErrorMessageOfflineSigninLink = {
     "error-message", "error-offline-login-link"};
 
-}  // namespace
-
 class UserSelectionScreenTest : public LoginManagerTest {
  public:
   UserSelectionScreenTest() : LoginManagerTest() {
@@ -75,7 +73,7 @@
 IN_PROC_BROWSER_TEST_F(UserSelectionScreenTest, ShowDircryptoMigrationBanner) {
   const auto& users = login_manager_mixin_.users();
   // No banner for the first user since default is no migration.
-  EXPECT_FALSE(ash::LoginScreenTestApi::IsWarningBubbleShown());
+  EXPECT_FALSE(LoginScreenTestApi::IsWarningBubbleShown());
 
   std::unique_ptr<base::HistogramTester> histogram_tester =
       std::make_unique<base::HistogramTester>();
@@ -84,12 +82,12 @@
       true);
 
   // Focus the 2nd user pod (consumer).
-  ASSERT_TRUE(ash::LoginScreenTestApi::FocusUser(users[1].account_id));
+  ASSERT_TRUE(LoginScreenTestApi::FocusUser(users[1].account_id));
 
   // Wait for FakeUserDataAuthClient to send back the check result.
   test::TestPredicateWaiter(base::BindRepeating([]() {
     // Banner should be shown for the 2nd user (consumer).
-    return ash::LoginScreenTestApi::IsWarningBubbleShown();
+    return LoginScreenTestApi::IsWarningBubbleShown();
   })).Wait();
   histogram_tester->ExpectBucketCount("Ash.Login.Login.MigrationBanner", true,
                                       1);
@@ -99,12 +97,12 @@
       false);
   histogram_tester = std::make_unique<base::HistogramTester>();
   // Focus the 3rd user pod (consumer).
-  ASSERT_TRUE(ash::LoginScreenTestApi::FocusUser(users[2].account_id));
+  ASSERT_TRUE(LoginScreenTestApi::FocusUser(users[2].account_id));
 
   // Wait for FakeUserDataAuthClient to send back the check result.
   test::TestPredicateWaiter(base::BindRepeating([]() {
     // Banner should be shown for the 3rd user (consumer).
-    return !ash::LoginScreenTestApi::IsWarningBubbleShown();
+    return !LoginScreenTestApi::IsWarningBubbleShown();
   })).Wait();
   histogram_tester->ExpectBucketCount("Ash.Login.Login.MigrationBanner", false,
                                       1);
@@ -115,12 +113,12 @@
   histogram_tester = std::make_unique<base::HistogramTester>();
 
   // Focus to the 4th user pod (enterprise).
-  ASSERT_TRUE(ash::LoginScreenTestApi::FocusUser(users[3].account_id));
+  ASSERT_TRUE(LoginScreenTestApi::FocusUser(users[3].account_id));
 
   // Wait for FakeUserDataAuthClient to send back the check result.
   test::TestPredicateWaiter(base::BindRepeating([]() {
     // Banner should not be shown for the enterprise user.
-    return !ash::LoginScreenTestApi::IsWarningBubbleShown();
+    return !LoginScreenTestApi::IsWarningBubbleShown();
   })).Wait();
 
   // Not recorded for enterprise.
@@ -165,14 +163,12 @@
 IN_PROC_BROWSER_TEST_F(UserSelectionScreenEnforceOnlineTest,
                        IsOnlineLoginEnforced) {
   const auto& users = login_manager_mixin_.users();
-  EXPECT_FALSE(ash::LoginScreenTestApi::IsOobeDialogVisible());
-  EXPECT_TRUE(
-      ash::LoginScreenTestApi::IsForcedOnlineSignin(users[0].account_id));
-  EXPECT_FALSE(
-      ash::LoginScreenTestApi::IsForcedOnlineSignin(users[1].account_id));
-  EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(users[0].account_id));
+  EXPECT_FALSE(LoginScreenTestApi::IsOobeDialogVisible());
+  EXPECT_TRUE(LoginScreenTestApi::IsForcedOnlineSignin(users[0].account_id));
+  EXPECT_FALSE(LoginScreenTestApi::IsForcedOnlineSignin(users[1].account_id));
+  EXPECT_TRUE(LoginScreenTestApi::FocusUser(users[0].account_id));
   OobeScreenWaiter(GaiaView::kScreenId).Wait();
-  EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
+  EXPECT_TRUE(LoginScreenTestApi::IsOobeDialogVisible());
 }
 
 class UserSelectionScreenBlockOfflineTest : public LoginManagerTest,
@@ -202,11 +198,11 @@
 
  protected:
   void OpenGaiaDialog(const AccountId& account_id) {
-    EXPECT_FALSE(ash::LoginScreenTestApi::IsOobeDialogVisible());
-    EXPECT_TRUE(ash::LoginScreenTestApi::IsForcedOnlineSignin(account_id));
-    EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(account_id));
+    EXPECT_FALSE(LoginScreenTestApi::IsOobeDialogVisible());
+    EXPECT_TRUE(LoginScreenTestApi::IsForcedOnlineSignin(account_id));
+    EXPECT_TRUE(LoginScreenTestApi::FocusUser(account_id));
     OobeScreenWaiter(GaiaView::kScreenId).Wait();
-    EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
+    EXPECT_TRUE(LoginScreenTestApi::IsOobeDialogVisible());
   }
 
   const LoginManagerMixin::TestUserInfo test_user_over_the_limit_{
@@ -259,4 +255,5 @@
   test::OobeJS().ExpectVisiblePath(kErrorMessageOfflineSigninLink);
 }
 
-}  // namespace chromeos
+}  // namespace
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/welcome_screen.cc b/chrome/browser/ash/login/screens/welcome_screen.cc
index 7ab0294b..3f73ac9 100644
--- a/chrome/browser/ash/login/screens/welcome_screen.cc
+++ b/chrome/browser/ash/login/screens/welcome_screen.cc
@@ -42,7 +42,7 @@
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_thread.h"
 
-namespace chromeos {
+namespace ash {
 namespace {
 
 constexpr const char kRemoraRequisitionIdentifier[] = "remora";
@@ -151,7 +151,7 @@
   return true;
 #else
   return policy::EnrollmentRequisitionManager::IsRemoraRequisition() ||
-         chromeos::switches::IsDeviceRequisitionConfigurable();
+         switches::IsDeviceRequisitionConfigurable();
 #endif
 }
 
@@ -384,7 +384,7 @@
     return;
   }
   if (action_id == kUserActionSetupDemoModeGesture) {
-    HandleAccelerator(ash::LoginAcceleratorAction::kStartDemoMode);
+    HandleAccelerator(LoginAcceleratorAction::kStartDemoMode);
     return;
   }
   if (action_id == kUserActionActivateChromeVoxFromHint) {
@@ -402,12 +402,12 @@
   }
 
   if (action_id == kUserActionActivateRemoraRequisition) {
-    HandleAccelerator(ash::LoginAcceleratorAction::kDeviceRequisitionRemora);
+    HandleAccelerator(LoginAcceleratorAction::kDeviceRequisitionRemora);
     return;
   }
 
   if (action_id == kUserActionEditDeviceRequisition) {
-    HandleAccelerator(ash::LoginAcceleratorAction::kEditDeviceRequisition);
+    HandleAccelerator(LoginAcceleratorAction::kEditDeviceRequisition);
     return;
   }
 
@@ -451,8 +451,8 @@
   }
 }
 
-bool WelcomeScreen::HandleAccelerator(ash::LoginAcceleratorAction action) {
-  if (action == ash::LoginAcceleratorAction::kStartDemoMode) {
+bool WelcomeScreen::HandleAccelerator(LoginAcceleratorAction action) {
+  if (action == LoginAcceleratorAction::kStartDemoMode) {
     if (!DemoSetupController::IsDemoModeAllowed())
       return true;
     if (!view_)
@@ -467,19 +467,19 @@
 
     view_->ShowDemoModeConfirmationDialog();
     return true;
-  } else if (action == ash::LoginAcceleratorAction::kStartEnrollment) {
+  } else if (action == LoginAcceleratorAction::kStartEnrollment) {
     context()->enrollment_triggered_early = true;
     return true;
-  } else if (action == ash::LoginAcceleratorAction::kEnableDebugging) {
+  } else if (action == LoginAcceleratorAction::kEnableDebugging) {
     OnEnableDebugging();
     return true;
-  } else if (action == ash::LoginAcceleratorAction::kEditDeviceRequisition &&
+  } else if (action == LoginAcceleratorAction::kEditDeviceRequisition &&
              switches::IsDeviceRequisitionConfigurable()) {
     if (view_)
       view_->ShowEditRequisitionDialog(
           policy::EnrollmentRequisitionManager::GetDeviceRequisition());
     return true;
-  } else if (action == ash::LoginAcceleratorAction::kDeviceRequisitionRemora &&
+  } else if (action == LoginAcceleratorAction::kDeviceRequisitionRemora &&
              IsRemoraRequisitionConfigurable()) {
     if (view_)
       view_->ShowRemoraRequisitionDialog();
@@ -568,7 +568,7 @@
 }
 
 void WelcomeScreen::NotifyLocaleChange() {
-  ash::LocaleUpdateController::Get()->OnLocaleChanged();
+  LocaleUpdateController::Get()->OnLocaleChanged();
 }
 
 void WelcomeScreen::CancelChromeVoxHintIdleDetection() {
@@ -588,4 +588,4 @@
   return chromevox_hint_detector_.get();
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/screens/welcome_screen.h b/chrome/browser/ash/login/screens/welcome_screen.h
index 4112eba1..b743d7af 100644
--- a/chrome/browser/ash/login/screens/welcome_screen.h
+++ b/chrome/browser/ash/login/screens/welcome_screen.h
@@ -20,13 +20,14 @@
 #include "chrome/browser/ash/login/demo_mode/demo_mode_detector.h"
 #include "chrome/browser/ash/login/screens/base_screen.h"
 #include "chrome/browser/ash/login/screens/chromevox_hint/chromevox_hint_detector.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ash/login/ui/input_events_blocker.h"
 #include "chrome/browser/ash/login/wizard_context.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
 
-namespace chromeos {
-
-class InputEventsBlocker;
-class WelcomeView;
+namespace ash {
 
 class WelcomeScreen : public BaseScreen,
                       public input_method::InputMethodManager::Observer,
@@ -120,7 +121,7 @@
   void ShowImpl() override;
   void HideImpl() override;
   void OnUserAction(const std::string& action_id) override;
-  bool HandleAccelerator(ash::LoginAcceleratorAction action) override;
+  bool HandleAccelerator(LoginAcceleratorAction action) override;
 
   // ChromeVoxHintDetector::Observer:
   void OnShouldGiveChromeVoxHint() override;
@@ -158,9 +159,9 @@
   // Callback when the system timezone settings is changed.
   void OnSystemTimezoneChanged();
 
-  // Notifies locale change via ash::LocaleUpdateController.
+  // Notifies locale change via LocaleUpdateController.
   void NotifyLocaleChange();
-  void OnLocaleChangeResult(ash::LocaleNotificationResult result);
+  void OnLocaleChangeResult(LocaleNotificationResult result);
 
   WelcomeView* view_ = nullptr;
   ScreenExitCallback exit_callback_;
@@ -187,6 +188,12 @@
   DISALLOW_COPY_AND_ASSIGN(WelcomeScreen);
 };
 
-}  // namespace chromeos
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace chromeos {
+using ::ash::WelcomeScreen;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_WELCOME_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/welcome_screen_browsertest.cc b/chrome/browser/ash/login/screens/welcome_screen_browsertest.cc
index 914d07cc..9426ed3 100644
--- a/chrome/browser/ash/login/screens/welcome_screen_browsertest.cc
+++ b/chrome/browser/ash/login/screens/welcome_screen_browsertest.cc
@@ -45,7 +45,10 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/ime/chromeos/extension_ime_util.h"
 
-namespace chromeos {
+namespace ash {
+
+// TODO(https://crbug.com/1164001): remove when migrated to ash::
+namespace extension_ime_util = ::chromeos::extension_ime_util;
 
 namespace {
 
@@ -152,7 +155,7 @@
   // WelcomeScreenBrowserTest:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     WelcomeScreenBrowserTest::SetUpCommandLine(command_line);
-    command_line->AppendSwitch(chromeos::switches::kSystemDevMode);
+    command_line->AppendSwitch(switches::kSystemDevMode);
   }
 };
 
@@ -646,7 +649,7 @@
   OobeScreenWaiter(WelcomeView::kScreenId).Wait();
   TtsExtensionEngine::GetInstance()->DisableBuiltInTTSEngineForTesting();
   test::ExecuteOobeJS(kSetAvailableVoices);
-  ash::ShellTestApi().SetTabletModeEnabledForTest(true);
+  ShellTestApi().SetTabletModeEnabledForTest(true);
   test::SpeechMonitor monitor;
   GiveChromeVoxHintForTesting();
   monitor.ExpectSpeech(
@@ -795,7 +798,7 @@
 IN_PROC_BROWSER_TEST_F(WelcomeScreenChromeVoxHintTest, StatusTray) {
   OobeScreenWaiter(WelcomeView::kScreenId).Wait();
   ASSERT_FALSE(IdleDetectionCancelledForTesting());
-  ash::SystemTrayTestApi::Create()->ShowBubble();
+  SystemTrayTestApi::Create()->ShowBubble();
   ASSERT_TRUE(IdleDetectionCancelledForTesting());
 }
 
@@ -877,4 +880,4 @@
   WaitForSpokenSuccessMetric();
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/signin_specifics.h b/chrome/browser/ash/login/signin_specifics.h
index 058312e0..0e5c7ed 100644
--- a/chrome/browser/ash/login/signin_specifics.h
+++ b/chrome/browser/ash/login/signin_specifics.h
@@ -26,4 +26,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::SigninSpecifics;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_SIGNIN_SPECIFICS_H_
diff --git a/chrome/browser/ash/login/test/js_checker.h b/chrome/browser/ash/login/test/js_checker.h
index 7778174..7d89547 100644
--- a/chrome/browser/ash/login/test/js_checker.h
+++ b/chrome/browser/ash/login/test/js_checker.h
@@ -272,6 +272,7 @@
 using ::chromeos::test::CreateOobeScreenWaiter;
 using ::chromeos::test::ExecuteOobeJS;
 using ::chromeos::test::GetOobeElementPath;
+using ::chromeos::test::JSChecker;
 using ::chromeos::test::OobeJS;
 using ::chromeos::test::UIPath;
 }  // namespace test
diff --git a/chrome/browser/ash/login/test/local_state_mixin.h b/chrome/browser/ash/login/test/local_state_mixin.h
index 284e8f73..ec93cad 100644
--- a/chrome/browser/ash/login/test/local_state_mixin.h
+++ b/chrome/browser/ash/login/test/local_state_mixin.h
@@ -29,4 +29,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::LocalStateMixin;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_TEST_LOCAL_STATE_MIXIN_H_
diff --git a/chrome/browser/ash/login/test/offline_login_test_mixin.h b/chrome/browser/ash/login/test/offline_login_test_mixin.h
index 2892fc2..6732c322 100644
--- a/chrome/browser/ash/login/test/offline_login_test_mixin.h
+++ b/chrome/browser/ash/login/test/offline_login_test_mixin.h
@@ -60,4 +60,11 @@
 };
 
 }  // namespace chromeos
+
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::OfflineLoginTestMixin;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_TEST_OFFLINE_LOGIN_TEST_MIXIN_H_
diff --git a/chrome/browser/ash/login/test/oobe_screen_exit_waiter.h b/chrome/browser/ash/login/test/oobe_screen_exit_waiter.h
index 28af1e26..e0b63ca 100644
--- a/chrome/browser/ash/login/test/oobe_screen_exit_waiter.h
+++ b/chrome/browser/ash/login/test/oobe_screen_exit_waiter.h
@@ -54,4 +54,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::OobeScreenExitWaiter;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_TEST_OOBE_SCREEN_EXIT_WAITER_H_
diff --git a/chrome/browser/ash/login/test/oobe_screens_utils.h b/chrome/browser/ash/login/test/oobe_screens_utils.h
index e96bd02..de6da18a 100644
--- a/chrome/browser/ash/login/test/oobe_screens_utils.h
+++ b/chrome/browser/ash/login/test/oobe_screens_utils.h
@@ -61,6 +61,7 @@
 // source migration is finished.
 namespace ash {
 namespace test {
+using ::chromeos::test::LanguageReloadObserver;
 using ::chromeos::test::SkipToEnrollmentOnRecovery;
 using ::chromeos::test::TapEulaAccept;
 using ::chromeos::test::TapWelcomeNext;
diff --git a/chrome/browser/ash/login/ui/fake_login_display_host.cc b/chrome/browser/ash/login/ui/fake_login_display_host.cc
index 0766af6..19da11e 100644
--- a/chrome/browser/ash/login/ui/fake_login_display_host.cc
+++ b/chrome/browser/ash/login/ui/fake_login_display_host.cc
@@ -9,7 +9,7 @@
 
 namespace chromeos {
 
-class FakeLoginDisplayHost::FakeBaseScreen : public chromeos::BaseScreen {
+class FakeLoginDisplayHost::FakeBaseScreen : public BaseScreen {
  public:
   explicit FakeBaseScreen(chromeos::OobeScreenId screen_id)
       : BaseScreen(screen_id, OobeScreenPriority::DEFAULT) {}
@@ -17,7 +17,7 @@
   ~FakeBaseScreen() override = default;
 
  private:
-  // chromeos::BaseScreen:
+  // BaseScreen:
   void ShowImpl() override {}
   void HideImpl() override {}
 
diff --git a/chrome/browser/ash/login/ui/login_display_host_mojo.h b/chrome/browser/ash/login/ui/login_display_host_mojo.h
index fbcfad827d..4a47dc8d 100644
--- a/chrome/browser/ash/login/ui/login_display_host_mojo.h
+++ b/chrome/browser/ash/login/ui/login_display_host_mojo.h
@@ -32,12 +32,10 @@
 }  // namespace views
 
 namespace chromeos {
-
 class ExistingUserController;
 class LoginDisplayMojo;
 class OobeUIDialogDelegate;
 class UserBoardViewMojo;
-class UserSelectionScreen;
 class MojoSystemInfoDispatcher;
 
 // A LoginDisplayHost instance that sends requests to the views-based signin
diff --git a/chrome/browser/ash/login/ui/views/user_board_view.h b/chrome/browser/ash/login/ui/views/user_board_view.h
index f6c532ad..b8ea522e 100644
--- a/chrome/browser/ash/login/ui/views/user_board_view.h
+++ b/chrome/browser/ash/login/ui/views/user_board_view.h
@@ -11,14 +11,14 @@
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/oobe_screen.h"
+// TODO(https://crbug.com/1164001): move to forward declaration
+#include "chrome/browser/ash/login/screens/user_selection_screen.h"
 #include "chromeos/components/proximity_auth/screenlock_bridge.h"
 
 class AccountId;
 
 namespace chromeos {
 
-class UserSelectionScreen;
-
 // TODO(jdufault): Rename UserBoardView to UserSelectionView. See
 // crbug.com/672142.
 
@@ -59,4 +59,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::UserBoardView;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_UI_VIEWS_USER_BOARD_VIEW_H_
diff --git a/chrome/browser/ash/login/user_online_signin_notifier.h b/chrome/browser/ash/login/user_online_signin_notifier.h
index 78d6410..737cdea 100644
--- a/chrome/browser/ash/login/user_online_signin_notifier.h
+++ b/chrome/browser/ash/login/user_online_signin_notifier.h
@@ -53,4 +53,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::UserOnlineSigninNotifier;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_USER_ONLINE_SIGNIN_NOTIFIER_H_
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc
index bb6d6b2..f4b065cf 100644
--- a/chrome/browser/ash/login/wizard_controller.cc
+++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -533,7 +533,7 @@
         base::BindRepeating(&WizardController::OnWelcomeScreenExit,
                             weak_factory_.GetWeakPtr())));
 
-    append(std::make_unique<chromeos::DemoPreferencesScreen>(
+    append(std::make_unique<DemoPreferencesScreen>(
         oobe_ui->GetView<DemoPreferencesScreenHandler>(),
         base::BindRepeating(&WizardController::OnDemoPreferencesScreenExit,
                             weak_factory_.GetWeakPtr())));
@@ -560,7 +560,7 @@
       oobe_ui->GetView<ResetScreenHandler>(), oobe_ui->GetErrorScreen(),
       base::BindRepeating(&WizardController::OnResetScreenExit,
                           weak_factory_.GetWeakPtr())));
-  append(std::make_unique<chromeos::DemoSetupScreen>(
+  append(std::make_unique<DemoSetupScreen>(
       oobe_ui->GetView<DemoSetupScreenHandler>(),
       base::BindRepeating(&WizardController::OnDemoSetupScreenExit,
                           weak_factory_.GetWeakPtr())));
@@ -1063,7 +1063,7 @@
   VLOG(1) << "Wizard screen " << screen
           << " exited with reason: " << exit_reason;
   // Do not perform checks and record stats for the skipped screen.
-  if (exit_reason == chromeos::BaseScreen::kNotApplicable)
+  if (exit_reason == BaseScreen::kNotApplicable)
     return;
   DCHECK(current_screen_->screen_id() == screen);
 
diff --git a/chrome/browser/ash/system/automatic_reboot_manager.cc b/chrome/browser/ash/system/automatic_reboot_manager.cc
index 1dd61fca..f8539d17 100644
--- a/chrome/browser/ash/system/automatic_reboot_manager.cc
+++ b/chrome/browser/ash/system/automatic_reboot_manager.cc
@@ -102,8 +102,7 @@
 
   std::string update_reboot_needed_uptime =
       base::NumberToString(uptime.InSecondsF());
-  base::WriteFileDescriptor(fd.get(), update_reboot_needed_uptime.c_str(),
-                            update_reboot_needed_uptime.size());
+  base::WriteFileDescriptor(fd.get(), update_reboot_needed_uptime);
 }
 
 }  // namespace
diff --git a/chrome/browser/autofill/android/save_address_profile_prompt_controller.cc b/chrome/browser/autofill/android/save_address_profile_prompt_controller.cc
index adbf24c..676c267 100644
--- a/chrome/browser/autofill/android/save_address_profile_prompt_controller.cc
+++ b/chrome/browser/autofill/android/save_address_profile_prompt_controller.cc
@@ -97,10 +97,12 @@
 SaveAddressProfilePromptController::GetDiffFromOldToNewProfile() {
   DCHECK(original_profile_);
   base::flat_map<ServerFieldType, std::pair<std::u16string, std::u16string>>
-      differences =
-          AutofillProfileComparator::GetSettingsVisibleProfileDifferenceMap(
-              original_profile_.value(), profile_,
-              g_browser_process->GetApplicationLocale());
+      differences = AutofillProfileComparator::GetProfileDifferenceMap(
+          original_profile_.value(), profile_,
+          autofill::ServerFieldTypeSet(
+              std::begin(kVisibleTypesForProfileDifferences),
+              std::end(kVisibleTypesForProfileDifferences)),
+          g_browser_process->GetApplicationLocale());
   std::vector<std::u16string> old_values;
   std::vector<std::u16string> new_values;
   for (auto type : kVisibleTypesForProfileDifferences) {
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index ef87e64..ebb34bd 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -5674,7 +5674,7 @@
   DCHECK(profile);
 
   content::PermissionController* permission_controller =
-      content::BrowserContext::GetPermissionController(browser_context);
+      browser_context->GetPermissionController();
   blink::mojom::PermissionStatus status =
       permission_controller->GetPermissionStatusForFrame(
           content::PermissionType::CLIPBOARD_READ_WRITE, render_frame_host,
diff --git a/chrome/browser/chrome_shared_array_buffer_browsertest.cc b/chrome/browser/chrome_shared_array_buffer_browsertest.cc
index 084fc1f..13b81cbe 100644
--- a/chrome/browser/chrome_shared_array_buffer_browsertest.cc
+++ b/chrome/browser/chrome_shared_array_buffer_browsertest.cc
@@ -34,7 +34,6 @@
         // Disabled:
         {
             features::kSharedArrayBuffer,
-            features::kWebAssemblyThreads,
             features::kSharedArrayBufferOnDesktop,
         });
   }
diff --git a/chrome/browser/chromeos/extensions/file_manager/event_router.cc b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
index b9daedf..bc3f5c0 100644
--- a/chrome/browser/chromeos/extensions/file_manager/event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
@@ -179,21 +179,26 @@
   return file_manager_private::MOUNT_COMPLETED_STATUS_NONE;
 }
 
-file_manager_private::CopyProgressStatusType
-CopyProgressTypeToCopyProgressStatusType(
-    storage::FileSystemOperation::CopyProgressType type) {
+file_manager_private::CopyOrMoveProgressStatusType
+CopyOrMoveProgressTypeToCopyOrMoveProgressStatusType(
+    storage::FileSystemOperation::CopyOrMoveProgressType type) {
   switch (type) {
-    case storage::FileSystemOperation::BEGIN_COPY_ENTRY:
-      return file_manager_private::COPY_PROGRESS_STATUS_TYPE_BEGIN_COPY_ENTRY;
-    case storage::FileSystemOperation::END_COPY_ENTRY:
-      return file_manager_private::COPY_PROGRESS_STATUS_TYPE_END_COPY_ENTRY;
-    case storage::FileSystemOperation::PROGRESS:
-      return file_manager_private::COPY_PROGRESS_STATUS_TYPE_PROGRESS;
-    case storage::FileSystemOperation::ERROR_COPY_ENTRY:
-      return file_manager_private::COPY_PROGRESS_STATUS_TYPE_ERROR;
+    case storage::FileSystemOperation::CopyOrMoveProgressType::kBegin:
+      return file_manager_private::COPY_OR_MOVE_PROGRESS_STATUS_TYPE_BEGIN;
+    case storage::FileSystemOperation::CopyOrMoveProgressType::kProgress:
+      return file_manager_private::COPY_OR_MOVE_PROGRESS_STATUS_TYPE_PROGRESS;
+    case storage::FileSystemOperation::CopyOrMoveProgressType::kEndCopy:
+      return file_manager_private::COPY_OR_MOVE_PROGRESS_STATUS_TYPE_END_COPY;
+    case storage::FileSystemOperation::CopyOrMoveProgressType::kEndMove:
+      return file_manager_private::COPY_OR_MOVE_PROGRESS_STATUS_TYPE_END_MOVE;
+    case storage::FileSystemOperation::CopyOrMoveProgressType::kEndRemoveSource:
+      return file_manager_private::
+          COPY_OR_MOVE_PROGRESS_STATUS_TYPE_END_REMOVE_SOURCE;
+    case storage::FileSystemOperation::CopyOrMoveProgressType::kError:
+      return file_manager_private::COPY_OR_MOVE_PROGRESS_STATUS_TYPE_ERROR;
   }
   NOTREACHED();
-  return file_manager_private::COPY_PROGRESS_STATUS_TYPE_NONE;
+  return file_manager_private::COPY_OR_MOVE_PROGRESS_STATUS_TYPE_NONE;
 }
 
 std::string FileErrorToErrorName(base::File::Error error_code) {
@@ -611,16 +616,17 @@
                                   base::File::Error error) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  file_manager_private::CopyProgressStatus status;
+  file_manager_private::CopyOrMoveProgressStatus status;
   if (error == base::File::FILE_OK) {
     // Send success event.
-    status.type = file_manager_private::COPY_PROGRESS_STATUS_TYPE_SUCCESS;
+    status.type =
+        file_manager_private::COPY_OR_MOVE_PROGRESS_STATUS_TYPE_SUCCESS;
     status.source_url = std::make_unique<std::string>(source_url.spec());
     status.destination_url =
         std::make_unique<std::string>(destination_url.spec());
   } else {
     // Send error event.
-    status.type = file_manager_private::COPY_PROGRESS_STATUS_TYPE_ERROR;
+    status.type = file_manager_private::COPY_OR_MOVE_PROGRESS_STATUS_TYPE_ERROR;
     status.error = std::make_unique<std::string>(FileErrorToErrorName(error));
   }
 
@@ -632,33 +638,34 @@
 
 void EventRouter::OnCopyProgress(
     int copy_id,
-    storage::FileSystemOperation::CopyProgressType type,
+    storage::FileSystemOperation::CopyOrMoveProgressType type,
     const GURL& source_url,
     const GURL& destination_url,
     int64_t size) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  file_manager_private::CopyProgressStatus status;
-  status.type = CopyProgressTypeToCopyProgressStatusType(type);
+  file_manager_private::CopyOrMoveProgressStatus status;
+  status.type = CopyOrMoveProgressTypeToCopyOrMoveProgressStatusType(type);
   status.source_url = std::make_unique<std::string>(source_url.spec());
-  if (type == storage::FileSystemOperation::END_COPY_ENTRY ||
-      type == storage::FileSystemOperation::ERROR_COPY_ENTRY)
+  if (type !=
+      storage::FileSystemOperation::CopyOrMoveProgressType::kEndRemoveSource)
     status.destination_url =
         std::make_unique<std::string>(destination_url.spec());
-  if (type == storage::FileSystemOperation::ERROR_COPY_ENTRY)
+  if (type == storage::FileSystemOperation::CopyOrMoveProgressType::kError)
     status.error = std::make_unique<std::string>(
         FileErrorToErrorName(base::File::FILE_ERROR_FAILED));
-  if (type == storage::FileSystemOperation::PROGRESS)
+  if (type == storage::FileSystemOperation::CopyOrMoveProgressType::kProgress)
     status.size = std::make_unique<double>(size);
 
   // Discard error progress since current JS code cannot handle this properly.
   // TODO(yawano): Remove this after JS side is implemented correctly.
-  if (type == storage::FileSystemOperation::ERROR_COPY_ENTRY)
+  if (type == storage::FileSystemOperation::CopyOrMoveProgressType::kError)
     return;
 
   // Should not skip events other than TYPE_PROGRESS.
   const bool always =
-      status.type != file_manager_private::COPY_PROGRESS_STATUS_TYPE_PROGRESS;
+      status.type !=
+      file_manager_private::COPY_OR_MOVE_PROGRESS_STATUS_TYPE_PROGRESS;
   if (!ShouldSendProgressEvent(always, &last_copy_progress_event_))
     return;
 
diff --git a/chrome/browser/chromeos/extensions/file_manager/event_router.h b/chrome/browser/chromeos/extensions/file_manager/event_router.h
index 92e91b2..32bb6cc 100644
--- a/chrome/browser/chromeos/extensions/file_manager/event_router.h
+++ b/chrome/browser/chromeos/extensions/file_manager/event_router.h
@@ -98,7 +98,7 @@
 
   // Called when a copy task progress is updated.
   void OnCopyProgress(int copy_id,
-                      storage::FileSystemOperation::CopyProgressType type,
+                      storage::FileSystemOperation::CopyOrMoveProgressType type,
                       const GURL& source_url,
                       const GURL& destination_url,
                       int64_t size);
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
index f3f9901..5e5ef501 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -145,7 +145,7 @@
 void NotifyCopyProgress(
     void* profile_id,
     storage::FileSystemOperationRunner::OperationID operation_id,
-    storage::FileSystemOperation::CopyProgressType type,
+    storage::FileSystemOperation::CopyOrMoveProgressType type,
     const FileSystemURL& source_url,
     const FileSystemURL& destination_url,
     int64_t size) {
@@ -163,7 +163,7 @@
 void OnCopyProgress(
     void* profile_id,
     storage::FileSystemOperationRunner::OperationID* operation_id,
-    storage::FileSystemOperation::CopyProgressType type,
+    storage::FileSystemOperation::CopyOrMoveProgressType type,
     const FileSystemURL& source_url,
     const FileSystemURL& destination_url,
     int64_t size) {
diff --git a/chrome/browser/chromeos/fileapi/observable_file_system_operation_impl.cc b/chrome/browser/chromeos/fileapi/observable_file_system_operation_impl.cc
index d48c84b..b287fb9 100644
--- a/chrome/browser/chromeos/fileapi/observable_file_system_operation_impl.cc
+++ b/chrome/browser/chromeos/fileapi/observable_file_system_operation_impl.cc
@@ -135,7 +135,7 @@
     const storage::FileSystemURL& dst,
     CopyOrMoveOption option,
     ErrorBehavior error_behavior,
-    const CopyProgressCallback& progress_callback,
+    const CopyOrMoveProgressCallback& progress_callback,
     StatusCallback callback) {
   storage::FileSystemOperationImpl::Copy(
       src, dst, option, error_behavior, progress_callback,
@@ -159,12 +159,15 @@
           std::move(callback)));
 }
 
-void ObservableFileSystemOperationImpl::Move(const storage::FileSystemURL& src,
-                                             const storage::FileSystemURL& dst,
-                                             CopyOrMoveOption option,
-                                             StatusCallback callback) {
+void ObservableFileSystemOperationImpl::Move(
+    const storage::FileSystemURL& src,
+    const storage::FileSystemURL& dst,
+    CopyOrMoveOption option,
+    ErrorBehavior error_behavior,
+    const CopyOrMoveProgressCallback& progress_callback,
+    StatusCallback callback) {
   storage::FileSystemOperationImpl::Move(
-      src, dst, option,
+      src, dst, option, error_behavior, progress_callback,
       RunInOrderCallback(
           RunOnUiThreadOnSuccessCallback(base::BindOnce(
               &NotifyFileMovedOnUiThread, account_id_, src, dst)),
diff --git a/chrome/browser/chromeos/fileapi/observable_file_system_operation_impl.h b/chrome/browser/chromeos/fileapi/observable_file_system_operation_impl.h
index 4afa280a..452c31ee 100644
--- a/chrome/browser/chromeos/fileapi/observable_file_system_operation_impl.h
+++ b/chrome/browser/chromeos/fileapi/observable_file_system_operation_impl.h
@@ -34,7 +34,7 @@
             const storage::FileSystemURL& dst,
             CopyOrMoveOption option,
             ErrorBehavior error_behavior,
-            const CopyProgressCallback& progress_callback,
+            const CopyOrMoveProgressCallback& progress_callback,
             StatusCallback callback) override;
   void CopyFileLocal(const storage::FileSystemURL& src,
                      const storage::FileSystemURL& dst,
@@ -44,6 +44,8 @@
   void Move(const storage::FileSystemURL& src,
             const storage::FileSystemURL& dst,
             CopyOrMoveOption option,
+            ErrorBehavior error_behavior,
+            const CopyOrMoveProgressCallback& progress_callback,
             StatusCallback callback) override;
   void MoveFileLocal(const storage::FileSystemURL& src,
                      const storage::FileSystemURL& dst,
diff --git a/chrome/browser/chromeos/full_restore/app_launch_handler.h b/chrome/browser/chromeos/full_restore/app_launch_handler.h
index 0a9668d..922754bc 100644
--- a/chrome/browser/chromeos/full_restore/app_launch_handler.h
+++ b/chrome/browser/chromeos/full_restore/app_launch_handler.h
@@ -53,6 +53,8 @@
   void SetForceLaunchBrowserForTesting();
 
  private:
+  friend class AppLaunchHandlerArcAppBrowserTest;
+
   void OnGetRestoreData(
       std::unique_ptr<::full_restore::RestoreData> restore_data);
 
diff --git a/chrome/browser/chromeos/full_restore/app_launch_handler_browsertest.cc b/chrome/browser/chromeos/full_restore/app_launch_handler_browsertest.cc
index c01dda0..3164c5d 100644
--- a/chrome/browser/chromeos/full_restore/app_launch_handler_browsertest.cc
+++ b/chrome/browser/chromeos/full_restore/app_launch_handler_browsertest.cc
@@ -849,6 +849,14 @@
                               info->name, info->intent_uri, session_id);
   }
 
+  void UpdateThemeColor(int32_t task_id,
+                        uint32_t primary_color,
+                        uint32_t status_bar_color) {
+    auto empty_icon = arc::mojom::RawIconPngData::New();
+    app_host()->OnTaskDescriptionChanged(task_id, "", std::move(empty_icon),
+                                         primary_color, status_bar_color);
+  }
+
   void SetProfile() {
     ::full_restore::FullRestoreSaveHandler::GetInstance()
         ->SetPrimaryProfilePath(profile()->GetPath());
@@ -866,8 +874,7 @@
   void Restore() {
     test_full_restore_info_observer_.Reset();
 
-    auto app_launch_handler = std::make_unique<AppLaunchHandler>(profile());
-    app_launch_handler->SetShouldRestore();
+    app_launch_handler()->SetShouldRestore();
     content::RunAllTasksUntilIdle();
   }
 
@@ -925,10 +932,36 @@
     }
   }
 
+  void VerifyThemeColor(const std::string& app_id,
+                        int32_t task_id,
+                        uint32_t primary_color,
+                        uint32_t status_bar_color) {
+    const auto& app_id_to_launch_list =
+        app_launch_handler()->restore_data_->app_id_to_launch_list();
+
+    auto it = app_id_to_launch_list.find(app_id);
+    EXPECT_TRUE(it != app_id_to_launch_list.end());
+
+    auto data_it = it->second.find(task_id);
+    EXPECT_TRUE(data_it != it->second.end());
+
+    EXPECT_TRUE(data_it->second->primary_color.has_value());
+    EXPECT_EQ(primary_color, data_it->second->primary_color.value());
+
+    EXPECT_TRUE(data_it->second->status_bar_color.has_value());
+    EXPECT_EQ(status_bar_color, data_it->second->status_bar_color.value());
+  }
+
   ArcAppListPrefs* app_prefs() { return ArcAppListPrefs::Get(profile()); }
 
   arc::mojom::AppHost* app_host() { return app_prefs(); }
 
+  AppLaunchHandler* app_launch_handler() {
+    if (!app_launch_handler_)
+      app_launch_handler_ = std::make_unique<AppLaunchHandler>(profile());
+    return app_launch_handler_.get();
+  }
+
   TestFullRestoreInfoObserver* test_full_restore_info_observer() {
     return &test_full_restore_info_observer_;
   }
@@ -943,6 +976,7 @@
   }
 
   std::unique_ptr<arc::FakeAppInstance> app_instance_;
+  std::unique_ptr<AppLaunchHandler> app_launch_handler_;
   TestFullRestoreInfoObserver test_full_restore_info_observer_;
 };
 
@@ -1196,6 +1230,7 @@
   auto shell_surface =
       exo_test_helper.CreateClientControlledShellSurface(surface.get());
   shell_surface->SetApplicationId(kRestoreWindowAppId);
+  shell_surface->SetGeometry(gfx::Rect(gfx::Size(256, 256)));
   auto surface_buffer = std::make_unique<exo::Buffer>(
       exo_test_helper.CreateGpuMemoryBuffer(gfx::Size(256, 256)));
   surface->Attach(surface_buffer.get());
@@ -1210,6 +1245,10 @@
   ASSERT_TRUE(index);
   EXPECT_EQ(kActivationIndex, *index);
 
+  // Check if it's also left-snapped.
+  EXPECT_EQ(kWindowStateType,
+            ash::WindowState::Get(arc_window)->GetStateType());
+
   // Destroy the task and close the window.
   app_host()->OnTaskDestroyed(kRestoreTaskId);
   arc_widget->CloseNow();
@@ -1224,6 +1263,58 @@
   StopInstance();
 }
 
+// Test restoration when the ARC window is created before OnTaskCreated is
+// called.
+IN_PROC_BROWSER_TEST_F(AppLaunchHandlerArcAppBrowserTest,
+                       ArcAppThemeColorUpdate) {
+  SetProfile();
+  InstallTestApps(kTestAppPackage, false);
+
+  const std::string app_id = GetTestApp1Id(kTestAppPackage);
+  int32_t session_id =
+      ::full_restore::FullRestoreSaveHandler::GetInstance()->GetArcSessionId();
+  ::full_restore::FullRestoreInfo::GetInstance()->AddObserver(
+      test_full_restore_info_observer());
+
+  SaveAppLaunchInfo(app_id, session_id);
+
+  // Create the window for app1. The task id needs to match the |window_app_id|
+  // arg of CreateExoWindow.
+  int32_t kTaskId = 100;
+  uint32_t kPrimaryColor = 0xFFFFFFFF;
+  uint32_t kStatusBarColor = 0xFF000000;
+  views::Widget* widget = CreateExoWindow("org.chromium.arc.100");
+  aura::Window* window = widget->GetNativeWindow();
+
+  VerifyObserver(window, /*launch_count=*/0, /*init_count=*/0);
+  VerifyWindowProperty(window, kTaskId, /*restore_window_id=*/0,
+                       /*hidden=*/false);
+
+  // Simulate creating the task.
+  CreateTask(app_id, kTaskId, session_id);
+
+  UpdateThemeColor(kTaskId, kPrimaryColor, kStatusBarColor);
+
+  VerifyObserver(window, /*launch_count=*/1, /*init_count=*/0);
+
+  SaveWindowInfo(window);
+
+  WaitForAppLaunchInfoSaved();
+
+  ASSERT_TRUE(app_launch_handler());
+  content::RunAllTasksUntilIdle();
+
+  VerifyThemeColor(app_id, kTaskId, kPrimaryColor, kStatusBarColor);
+
+  widget->CloseNow();
+
+  app_host()->OnTaskDestroyed(kTaskId);
+
+  ::full_restore::FullRestoreInfo::GetInstance()->RemoveObserver(
+      test_full_restore_info_observer());
+  StopInstance();
+}
+
 class AppLaunchHandlerNoBrowserBrowserTest
     : public AppLaunchHandlerBrowserTest {
  public:
diff --git a/chrome/browser/chromeos/full_restore/full_restore_arc_task_handler.cc b/chrome/browser/chromeos/full_restore/full_restore_arc_task_handler.cc
index 1cb04cb..f1189999 100644
--- a/chrome/browser/chromeos/full_restore/full_restore_arc_task_handler.cc
+++ b/chrome/browser/chromeos/full_restore/full_restore_arc_task_handler.cc
@@ -46,6 +46,16 @@
   ::full_restore::OnTaskDestroyed(task_id);
 }
 
+void FullRestoreArcTaskHandler::OnTaskDescriptionChanged(
+    int32_t task_id,
+    const std::string& label,
+    const arc::mojom::RawIconPngData& icon,
+    uint32_t primary_color,
+    uint32_t status_bar_color) {
+  ::full_restore::OnTaskThemeColorUpdated(task_id, primary_color,
+                                          status_bar_color);
+}
+
 void FullRestoreArcTaskHandler::OnAppConnectionReady() {
 #if BUILDFLAG(ENABLE_WAYLAND_SERVER)
   if (window_handler_)
diff --git a/chrome/browser/chromeos/full_restore/full_restore_arc_task_handler.h b/chrome/browser/chromeos/full_restore/full_restore_arc_task_handler.h
index 40cd15d8..324deac 100644
--- a/chrome/browser/chromeos/full_restore/full_restore_arc_task_handler.h
+++ b/chrome/browser/chromeos/full_restore/full_restore_arc_task_handler.h
@@ -47,6 +47,11 @@
                      const std::string& intent,
                      int32_t session_id) override;
   void OnTaskDestroyed(int task_id) override;
+  void OnTaskDescriptionChanged(int32_t task_id,
+                                const std::string& label,
+                                const arc::mojom::RawIconPngData& icon,
+                                uint32_t primary_color,
+                                uint32_t status_bar_color) override;
   void OnAppConnectionReady() override;
 
  private:
diff --git a/chrome/browser/chromeos/smb_client/smb_service.cc b/chrome/browser/chromeos/smb_client/smb_service.cc
index ca5b255b..96cc40b 100644
--- a/chrome/browser/chromeos/smb_client/smb_service.cc
+++ b/chrome/browser/chromeos/smb_client/smb_service.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/containers/span.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/metrics/histogram_macros.h"
@@ -121,16 +122,16 @@
 base::ScopedFD MakeFdWithContents(const std::string& contents) {
   const size_t content_size = contents.size();
 
-  base::ScopedFD read_fd, write_fd;
+  base::ScopedFD read_fd;
+  base::ScopedFD write_fd;
   if (!base::CreatePipe(&read_fd, &write_fd, true /* non_blocking */)) {
     LOG(ERROR) << "Unable to create pipe";
     return {};
   }
   bool success =
-      base::WriteFileDescriptor(write_fd.get(),
-                                reinterpret_cast<const char*>(&content_size),
-                                sizeof(content_size)) &&
-      base::WriteFileDescriptor(write_fd.get(), contents.data(), content_size);
+      base::WriteFileDescriptor(
+          write_fd.get(), base::as_bytes(base::make_span(&content_size, 1))) &&
+      base::WriteFileDescriptor(write_fd.get(), contents);
   if (!success) {
     PLOG(ERROR) << "Unable to write contents to pipe";
     return {};
diff --git a/chrome/browser/chromeos/smb_client/temp_file_manager.cc b/chrome/browser/chromeos/smb_client/temp_file_manager.cc
index 4af224ac..1fd31d50 100644
--- a/chrome/browser/chromeos/smb_client/temp_file_manager.cc
+++ b/chrome/browser/chromeos/smb_client/temp_file_manager.cc
@@ -32,9 +32,7 @@
   base::ScopedFD temp_fd = CreateTempFile();
 
   // Write the data into the newly created file.
-  if (!base::WriteFileDescriptor(temp_fd.get(),
-                                 reinterpret_cast<const char*>(data.data()),
-                                 data.size())) {
+  if (!base::WriteFileDescriptor(temp_fd.get(), data)) {
     LOG(ERROR) << "Error writing to temporary file";
     temp_fd.reset();
     return temp_fd;
diff --git a/chrome/browser/content_settings/chrome_content_settings_utils.cc b/chrome/browser/content_settings/chrome_content_settings_utils.cc
index 46ed25a..4271687 100644
--- a/chrome/browser/content_settings/chrome_content_settings_utils.cc
+++ b/chrome/browser/content_settings/chrome_content_settings_utils.cc
@@ -50,7 +50,8 @@
   if (content_type != ContentSettingsType::FILE_HANDLING || !url.is_valid())
     return {};
 
-  return web_app::GetFileExtensionsHandledByWebAppDisplayedAsList(profile, url);
+  return web_app::GetFileTypeAssociationsHandledByWebAppDisplayedAsList(profile,
+                                                                        url);
 }
 #endif
 
diff --git a/chrome/browser/extensions/api/image_writer_private/OWNERS b/chrome/browser/extensions/api/image_writer_private/OWNERS
new file mode 100644
index 0000000..0afdfaa
--- /dev/null
+++ b/chrome/browser/extensions/api/image_writer_private/OWNERS
@@ -0,0 +1,4 @@
+per-file *_messages.cc=set noparent
+per-file *_messages.cc=file://ipc/SECURITY_OWNERS
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=file://ipc/SECURITY_OWNERS
diff --git a/chrome/browser/extensions/api/image_writer_private/error_messages.cc b/chrome/browser/extensions/api/image_writer_private/error_messages.cc
index 06db458..69f2461a 100644
--- a/chrome/browser/extensions/api/image_writer_private/error_messages.cc
+++ b/chrome/browser/extensions/api/image_writer_private/error_messages.cc
@@ -26,6 +26,7 @@
 const char kDownloadInterrupted[] = "DOWNLOAD_INTERRUPTED";
 const char kTempDirError[] = "TEMP_DIR_CREATION_ERROR";
 const char kTempFileError[] = "TEMP_FILE_CREATION_ERROR";
+const char kTempFileNoSpace[] = "TEMP_FILE_NO_SPACE";
 const char kUrlInvalid[] = "URL_INVALID";
 
 // Unzip errors
diff --git a/chrome/browser/extensions/api/image_writer_private/error_messages.h b/chrome/browser/extensions/api/image_writer_private/error_messages.h
index 225f733..a0356ad4 100644
--- a/chrome/browser/extensions/api/image_writer_private/error_messages.h
+++ b/chrome/browser/extensions/api/image_writer_private/error_messages.h
@@ -27,6 +27,7 @@
 extern const char kDownloadInterrupted[];
 extern const char kTempDirError[];
 extern const char kTempFileError[];
+extern const char kTempFileNoSpace[];
 extern const char kUrlInvalid[];
 
 // Unzip errors
diff --git a/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader.cc b/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader.cc
index 691ef3c..d629952 100644
--- a/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader.cc
+++ b/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader.cc
@@ -44,6 +44,10 @@
     // Read the actual file size.
     total_bytes_ = ReadOctalNumber(buffer_.data() + 124, 12);
 
+    if (!delegate_->SetContentsLength(total_bytes_, &error_id_)) {
+      return Result::kFailure;
+    }
+
     // Skip the rest of the header.
     offset += 512;
   }
diff --git a/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader.h b/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader.h
index 7bccae2..a886a5b0 100644
--- a/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader.h
+++ b/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader.h
@@ -45,6 +45,13 @@
     virtual bool WriteContents(const char* data,
                                int size,
                                std::string* error_id) = 0;
+
+    // Sets the full length of the data written by WriteContents(). If the OS
+    // supports the functionality, it allocates the region on the disk and fails
+    // when the disk is out of space.
+    // Returns kFailure and sets |error_id| if it fails.
+    // Always returns true if the functionality is not supported.
+    virtual bool SetContentsLength(uint64_t length, std::string* error_id) = 0;
   };
 
   explicit SingleFileTarReader(Delegate* delegate);
diff --git a/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader_unittest.cc b/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader_unittest.cc
index f6643a4..0bd151a 100644
--- a/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader_unittest.cc
+++ b/chrome/browser/extensions/api/image_writer_private/single_file_tar_reader_unittest.cc
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "base/files/file_util.h"
+#include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
 #include "chrome/browser/extensions/api/image_writer_private/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -49,12 +50,23 @@
     return true;
   }
 
+  bool SetContentsLength(uint64_t length, std::string* error_id) override {
+    if (no_space_) {
+      *error_id = error::kTempFileNoSpace;
+      return false;
+    }
+    return true;
+  }
+
   SingleFileTarReader& reader() { return reader_; }
   const std::vector<char>& contents() const { return contents_; }
 
+  void set_no_space(bool no_space) { no_space_ = no_space; }
+
  private:
   std::unique_ptr<base::File> infile_;
   std::vector<char> contents_;
+  bool no_space_ = false;
 
   SingleFileTarReader reader_;
 };
@@ -73,6 +85,16 @@
   EXPECT_EQ((std::vector<char>{'f', 'o', 'o', '\n'}), contents());
 }
 
+TEST_F(SingleFileTarReaderTest, TempFileNoSpace) {
+  base::FilePath test_data_dir;
+  ASSERT_TRUE(GetTestDataDirectory(&test_data_dir));
+  ASSERT_TRUE(OpenTarFile(test_data_dir.AppendASCII("test.tar")));
+
+  set_no_space(true);
+  EXPECT_EQ(SingleFileTarReader::Result::kFailure, reader().ExtractChunk());
+  EXPECT_EQ(error::kTempFileNoSpace, reader().error_id());
+}
+
 TEST_F(SingleFileTarReaderTest, ReadOctalNumber) {
   const char kNumber[12] = "00000000123";
   EXPECT_EQ(83u, SingleFileTarReader::ReadOctalNumber(kNumber, 12));
diff --git a/chrome/browser/extensions/api/image_writer_private/tar_extractor.cc b/chrome/browser/extensions/api/image_writer_private/tar_extractor.cc
index 1c698c8..7bc5424 100644
--- a/chrome/browser/extensions/api/image_writer_private/tar_extractor.cc
+++ b/chrome/browser/extensions/api/image_writer_private/tar_extractor.cc
@@ -6,7 +6,9 @@
 
 #include <utility>
 
+#include "base/files/file_util.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "build/build_config.h"
 #include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
 
 namespace extensions {
@@ -75,6 +77,16 @@
   return true;
 }
 
+bool TarExtractor::SetContentsLength(uint64_t length, std::string* error_id) {
+#if defined(OS_POSIX)
+  if (!base::AllocateFileRegion(&outfile_, 0, length)) {
+    *error_id = error::kTempFileNoSpace;
+    return false;
+  }
+#endif
+  return true;
+}
+
 void TarExtractor::ExtractImpl() {
   infile_.Initialize(properties_.image_path,
                      base::File::FLAG_OPEN | base::File::FLAG_READ);
diff --git a/chrome/browser/extensions/api/image_writer_private/tar_extractor.h b/chrome/browser/extensions/api/image_writer_private/tar_extractor.h
index 0f98f44..742c24a 100644
--- a/chrome/browser/extensions/api/image_writer_private/tar_extractor.h
+++ b/chrome/browser/extensions/api/image_writer_private/tar_extractor.h
@@ -38,6 +38,7 @@
   bool WriteContents(const char* data,
                      int size,
                      std::string* error_id) override;
+  bool SetContentsLength(uint64_t length, std::string* error_id) override;
 
   SingleFileTarReader tar_reader_;
 
diff --git a/chrome/browser/extensions/api/image_writer_private/xz_extractor.cc b/chrome/browser/extensions/api/image_writer_private/xz_extractor.cc
index 4219c13..6a707a5 100644
--- a/chrome/browser/extensions/api/image_writer_private/xz_extractor.cc
+++ b/chrome/browser/extensions/api/image_writer_private/xz_extractor.cc
@@ -9,8 +9,10 @@
 
 #include "base/bind.h"
 #include "base/files/file_path.h"
+#include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "build/build_config.h"
 #include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
 #include "chrome/browser/extensions/api/image_writer_private/single_file_tar_reader.h"
 #include "chrome/browser/file_util_service.h"
@@ -209,5 +211,15 @@
   return true;
 }
 
+bool XzExtractor::SetContentsLength(uint64_t length, std::string* error_id) {
+#if defined(OS_POSIX)
+  if (!base::AllocateFileRegion(&outfile_, 0, length)) {
+    *error_id = error::kTempFileNoSpace;
+    return false;
+  }
+#endif
+  return true;
+}
+
 }  // namespace image_writer
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/image_writer_private/xz_extractor.h b/chrome/browser/extensions/api/image_writer_private/xz_extractor.h
index edde3f69..9b2c15b 100644
--- a/chrome/browser/extensions/api/image_writer_private/xz_extractor.h
+++ b/chrome/browser/extensions/api/image_writer_private/xz_extractor.h
@@ -56,6 +56,7 @@
   bool WriteContents(const char* data,
                      int size,
                      std::string* error_id) override;
+  bool SetContentsLength(uint64_t length, std::string* error_id) override;
 
   mojo::Remote<chrome::mojom::FileUtilService> service_;
   mojo::Remote<chrome::mojom::XzFileExtractor> remote_xz_file_extractor_;
diff --git a/chrome/browser/extensions/api/messaging/native_message_process_host_unittest.cc b/chrome/browser/extensions/api/messaging/native_message_process_host_unittest.cc
index d56e0775..573b62d 100644
--- a/chrome/browser/extensions/api/messaging/native_message_process_host_unittest.cc
+++ b/chrome/browser/extensions/api/messaging/native_message_process_host_unittest.cc
@@ -197,8 +197,7 @@
   base::File read_file(pipe_handles[0]);
   std::string formatted_message = FormatMessage(kTestMessage);
   ASSERT_GT(base::GetPageSize(), formatted_message.size());
-  ASSERT_TRUE(base::WriteFileDescriptor(
-      pipe_handles[1], formatted_message.data(), formatted_message.size()));
+  ASSERT_TRUE(base::WriteFileDescriptor(pipe_handles[1], formatted_message));
   base::File write_file(pipe_handles[1]);
   std::unique_ptr<NativeProcessLauncher> launcher =
       FakeLauncher::CreateWithPipeInput(std::move(read_file), temp_output_file);
diff --git a/chrome/browser/extensions/blocklist_states_interaction_unittest.cc b/chrome/browser/extensions/blocklist_states_interaction_unittest.cc
index 7506c4f..b9a32e6 100644
--- a/chrome/browser/extensions/blocklist_states_interaction_unittest.cc
+++ b/chrome/browser/extensions/blocklist_states_interaction_unittest.cc
@@ -7,6 +7,7 @@
 #include "chrome/browser/extensions/extension_service_test_base.h"
 #include "chrome/browser/extensions/test_blocklist.h"
 #include "components/safe_browsing/buildflags.h"
+#include "extensions/browser/blocklist_state.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 // The interaction tests rely on the safe-browsing database.
@@ -146,10 +147,41 @@
       kTestExtensionId, disable_reason::DISABLE_GREYLIST));
 
   SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", true);
+  EXPECT_EQ(BLOCKLISTED_MALWARE,
+            ExtensionPrefs::Get(profile())->GetExtensionBlocklistState(
+                kTestExtensionId));
   EXPECT_TRUE(blocklisted_extensions.Contains(kTestExtensionId));
   EXPECT_FALSE(enabled_extensions.Contains(kTestExtensionId));
 
   SetOmahaBlocklistStateForExtension(kTestExtensionId, "_malware", false);
+  // TODO(crbug.com/1193695): Ideally this should be set to the original Safe
+  // Browsing greylist state BLOCKLISTED_POTENTIALLY_UNWANTED. However, this is
+  // not possible with the current implementation, because the Omaha blocklist
+  // state (malware) overrides the Safe Browsing blocklist state, and there is
+  // no way to preserve the original Safe Browsing greylist state (potentially
+  // unwanted). This should happen pretty rare - only when the extension is
+  // removed from the Omaha attribute blocklist but stays in the Safe Browsing
+  // greylist. It will be fixed after we decouple Safe Browsing blocklist state
+  // and Omaha attribute blocklist state.
+  EXPECT_EQ(NOT_BLOCKLISTED,
+            ExtensionPrefs::Get(profile())->GetExtensionBlocklistState(
+                kTestExtensionId));
+  EXPECT_FALSE(blocklisted_extensions.Contains(kTestExtensionId));
+  // TODO(crbug.com/1193695): The extension is still disabled with
+  // DISABLE_GREYLIST reason even though the blocklist state is cleared. This
+  // should be fixed when we start to consume Omaha attribute greylist.
+  EXPECT_FALSE(enabled_extensions.Contains(kTestExtensionId));
+  EXPECT_TRUE(ExtensionPrefs::Get(profile())->HasDisableReason(
+      kTestExtensionId, disable_reason::DISABLE_GREYLIST));
+
+  // The Safe Browsing greylist state should be set correctly after the Safe
+  // Browsing blocklist is refreshed.
+  SetSafeBrowsingBlocklistStateForExtension(kTestExtensionId,
+                                            BLOCKLISTED_POTENTIALLY_UNWANTED);
+  EXPECT_EQ(BLOCKLISTED_POTENTIALLY_UNWANTED,
+            ExtensionPrefs::Get(profile())->GetExtensionBlocklistState(
+                kTestExtensionId));
+
   EXPECT_FALSE(blocklisted_extensions.Contains(kTestExtensionId));
   // The extension should be kept disabled because it's still in the Safe
   // Browsing greylist.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index cbf568a..7c32928 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1932,6 +1932,11 @@
     "expiry_milestone": 83
   },
   {
+    "name": "enable-input-in-diagnostics-app",
+    "owners": [ "//chromeos/components/diagnostics_ui/OWNERS" ],
+    "expiry_milestone": 98
+  },
+  {
     "name": "enable-input-noise-cancellation-ui",
     "owners": [ "swifton@google.com", "cros-peripherals@google.com" ],
     "expiry_milestone": 98
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index b4ec18f..88be556 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1171,10 +1171,6 @@
 const char kEnableWasmSimdDescription[] =
     "Enables support for the WebAssembly SIMD proposal.";
 
-const char kEnableWasmThreadsName[] = "WebAssembly threads support";
-const char kEnableWasmThreadsDescription[] =
-    "Enables support for the WebAssembly Threads proposal.";
-
 const char kEnableWasmTieringName[] = "WebAssembly tiering";
 const char kEnableWasmTieringDescription[] =
     "Enables tiered compilation of WebAssembly (will tier up to TurboFan if "
@@ -4274,6 +4270,11 @@
     "Enable additional heuristic palm rejection logic when interacting with "
     "stylus usage. Not intended for all devices.";
 
+const char kEnableInputInDiagnosticsAppName[] =
+    "Enable input device cards in the Diagnostics App";
+const char kEnableInputInDiagnosticsAppDescription[] =
+    "Enable input device cards in the Diagnostics App";
+
 const char kEnableInputNoiseCancellationUiName[] =
     "Enable Input Noise Cancellation UI.";
 const char kEnableInputNoiseCancellationUiDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index b09e988a..7331a8c 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -684,9 +684,6 @@
 extern const char kEnableWasmSimdName[];
 extern const char kEnableWasmSimdDescription[];
 
-extern const char kEnableWasmThreadsName[];
-extern const char kEnableWasmThreadsDescription[];
-
 extern const char kEnableWasmTieringName[];
 extern const char kEnableWasmTieringDescription[];
 
@@ -2469,6 +2466,9 @@
 extern const char kEnableHeuristicStylusPalmRejectionName[];
 extern const char kEnableHeuristicStylusPalmRejectionDescription[];
 
+extern const char kEnableInputInDiagnosticsAppName[];
+extern const char kEnableInputInDiagnosticsAppDescription[];
+
 extern const char kEnableInputNoiseCancellationUiName[];
 extern const char kEnableInputNoiseCancellationUiDescription[];
 
diff --git a/chrome/browser/hid/hid_chooser_context.h b/chrome/browser/hid/hid_chooser_context.h
index 5533a58..e3104a7 100644
--- a/chrome/browser/hid/hid_chooser_context.h
+++ b/chrome/browser/hid/hid_chooser_context.h
@@ -12,6 +12,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/containers/queue.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/unguessable_token.h"
diff --git a/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc b/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc
index d6704a3..2205a0fc 100644
--- a/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc
+++ b/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc
@@ -220,6 +220,8 @@
     ASSERT_TRUE(test_files_ready);
     operation_runner()->Move(
         move_src_, move_dest_, storage::FileSystemOperation::OPTION_NONE,
+        storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
+        storage::FileSystemOperation::CopyOrMoveProgressCallback(),
         base::BindOnce(&MediaFileValidatorTest::OnMoveResult,
                        base::Unretained(this), expected_result));
   }
diff --git a/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc b/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
index 2d07a03..1722cd0e 100644
--- a/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
+++ b/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
@@ -297,7 +297,7 @@
       operation_runner()->Copy(
           url, dest_url, storage::FileSystemOperation::OPTION_NONE,
           storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
-          storage::FileSystemOperationRunner::CopyProgressCallback(),
+          storage::FileSystemOperation::CopyOrMoveProgressCallback(),
           base::BindOnce(&ExpectEqHelper, test_name, expectation));
       content::RunAllTasksUntilIdle();
     }
@@ -360,7 +360,7 @@
       operation_runner()->Copy(
           src_url, url, storage::FileSystemOperation::OPTION_NONE,
           storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
-          storage::FileSystemOperationRunner::CopyProgressCallback(),
+          storage::FileSystemOperation::CopyOrMoveProgressCallback(),
           base::BindOnce(&ExpectEqHelper, test_name, expectation));
       content::RunAllTasksUntilIdle();
     }
@@ -398,6 +398,8 @@
       }
       operation_runner()->Move(
           url, dest_url, storage::FileSystemOperation::OPTION_NONE,
+          storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
+          storage::FileSystemOperation::CopyOrMoveProgressCallback(),
           base::BindOnce(&ExpectEqHelper, test_name, expectation));
       content::RunAllTasksUntilIdle();
     }
@@ -460,6 +462,8 @@
       }
       operation_runner()->Move(
           src_url, url, storage::FileSystemOperation::OPTION_NONE,
+          storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
+          storage::FileSystemOperation::CopyOrMoveProgressCallback(),
           base::BindOnce(&ExpectEqHelper, test_name, expectation));
       content::RunAllTasksUntilIdle();
     }
diff --git a/chrome/browser/notifications/persistent_notification_handler.cc b/chrome/browser/notifications/persistent_notification_handler.cc
index fceb89e..f0ba4a9 100644
--- a/chrome/browser/notifications/persistent_notification_handler.cc
+++ b/chrome/browser/notifications/persistent_notification_handler.cc
@@ -109,9 +109,8 @@
 #endif
 
   blink::mojom::PermissionStatus permission_status =
-      content::BrowserContext::GetPermissionController(profile)
-          ->GetPermissionStatus(content::PermissionType::NOTIFICATIONS, origin,
-                                origin);
+      profile->GetPermissionController()->GetPermissionStatus(
+          content::PermissionType::NOTIFICATIONS, origin, origin);
 
   // Don't process click events when the |origin| doesn't have permission. This
   // can't be a DCHECK because of potential races with native notifications.
diff --git a/chrome/browser/policy/messaging_layer/public/report_client.cc b/chrome/browser/policy/messaging_layer/public/report_client.cc
index 48daa0e..2964f22 100644
--- a/chrome/browser/policy/messaging_layer/public/report_client.cc
+++ b/chrome/browser/policy/messaging_layer/public/report_client.cc
@@ -255,9 +255,13 @@
 void ReportingClient::ClientInitializingContext::OnCloudPolicyClientConfigured(
     StatusOr<policy::CloudPolicyClient*> client_result) {
   if (!client_result.ok()) {
-    Complete(Status(error::FAILED_PRECONDITION,
-                    base::StrCat({"Unable to build CloudPolicyClient: ",
-                                  client_result.status().message()})));
+    client_->uploaders_queue_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            &ClientInitializingContext::Complete, base::Unretained(this),
+            Status(error::FAILED_PRECONDITION,
+                   base::StrCat({"Unable to build CloudPolicyClient: ",
+                                 client_result.status().message()}))));
     return;
   }
   cloud_policy_client_ = client_result.ValueOrDie();
@@ -278,16 +282,22 @@
 void ReportingClient::ClientInitializingContext::OnStorageModuleConfigured(
     StatusOr<scoped_refptr<StorageModuleInterface>> storage_result) {
   if (!storage_result.ok()) {
-    Complete(Status(error::FAILED_PRECONDITION,
-                    base::StrCat({"Unable to build StorageModule: ",
-                                  storage_result.status().message()})));
+    client_->uploaders_queue_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            &ClientInitializingContext::Complete, base::Unretained(this),
+            Status(error::FAILED_PRECONDITION,
+                   base::StrCat({"Unable to build StorageModule: ",
+                                 storage_result.status().message()}))));
     return;
   }
 
   storage_ = storage_result.ValueOrDie();
   if (!cloud_policy_client_) {
     // No policy client - no uploader needed (uploads will not be forwarded).
-    Complete(Status::StatusOK());
+    client_->uploaders_queue_task_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&ClientInitializingContext::Complete,
+                                  base::Unretained(this), Status::StatusOK()));
     return;
   }
 
@@ -303,19 +313,24 @@
 void ReportingClient::ClientInitializingContext::OnUploadClientCreated(
     StatusOr<std::unique_ptr<UploadClient>> upload_client_result) {
   if (!upload_client_result.ok()) {
-    Complete(Status(error::FAILED_PRECONDITION,
-                    base::StrCat({"Unable to create UploadClient: ",
-                                  upload_client_result.status().message()})));
+    client_->uploaders_queue_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            &ClientInitializingContext::Complete, base::Unretained(this),
+            Status(error::FAILED_PRECONDITION,
+                   base::StrCat({"Unable to create UploadClient: ",
+                                 upload_client_result.status().message()}))));
     return;
   }
   upload_client_ = std::move(upload_client_result.ValueOrDie());
   // All done, return success.
-  base::ThreadPool::PostTask(
+  client_->uploaders_queue_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&ClientInitializingContext::Complete,
                                 base::Unretained(this), Status::StatusOK()));
 }
 
 void ReportingClient::ClientInitializingContext::OnCompleted() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(client_->uploaders_queue_sequence_checker_);
   if (cloud_policy_client_) {
     DCHECK(client_->cloud_policy_client_ == nullptr)
         << "Cloud policy client already recorded";
@@ -344,6 +359,7 @@
       chromeos::ProfileHelper::Get()->GetActiveUserProfileDir());
 #endif
   reporting_path_ = user_data_dir.Append(kReportingDirectory);
+  DETACH_FROM_SEQUENCE(uploaders_queue_sequence_checker_);
 }
 
 ReportingClient::~ReportingClient() = default;
@@ -387,6 +403,8 @@
           [](Priority priority, bool need_encryption_key,
              UploaderInterface::UploaderInterfaceResultCb start_uploader_cb,
              ReportingClient* instance) {
+            DCHECK_CALLED_ON_VALID_SEQUENCE(
+                instance->uploaders_queue_sequence_checker_);
             if (instance->upload_client_) {
               auto uploader = Uploader::Create(
                   need_encryption_key,
@@ -405,6 +423,7 @@
 }
 
 void ReportingClient::FlushAsyncStartUploaderQueue() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(uploaders_queue_sequence_checker_);
   // Executed on sequential task runner.
   while (!async_start_uploaders_queue_.empty()) {
     auto& request = async_start_uploaders_queue_.front();
@@ -419,6 +438,7 @@
 
 void ReportingClient::SetUploadClient(
     std::unique_ptr<UploadClient> upload_client) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(uploaders_queue_sequence_checker_);
   // This can only happen once.
   DCHECK(!upload_client_);
   upload_client_ = std::move(upload_client);
diff --git a/chrome/browser/policy/messaging_layer/public/report_client.h b/chrome/browser/policy/messaging_layer/public/report_client.h
index cae3b7bf..c086ac5 100644
--- a/chrome/browser/policy/messaging_layer/public/report_client.h
+++ b/chrome/browser/policy/messaging_layer/public/report_client.h
@@ -168,6 +168,8 @@
   std::string verification_key_;
   GetCloudPolicyClientCallback build_cloud_policy_client_cb_;
 
+  // The three member variables below are protected by
+  // uploaders_queue_task_runner_.
   // TODO(chromium:1078512) Passing around a raw pointer is unsafe. Wrap
   // CloudPolicyClient and guard access.
   policy::CloudPolicyClient* cloud_policy_client_ = nullptr;
@@ -179,6 +181,7 @@
   // case it is added to the queue and executed only once upload_client_ is set.
   std::queue<AsyncStartUploaderRequest> async_start_uploaders_queue_;
   scoped_refptr<base::SequencedTaskRunner> uploaders_queue_task_runner_;
+  SEQUENCE_CHECKER(uploaders_queue_sequence_checker_);
 };
 }  // namespace reporting
 
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_search.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_search.html
index 4fc18fe..5e8ce3c 100644
--- a/chrome/browser/resources/chromeos/emoji_picker/emoji_search.html
+++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_search.html
@@ -3,9 +3,10 @@
     display: flex;
     flex-direction: column;
     overflow-y: scroll;
+    --emoji-picker-search-margins: 14px;
   }
   cr-search-field {
-    --cr-search-field-clear-icon-margin-end: 14px;
+    --cr-search-field-clear-icon-margin-end: var(--emoji-picker-search-margins);
     --cr-search-field-clear-icon-size:20px;
     --cr-search-field-input-border-bottom: none;
     --cr-search-field-input-padding-bottom: 0;
@@ -15,7 +16,8 @@
     --cr-search-field-search-icon-display: none;
     --cr-search-field-search-icon-fill: var(--cr-secondary-text-color);
     --cr-search-field-search-icon-inline-display: block;
-    --cr-search-field-search-icon-inline-margin-start: 14px;
+    --cr-search-field-search-icon-inline-margin-start:
+      var(--emoji-picker-search-margins);
     --cr-search-field-underline-display: none;
     align-items: center;
     background-color: var(--google-grey-100);
@@ -34,6 +36,7 @@
     border: 2px solid transparent;
     border-radius: 40px;
     display: flex;
+    margin-inline-end: var(--emoji-picker-search-margins);
   }
   .result:focus,
   .result:active {
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.html b/chrome/browser/resources/settings/basic_page/basic_page.html
index 5fce87a..741d47b 100644
--- a/chrome/browser/resources/settings/basic_page/basic_page.html
+++ b/chrome/browser/resources/settings/basic_page/basic_page.html
@@ -98,7 +98,7 @@
         <template is="dom-if" if="[[showPage_(pageVisibility.safetyCheck)]]"
             restamp>
           <settings-section page-title="$i18n{safetyCheckSectionTitle}"
-              section="safetyCheck"
+              section="safetyCheck" nest-under-section="privacy"
               id="safetyCheckSettingsSection">
             <settings-safety-check-page prefs="{{prefs}}">
             </settings-safety-check-page>
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn
index cceca8b..b891ddd 100644
--- a/chrome/browser/resources/settings/chromeos/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -405,10 +405,8 @@
     "chromeos/os_languages_page/input_method_util.m.js",
     "chromeos/os_languages_page/input_page.m.js",
     "chromeos/os_languages_page/languages_metrics_proxy.m.js",
-    "chromeos/os_languages_page/manage_input_methods_page.m.js",
     "chromeos/os_languages_page/os_add_languages_dialog.m.js",
     "chromeos/os_languages_page/os_edit_dictionary_page.m.js",
-    "chromeos/os_languages_page/os_languages_page.m.js",
     "chromeos/os_languages_page/os_languages_page_v2.m.js",
     "chromeos/os_languages_page/os_languages_section.m.js",
     "chromeos/os_languages_page/shared_style.m.js",
diff --git a/chrome/browser/resources/settings/chromeos/lazy_load.js b/chrome/browser/resources/settings/chromeos/lazy_load.js
index e3ece308..f3ddee7 100644
--- a/chrome/browser/resources/settings/chromeos/lazy_load.js
+++ b/chrome/browser/resources/settings/chromeos/lazy_load.js
@@ -28,7 +28,6 @@
 import './os_languages_page/input_method_options_page.m.js';
 import './os_languages_page/input_page.m.js';
 import './os_languages_page/os_edit_dictionary_page.m.js';
-import './os_languages_page/os_languages_page.m.js';
 import './os_languages_page/os_languages_page_v2.m.js';
 import './os_languages_page/os_languages_section.m.js';
 import './os_languages_page/smart_inputs_page.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
index e69b0be..8dafdfdc 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
@@ -18,10 +18,8 @@
     ":input_method_util.m",
     ":input_page.m",
     ":languages_metrics_proxy.m",
-    ":manage_input_methods_page.m",
     ":os_add_languages_dialog.m",
     ":os_edit_dictionary_page.m",
-    ":os_languages_page.m",
     ":os_languages_page_v2.m",
     ":os_languages_section.m",
     ":smart_inputs_page.m",
@@ -105,12 +103,6 @@
   externs_list = [ "$externs_path/metrics_private.js" ]
 }
 
-js_library("manage_input_methods_page.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/manage_input_methods_page.m.js" ]
-  deps = [ "//ui/webui/resources/js:cr.m" ]
-  extra_deps = [ ":manage_input_methods_page_module" ]
-}
-
 js_library("os_add_languages_dialog.m") {
   sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/os_add_languages_dialog.m.js" ]
   deps = [
@@ -137,29 +129,6 @@
   extra_deps = [ ":os_edit_dictionary_page_module" ]
 }
 
-js_library("os_languages_page.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.m.js" ]
-  deps = [
-    ":input_method_util.m",
-    ":languages_metrics_proxy.m",
-    "..:deep_linking_behavior.m",
-    "..:metrics_recorder.m",
-    "..:os_route.m",
-    "../..:i18n_setup",
-    "../..:lifetime_browser_proxy",
-    "../..:router",
-    "../localized_link:localized_link.m",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu.m",
-    "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button.m",
-    "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render.m",
-    "//ui/webui/resources/js:assert.m",
-    "//ui/webui/resources/js:cr.m",
-    "//ui/webui/resources/js/cr/ui:focus_without_ink.m",
-  ]
-  extra_deps = [ ":os_languages_page_module" ]
-}
-
 js_library("os_languages_page_v2.m") {
   sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.m.js" ]
   deps = [
@@ -187,8 +156,8 @@
   sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.m.js" ]
   deps = [
     ":input_method_options_page.m",
-    ":manage_input_methods_page.m",
-    ":os_languages_page.m",
+    ":input_page.m",
+    ":os_languages_page_v2.m",
     "..:os_route.m",
     "../..:router",
     "../../languages_page:languages",
@@ -196,6 +165,7 @@
     "../../settings_page:settings_subpage",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:cr.m",
+    "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js/cr/ui:focus_without_ink.m",
   ]
@@ -221,11 +191,9 @@
     ":change_device_language_dialog_module",
     ":input_method_options_page_module",
     ":input_page_module",
-    ":manage_input_methods_page_module",
     ":modulize",
     ":os_add_languages_dialog_module",
     ":os_edit_dictionary_page_module",
-    ":os_languages_page_module",
     ":os_languages_page_v2_module",
     ":os_languages_section_module",
     ":shared_style_module",
@@ -258,15 +226,6 @@
   auto_imports = os_settings_auto_imports
 }
 
-polymer_modulizer("manage_input_methods_page") {
-  js_file = "manage_input_methods_page.js"
-  html_file = "manage_input_methods_page.html"
-  html_type = "dom-module"
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-  auto_imports = os_settings_auto_imports
-}
-
 polymer_modulizer("os_add_languages_dialog") {
   js_file = "os_add_languages_dialog.js"
   html_file = "os_add_languages_dialog.html"
@@ -285,15 +244,6 @@
   auto_imports = os_settings_auto_imports
 }
 
-polymer_modulizer("os_languages_page") {
-  js_file = "os_languages_page.js"
-  html_file = "os_languages_page.html"
-  html_type = "dom-module"
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-  auto_imports = os_settings_auto_imports
-}
-
 polymer_modulizer("os_languages_page_v2") {
   js_file = "os_languages_page_v2.js"
   html_file = "os_languages_page_v2.html"
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/manage_input_methods_page.html b/chrome/browser/resources/settings/chromeos/os_languages_page/manage_input_methods_page.html
deleted file mode 100644
index fb7b219..0000000
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/manage_input_methods_page.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!-- TODO(crbug.com/1097328): Delete this file and all of the i18n strings
-     used here, as this is unused. -->
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.html">
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="../../settings_shared_css.html">
-
-<dom-module id="settings-manage-input-methods-page">
-  <template>
-    <style include="settings-shared"></style>
-    <div class="settings-box continuation"
-        hidden$="[[!inputMethodsLimitedByPolicy_(
-            prefs.settings.language.allowed_input_methods)]]">
-      <iron-icon class="policy" icon="cr20:domain"></iron-icon>
-      <div>$i18n{inputMethodsManagedbyPolicy}</div>
-    </div>
-    <div class="settings-box first block">
-      <template is="dom-repeat" items="[[languageList_]]">
-        <h2>[[item.language.displayName]]</h2>
-        <div class="list-frame vertical-list">
-          <template is="dom-repeat" items="[[item.inputMethods]]">
-            <div class="list-item">
-              <div class="language-name">
-                <cr-checkbox checked="[[item.enabled]]"
-                    on-change="onCheckboxChange_"
-                    disabled="[[!enableInputMethodCheckbox_(
-                        item, languages.inputMethods.enabled.*)]]">
-                  <span>[[item.displayName]]</span>
-                </cr-checkbox>
-              </div>
-            </div>
-          </template>
-        </div>
-      </template>
-    </div>
-  </template>
-  <script src="manage_input_methods_page.js"></script>
-</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/manage_input_methods_page.js b/chrome/browser/resources/settings/chromeos/os_languages_page/manage_input_methods_page.js
deleted file mode 100644
index 247caf3..0000000
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/manage_input_methods_page.js
+++ /dev/null
@@ -1,229 +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.
-
-// TODO(crbug.com/1097328): Delete this file, as it is unused.
-
-/**
- * @fileoverview 'settings-manage-input-methods-page' is a sub-page for enabling
- * and disabling input methods. Input methods are grouped by base languages to
- * avoid showing duplicate or ambiguous input methods.
- */
-Polymer({
-  is: 'settings-manage-input-methods-page',
-
-  properties: {
-    /** @type {!LanguagesModel|undefined} */
-    languages: {
-      type: Object,
-      notify: true,
-    },
-
-    /** @type {!LanguageHelper} */
-    languageHelper: Object,
-
-    /**
-     * List of enabled languages with the input methods to show.
-     * @private {!Array<
-     *     !{language: !chrome.languageSettingsPrivate.Language,
-     *       inputMethods: !Array<!chrome.languageSettingsPrivate.InputMethod>
-     *      }>}
-     */
-    languageList_: {
-      type: Array,
-      value() {
-        return [];
-      },
-    },
-  },
-
-  observers: [
-    'availableInputMethodsChanged_(languages.enabled.*,' +
-        'languages.inputMethods.supported.*)',
-    'enabledInputMethodsChanged_(languages.inputMethods.enabled.*)',
-  ],
-
-  /** @private */
-  availableInputMethodsChanged_() {
-    this.populateLanguageList_();
-  },
-
-  /** @private */
-  enabledInputMethodsChanged_() {
-    this.populateLanguageList_();
-  },
-
-  /**
-   * Handler for an input method checkbox.
-   * @param {!{model: !{item: chrome.languageSettingsPrivate.InputMethod},
-   *           target: !Element}} e
-   * @private
-   */
-  onCheckboxChange_(e) {
-    // TODO(michaelpg): Show confirmation dialog for 3rd-party IMEs.
-    const id = e.model.item.id;
-    if (e.target.checked) {
-      this.languageHelper.addInputMethod(id);
-    } else {
-      this.languageHelper.removeInputMethod(id);
-    }
-  },
-
-  /**
-   * Returns true if the input method can be added/removed.
-   * @param {!chrome.languageSettingsPrivate.InputMethod} targetInputMethod
-   * @param {!Object} change Polymer change object (provided in the HTML so this
-   *     gets called whenever languages.inputMethods.enabled.* changes).
-   * @return {boolean}
-   * @private
-   */
-  enableInputMethodCheckbox_(targetInputMethod, change) {
-    if (targetInputMethod.isProhibitedByPolicy) {
-      return false;
-    }
-
-    if (!targetInputMethod.enabled) {
-      return true;
-    }
-
-    // Third-party IMEs can always be removed.
-    if (!this.languageHelper.isComponentIme(targetInputMethod)) {
-      return true;
-    }
-
-    // Can be removed as long as there is another component IME.
-    return this.languages.inputMethods.enabled.some(function(inputMethod) {
-      return inputMethod !== targetInputMethod &&
-          this.languageHelper.isComponentIme(inputMethod);
-    }, this);
-  },
-
-  /**
-   * Creates the list of languages and their input methods as the data source
-   * for the view.
-   * @private
-   */
-  populateLanguageList_() {
-    const languageList = [];
-
-    // Languages that have already been listed further up.
-    const /** !Set<string> */ usedLanguages = new Set();
-
-    // Add languages in preference order. However, if there are multiple
-    // enabled variants of the same base language, group them all as the base
-    // language instead of showing each variant individually. This prevents us
-    // from displaying duplicate input methods under different variants.
-    for (let i = 0; i < this.languages.enabled.length; i++) {
-      const languageState = this.languages.enabled[i];
-      // Skip the language if we have already included it or its base language.
-      if (usedLanguages.has(languageState.language.code)) {
-        continue;
-      }
-      const baseLanguageCode = this.languageHelper.getLanguageCodeWithoutRegion(
-          languageState.language.code);
-      if (usedLanguages.has(baseLanguageCode)) {
-        continue;
-      }
-
-      // Find the other languages further down in the preferred languages list
-      // which also use this language's base language code.
-      const languageFamilyCodes = [languageState.language.code];
-      for (let j = i + 1; j < this.languages.enabled.length; j++) {
-        const otherCode = this.languages.enabled[j].language.code;
-        if (this.languageHelper.getLanguageCodeWithoutRegion(otherCode) ===
-            baseLanguageCode) {
-          languageFamilyCodes.push(this.languages.enabled[j].language.code);
-        }
-      }
-
-      const combinedInputMethods =
-          this.getInputMethodsForLanguages(languageFamilyCodes);
-
-      // Skip the language if it has no new input methods.
-      if (!combinedInputMethods.length) {
-        continue;
-      }
-
-      // Add the language or base language.
-      let displayLanguage = languageState.language;
-      if (languageFamilyCodes.length > 1) {
-        const baseLanguage = this.languageHelper.getLanguage(baseLanguageCode);
-        if (baseLanguage) {
-          displayLanguage = baseLanguage;
-        }
-      }
-      languageList.push({
-        language: displayLanguage,
-        inputMethods: combinedInputMethods,
-      });
-      for (let k = 0; k < languageFamilyCodes.length; k++) {
-        usedLanguages.add(languageFamilyCodes[k]);
-      }
-    }
-
-    // Add ARC IMEs to the bottom if any.
-    const arcInputMethods = this.getInputMethodsForLanguages(
-        [this.languageHelper.getArcImeLanguageCode()]);
-    if (arcInputMethods.length) {
-      languageList.push({
-        language: this.languageHelper.getLanguage(
-            this.languageHelper.getArcImeLanguageCode()),
-        inputMethods: arcInputMethods,
-      });
-    }
-
-    this.languageList_ = languageList;
-    this.notifyInputMethodsChanged_();
-  },
-
-  /**
-   * Returns the input methods that support any of the given languages.
-   * @param {!Array<string>} languageCodes
-   * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>}
-   * @private
-   */
-  getInputMethodsForLanguages(languageCodes) {
-    // Input methods that have already been listed for this language.
-    const /** !Set<string> */ usedInputMethods = new Set();
-    /** @type {!Array<chrome.languageSettingsPrivate.InputMethod>} */
-    const combinedInputMethods = [];
-    for (let i = 0; i < languageCodes.length; i++) {
-      const inputMethods =
-          this.languageHelper.getInputMethodsForLanguage(languageCodes[i]);
-      // Get the language's unused input methods and mark them as used.
-      const newInputMethods = inputMethods.filter(function(inputMethod) {
-        if (usedInputMethods.has(inputMethod.id)) {
-          return false;
-        }
-        usedInputMethods.add(inputMethod.id);
-        return true;
-      });
-      [].push.apply(combinedInputMethods, newInputMethods);
-    }
-    return combinedInputMethods;
-  },
-
-  // TODO(Polymer/polymer#3603): We have to notify Polymer of properties that
-  // may have changed on nested objects, even when the outer property itself
-  // is set to a new array.
-  // TODO(michaelpg): Test this behavior.
-  /** @private */
-  notifyInputMethodsChanged_() {
-    for (let i = 0; i < this.languageList_.length; i++) {
-      for (let j = 0; j < this.languageList_[i].inputMethods.length; j++) {
-        this.notifyPath(
-            'languageList_.' + i + '.inputMethods.' + j + '.enabled',
-            this.languageList_[i].inputMethods[j].enabled);
-      }
-    }
-  },
-
-  /**
-   * @param {Object} allowedInputMethods
-   * @return {boolean}
-   * @private
-   */
-  inputMethodsLimitedByPolicy_(allowedInputMethods) {
-    return !!allowedInputMethods && allowedInputMethods.value.length > 0;
-  }
-});
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.html b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.html
deleted file mode 100644
index 8690cba..0000000
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.html
+++ /dev/null
@@ -1,305 +0,0 @@
-<!-- TODO(crbug.com/1097328): Delete this file and all of the i18n strings
-     used here, as this is unused. -->
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/html/action_link.html">
-<link rel="import" href="chrome://resources/cr_elements/action_link_css.html">
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="chrome://resources/html/cr.html">
-<link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
-<link rel="import" href="input_method_util.html">
-<link rel="import" href="languages_metrics_proxy.html">
-<link rel="import" href="os_add_languages_dialog.html">
-<link rel="import" href="../localized_link/localized_link.html">
-<link rel="import" href="../../controls/settings_toggle_button.html">
-<link rel="import" href="../../lifetime_browser_proxy.html">
-<link rel="import" href="../../prefs/prefs_behavior.html">
-<link rel="import" href="../deep_linking_behavior.html">
-<link rel="import" href="../os_route.html">
-<link rel="import" href="../../i18n_setup.html">
-<link rel="import" href="../../router.html">
-<link rel="import" href="../../settings_shared_css.html">
-<link rel="import" href="../../settings_vars_css.html">
-<link rel="import" href="../metrics_recorder.html">
-
-<dom-module id="os-settings-languages-page">
-  <template>
-    <style include="settings-shared action-link">
-      h2 {
-        padding-inline-start: var(--cr-section-padding);
-      }
-
-      .explain-selected {
-        color: var(--cros-success-color);
-        font-weight: initial;
-        margin-top: 4px;
-      }
-
-      cr-action-menu.complex .dropdown-item {
-        min-height: 36px;
-      }
-
-      cr-action-menu:not(.complex) hr {
-        display: none;
-      }
-
-      cr-action-menu.complex hr {
-        /* Override user-agent border and margin. */
-        border: none;
-        /* TODO(michaelpg): Update to whatever variable is used for the darker,
-         * full-width separators: crbug.com/649547. */
-        border-top: var(--cr-separator-line);
-        margin: 6px 0 0 0;
-      }
-
-      cr-checkbox.dropdown-item {
-        --cr-action-menu-disabled-item-opacity: 0.38;
-        margin-inline-start: 0;
-      }
-
-      .icon-external {
-        /* The negative margin messes up the outline border. These are in an
-           indented list so this looks fine until moved: crbug.com/708286. */
-        margin-inline-end: 0;
-      }
-
-      #uiLanguageItem:focus {
-        background-color: transparent;
-      }
-
-      #uiLanguageItem span {
-        line-height: 20px;
-      }
-
-      #uiLanguageItem cr-policy-indicator {
-        float: right;
-        margin-inline-start: 20px;
-      }
-
-      .name-with-error-list {
-        padding: 14px 0;
-      }
-
-      .name-with-error-list div {
-        color: var(--cros-error-color);
-        margin-top: 8px;
-      }
-
-      iron-icon[icon='cr:error'] {
-        --iron-icon-fill-color: var(--cros-error-color);
-        height: var(--cr-icon-size);
-        margin-inline-end: 8px;
-        width: var(--cr-icon-size);
-      }
-
-      .name-with-error-list[disabled] {
-        pointer-events: none;
-      }
-
-      iron-icon.policy {
-        margin-inline-start: 10px;
-      }
-
-      cr-policy-pref-indicator {
-        margin-inline-end: var(--settings-controlled-by-spacing);
-      }
-
-      div.list-item.non-target .target-info {
-        display: none;
-      }
-
-      /* Any .target.target-info following another .target element needs to
-      be hidden. We only want to show the _first_ .target-info of the list.
-      This is a way to do a :first-of-class selector. */
-      div.list-item.target ~  div.list-item.target .target-info {
-        display: none;
-      }
-
-      /* The default implementation of the actionable list item makes the entire
-      list item row a button such that clicking anywhere will activate the
-      action of the list item. The input method list behaves differently in that
-      clicking the list item sets that item as the input method, and the
-      selected list item should not react to selection after being selected.
-      Set the cursor to auto to override the default implementation which would
-      otherwise make the entire row appear clickable when it is not. */
-      div.list-item.selected[actionable] {
-        cursor: auto;
-      }
-
-      #restartButton {
-        margin-inline-start: var(--settings-controlled-by-spacing);
-      }
-
-      .internal-wrapper,
-      .external-wrapper {
-        display: flex;
-      }
-    </style>
-
-    <div route-path="default">
-
-      <h2>$i18n{osLanguagesListTitle}</h2>
-
-      <span class="settings-box first"
-          hidden="[[isHelpTextHidden_(languages.enabled.*)]]">
-        <settings-localized-link
-            localized-string="$i18n{orderLanguagesInstructions}"
-            link-url="$i18n{languagesLearnMoreURL}">
-        </settings-localized-link>
-      </span>
-      <div class="list-frame vertical-list" id="languagesList">
-        <template is="dom-repeat" items="[[languages.enabled]]">
-          <div class$="list-item [[getLanguageItemClass_(
-              item.language.code, language.prospectiveUILanguage)]]">
-            <div class="start" id="displayText-[[index]]"
-                aria-hidden="true">
-              <div title="[[item.language.nativeDisplayName]]">
-                [[item.language.displayName]]
-              </div>
-              <div class="explain-selected"
-                  hidden="[[!isProspectiveUILanguage_(
-                      item.language.code,
-                      languages.prospectiveUILanguage)]]">
-                $i18n{isDisplayedInThisLanguage}
-              </div>
-            </div>
-            <template is="dom-if" if="[[isRestartRequired_(
-                item.language.code, languages.prospectiveUILanguage)]]"
-                restamp>
-              <cr-button id="restartButton" on-click="onRestartTap_"
-                  aria-label$="[[getRestartButtonDescription_(
-                      item.language.displayName)]]">
-                $i18n{restart}
-              </cr-button>
-            </template>
-            <cr-icon-button class="icon-more-vert"
-                title="$i18n{moreActions}" id="more-[[item.language.code]]"
-                on-click="onDotsTap_"
-                aria-labelledby$="displayText-[[index]]">
-            </cr-icon-button>
-          </div>
-        </template>
-        <div class="list-item">
-          <a is="action-link" class="list-button" id="addLanguages"
-              disabled="[[!canEnableSomeSupportedLanguage_(languages)]]"
-              on-click="onAddLanguagesTap_"
-              deep-link-focus-id$="[[Setting.kAddLanguage]]">
-            $i18n{addLanguages}
-          </a>
-        </div>
-      </div>
-
-      <h2>$i18n{inputMethodsListTitle}</h2>
-
-      <div class="list-frame vertical-list" id="inputMethodsList">
-        <template is="dom-repeat"
-            items="[[languages.inputMethods.enabled]]">
-          <div class$="list-item [[getInputMethodItemClass_(
-              item.id, languages.inputMethods.currentId)]]"
-              actionable on-click="onInputMethodTap_"
-              on-keypress="onInputMethodTap_" on-mousedown="onMouseDown_"
-              tabindex$="[[getInputMethodTabIndex_(
-                  item.id, languages.inputMethods.currentId)]]"
-              aria-labelledby$="language-[[index]]" role="button">
-            <div class="start" id="language-[[index]]" aria-hidden="true">
-              <div class="display-name">[[item.displayName]]</div>
-              <div class="explain-selected"
-                  hidden="[[!isCurrentInputMethod_(
-                      item.id, languages.inputMethods.currentId)]]">
-                $i18n{inputMethodEnabled}
-              </div>
-            </div>
-            <template is="dom-if" if="[[hasOptionsPageInSettings_(item.id)]]">
-              <div class="internal-wrapper" hidden="[[!item.hasOptionsPage]]">
-                <cr-icon-button class="subpage-arrow"
-                    on-click="navigateToOptionsPageInSettings_">
-                </cr-icon-button>
-              </div>
-            </template>
-            <template is="dom-if" if="[[!hasOptionsPageInSettings_(item.id)]]">
-              <div class="external-wrapper" hidden="[[!item.hasOptionsPage]]">
-                <div class="separator"></div>
-                <cr-icon-button class="icon-external"
-                    on-click="openExtensionOptionsPage_"></cr-icon-button>
-              </div>
-            </template>
-          </div>
-        </template>
-        <cr-link-row class="hr list-item" id="manageInputMethods"
-            on-click="onManageInputMethodsTap_"
-            label="$i18n{manageInputMethods}"
-            role-description="$i18n{subpageArrowRoleDescription}"></cr-link-row>
-      </div>
-      <settings-toggle-button
-          class="hr" id="showImeMenu"
-          pref="{{prefs.settings.language.ime_menu_activated}}"
-          label="$i18n{showImeMenu}"
-          on-settings-boolean-control-change="onShowImeMenuChange_"
-          deep-link-focus-id$="[[Setting.kShowInputOptionsInShelf]]">
-      </settings-toggle-button>
-
-      <cr-lazy-render id="menu">
-        <template>
-          <cr-action-menu class="complex" on-close="onCloseMenu_"
-              role-description="$i18n{menu}">
-            <cr-checkbox id="uiLanguageItem" class="dropdown-item"
-                hidden="[[isGuest_]]"
-                disabled="[[disableUILanguageCheckbox_(
-                    detailLanguage_, languages.prospectiveUILanguage)]]"
-                checked="[[isProspectiveUILanguage_(
-                    detailLanguage_.language.code,
-                    languages.prospectiveUILanguage)]]"
-                on-change="onUILanguageChange_">
-              <span>$i18n{displayInThisLanguage}</span>
-              <iron-icon class="policy" icon="cr20:domain" hidden$="[[
-                  !detailLanguage_.language.isProhibitedLanguage]]">
-              </iron-icon>
-            </cr-checkbox>
-            <hr hidden="[[!shouldShowDialogSeparator_(languages.enabled.*)]]">
-            <button class="dropdown-item" role="menuitem"
-                on-click="onMoveToTopTap_"
-                hidden="[[isNthLanguage_(
-                    0, detailLanguage_, languages.enabled.*)]]">
-              $i18n{moveToTop}
-            </button>
-            <button class="dropdown-item" role="menuitem"
-                on-click="onMoveUpTap_"
-                hidden="[[!showMoveUp_(detailLanguage_,
-                    languages.enabled.*)]]">
-              $i18n{moveUp}
-            </button>
-            <button class="dropdown-item" role="menuitem"
-                on-click="onMoveDownTap_"
-                hidden="[[!showMoveDown_(
-                    detailLanguage_, languages.enabled.*)]]">
-              $i18n{moveDown}
-            </button>
-            <button class="dropdown-item" role="menuitem"
-                on-click="onRemoveLanguageTap_"
-                hidden="[[!detailLanguage_.removable]]">
-              $i18n{removeLanguage}
-            </button>
-          </cr-action-menu>
-        </template>
-      </cr-lazy-render>
-    </div>
-
-    <template is="dom-if" if="[[showAddLanguagesDialog_]]" restamp>
-      <os-settings-add-languages-dialog languages="{{languages}}"
-          language-helper="[[languageHelper]]"
-          on-close="onAddLanguagesDialogClose_">
-      </os-settings-add-languages-dialog>
-    </template>
-  </template>
-  <script src="os_languages_page.js"></script>
-</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.js b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.js
deleted file mode 100644
index 8edb4717..0000000
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page.js
+++ /dev/null
@@ -1,589 +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.
-
-// TODO(crbug.com/1097328): Delete this file and the 'displayLanguageRestart'
-//     i18n string definition, as this is unused.
-
-/**
- * @fileoverview 'os-settings-languages-page' is the settings sub-page
- * for language and input method settings.
- */
-cr.define('settings', function() {
-  /**
-   * @type {number} Millisecond delay that can be used when closing an action
-   *      menu to keep it briefly on-screen.
-   */
-  const kMenuCloseDelay = 100;
-
-  Polymer({
-    is: 'os-settings-languages-page',
-
-    behaviors: [
-      DeepLinkingBehavior,
-      I18nBehavior,
-      PrefsBehavior,
-      settings.RouteObserverBehavior,
-    ],
-
-    properties: {
-      /**
-       * Preferences state.
-       */
-      prefs: {
-        type: Object,
-        notify: true,
-      },
-
-      /**
-       * Read-only reference to the languages model provided by the
-       * 'os-settings-languages' instance.
-       * @type {!LanguagesModel|undefined}
-       */
-      languages: {
-        type: Object,
-        notify: true,
-      },
-
-      /** @type {!LanguageHelper} */
-      languageHelper: Object,
-
-      /**
-       * The language to display the details for.
-       * @type {!LanguageState|undefined}
-       * @private
-       */
-      detailLanguage_: Object,
-
-      /** @private */
-      showAddLanguagesDialog_: Boolean,
-
-      /** @type {!Map<string, (string|Function)>} */
-      focusConfig: {
-        type: Object,
-        observer: 'focusConfigChanged_',
-      },
-
-      /** @private */
-      isGuest_: {
-        type: Boolean,
-        value() {
-          return loadTimeData.getBoolean('isGuest');
-        },
-      },
-
-      /**
-       * Used by DeepLinkingBehavior to focus this page's deep links.
-       * @type {!Set<!chromeos.settings.mojom.Setting>}
-       */
-      supportedSettingIds: {
-        type: Object,
-        value: () => new Set([
-          chromeos.settings.mojom.Setting.kAddLanguage,
-          chromeos.settings.mojom.Setting.kShowInputOptionsInShelf,
-        ]),
-      },
-    },
-
-    /** @private {?settings.LanguagesMetricsProxy} */
-    languagesMetricsProxy_: null,
-
-    /** @override */
-    created() {
-      this.languagesMetricsProxy_ =
-          settings.LanguagesMetricsProxyImpl.getInstance();
-    },
-
-    /**
-     * @param {!settings.Route} route
-     * @param {!settings.Route} oldRoute
-     */
-    currentRouteChanged(route, oldRoute) {
-      this.attemptDeepLink();
-    },
-
-    /** @private {boolean} */
-    isChangeInProgress_: false,
-
-    /**
-     * @param {!Map<string, (string|Function)>} newConfig
-     * @param {?Map<string, (string|Function)>} oldConfig
-     * @private
-     */
-    focusConfigChanged_(newConfig, oldConfig) {
-      // focusConfig is set only once on the parent, so this observer should
-      // only fire once.
-      assert(!oldConfig);
-      this.focusConfig.set(
-          settings.routes.OS_LANGUAGES_INPUT.path,
-          () => cr.ui.focusWithoutInk(this.$.manageInputMethods));
-    },
-
-    /**
-     * @param {!Event} e
-     * @private
-     */
-    onShowImeMenuChange_(e) {
-      this.languagesMetricsProxy_.recordToggleShowInputOptionsOnShelf(
-          e.target.checked);
-    },
-
-    /**
-     * Stamps and opens the Add Languages dialog, registering a listener to
-     * disable the dialog's dom-if again on close.
-     * @param {!Event} e
-     * @private
-     */
-    onAddLanguagesTap_(e) {
-      e.preventDefault();
-      this.languagesMetricsProxy_.recordAddLanguages();
-      this.showAddLanguagesDialog_ = true;
-    },
-
-    /** @private */
-    onAddLanguagesDialogClose_() {
-      this.showAddLanguagesDialog_ = false;
-      cr.ui.focusWithoutInk(assert(this.$.addLanguages));
-    },
-
-    /**
-     * Checks if there are supported languages that are not enabled but can be
-     * enabled.
-     * @param {LanguagesModel|undefined} languages
-     * @return {boolean} True if there is at least one available language.
-     * @private
-     */
-    canEnableSomeSupportedLanguage_(languages) {
-      return languages === undefined || languages.supported.some(language => {
-        return this.languageHelper.canEnableLanguage(language);
-      });
-    },
-
-    /**
-     * Used to determine whether to show the separator between checkbox settings
-     * and move buttons in the dialog menu.
-     * @return {boolean} True if there is currently more than one selected
-     *     language.
-     * @private
-     */
-    shouldShowDialogSeparator_() {
-      return this.languages !== undefined &&
-          this.languages.enabled.length > 1 && !this.isGuest_;
-    },
-
-    /**
-     * Used to determine which "Move" buttons to show for ordering enabled
-     * languages.
-     * @param {number} n
-     * @return {boolean} True if |language| is at the |n|th index in the list of
-     *     enabled languages.
-     * @private
-     */
-    isNthLanguage_(n) {
-      if (this.languages === undefined || this.detailLanguage_ === undefined) {
-        return false;
-      }
-
-      if (n >= this.languages.enabled.length) {
-        return false;
-      }
-
-      const compareLanguage = assert(this.languages.enabled[n]);
-      return this.detailLanguage_.language === compareLanguage.language;
-    },
-
-    /**
-     * @return {boolean} True if the "Move to top" option for |language| should
-     *     be visible.
-     * @private
-     */
-    showMoveUp_() {
-      // "Move up" is a no-op for the top language, and redundant with
-      // "Move to top" for the 2nd language.
-      return !this.isNthLanguage_(0) && !this.isNthLanguage_(1);
-    },
-
-    /**
-     * @return {boolean} True if the "Move down" option for |language| should be
-     *     visible.
-     * @private
-     */
-    showMoveDown_() {
-      return this.languages !== undefined &&
-          !this.isNthLanguage_(this.languages.enabled.length - 1);
-    },
-
-    /**
-     * @param {!Object} change Polymer change object for languages.enabled.*.
-     * @return {boolean} True if there are less than 2 languages.
-     */
-    isHelpTextHidden_(change) {
-      return this.languages !== undefined && this.languages.enabled.length <= 1;
-    },
-
-    /**
-     * Opens the Manage Input Methods page.
-     * @private
-     */
-    onManageInputMethodsTap_() {
-      this.languagesMetricsProxy_.recordManageInputMethods();
-      settings.Router.getInstance().navigateTo(
-          settings.routes.OS_LANGUAGES_INPUT);
-    },
-
-    /**
-     * Handler for tap and <Enter> events on an input method on the main page,
-     * which sets it as the current input method.
-     * @param {!{model: !{item: !chrome.languageSettingsPrivate.InputMethod},
-     *           target: !{tagName: string},
-     *           type: string,
-     *           key: (string|undefined)}} e
-     */
-    onInputMethodTap_(e) {
-      // Taps on the button are handled in onInputMethodOptionsTap_.
-      // TODO(dschuyler): The row has two operations that are not clearly
-      // delineated. crbug.com/740691
-      if (e.target.tagName === 'CR-ICON-BUTTON') {
-        return;
-      }
-
-      // Ignore key presses other than <Enter>.
-      if (e.type === 'keypress' && e.key !== 'Enter') {
-        return;
-      }
-
-      // Set the input method.
-      this.languageHelper.setCurrentInputMethod(e.model.item.id);
-    },
-
-    /**
-     * Opens the input method extension's options page in a new tab (or focuses
-     * an existing instance of the IME's options).
-     * @param {!{model: !{item: chrome.languageSettingsPrivate.InputMethod}}} e
-     * @private
-     */
-    openExtensionOptionsPage_(e) {
-      this.languageHelper.openInputMethodOptions(e.model.item.id);
-    },
-
-
-    /**
-     * @param {string} id Input method ID.
-     * @return {boolean} True if there is a options page in ChromeOS settings
-     *     for the input method ID.
-     * @private
-     */
-    hasOptionsPageInSettings_(id) {
-      return loadTimeData.getBoolean('imeOptionsInSettings') &&
-          settings.input_method_util.hasOptionsPageInSettings(id);
-    },
-
-    /**
-     * Navigate to the input method options page in ChromeOS settings.
-     * @param {!{model: !{item: chrome.languageSettingsPrivate.InputMethod}}} e
-     * @private
-     */
-    navigateToOptionsPageInSettings_(e) {
-      const params = new URLSearchParams;
-      params.append('id', e.model.item.id);
-      settings.Router.getInstance().navigateTo(
-          settings.routes.OS_LANGUAGES_INPUT_METHOD_OPTIONS, params);
-    },
-
-    /**
-     * @return {boolean} True for a secondary user in a multi-profile session.
-     * @private
-     */
-    isSecondaryUser_() {
-      return loadTimeData.getBoolean('isSecondaryUser');
-    },
-
-    /**
-     * @param {string} languageCode The language code identifying a language.
-     * @param {string} prospectiveUILanguage The prospective UI language.
-     * @return {boolean} True if the prospective UI language is set to
-     *     |languageCode| but requires a restart to take effect.
-     * @private
-     */
-    isRestartRequired_(languageCode, prospectiveUILanguage) {
-      return prospectiveUILanguage === languageCode &&
-          this.languageHelper.requiresRestart();
-    },
-
-    /** @private */
-    onCloseMenu_() {
-      if (!this.isChangeInProgress_) {
-        return;
-      }
-      Polymer.dom.flush();
-      this.isChangeInProgress_ = false;
-      const restartButton = this.$$('#restartButton');
-      if (!restartButton) {
-        return;
-      }
-      cr.ui.focusWithoutInk(restartButton);
-    },
-
-    /**
-     * @param {!LanguageState} languageState
-     * @param {string} prospectiveUILanguage The chosen UI language.
-     * @return {boolean} True if the given language cannot be set as the
-     *     prospective UI language by the user.
-     * @private
-     */
-    disableUILanguageCheckbox_(languageState, prospectiveUILanguage) {
-      if (this.detailLanguage_ === undefined) {
-        return true;
-      }
-
-      // UI language setting belongs to the primary user.
-      if (this.isSecondaryUser_()) {
-        return true;
-      }
-
-      // If the language cannot be a UI language, we can't set it as the
-      // prospective UI language.
-      if (!languageState.language.supportsUI) {
-        return true;
-      }
-
-      // Unchecking the currently chosen language doesn't make much sense.
-      if (languageState.language.code === prospectiveUILanguage) {
-        return true;
-      }
-
-      // Check if the language is prohibited by the current "AllowedLanguages"
-      // policy.
-      if (languageState.language.isProhibitedLanguage) {
-        return true;
-      }
-
-      // Otherwise, the prospective language can be changed to this language.
-      return false;
-    },
-
-    /**
-     * Handler for changes to the UI language checkbox.
-     * @param {!{target: !Element}} e
-     * @private
-     */
-    onUILanguageChange_(e) {
-      // We don't support unchecking this checkbox. TODO(michaelpg): Ask for a
-      // simpler widget.
-      assert(e.target.checked);
-      this.languagesMetricsProxy_.recordInteraction(
-          settings.LanguagesPageInteraction.SWITCH_SYSTEM_LANGUAGE);
-      this.isChangeInProgress_ = true;
-      this.languageHelper.setProspectiveUILanguage(
-          this.detailLanguage_.language.code);
-      this.languageHelper.moveLanguageToFront(
-          this.detailLanguage_.language.code);
-
-      this.closeMenuSoon_();
-    },
-
-    /**
-     * Moves the language to the top of the list.
-     * @private
-     */
-    onMoveToTopTap_() {
-      /** @type {!CrActionMenuElement} */ (this.$.menu.get()).close();
-      this.languageHelper.moveLanguageToFront(
-          this.detailLanguage_.language.code);
-      settings.recordSettingChange();
-    },
-
-    /**
-     * Moves the language up in the list.
-     * @private
-     */
-    onMoveUpTap_() {
-      /** @type {!CrActionMenuElement} */ (this.$.menu.get()).close();
-      this.languageHelper.moveLanguage(
-          this.detailLanguage_.language.code, true /* upDirection */);
-      settings.recordSettingChange();
-    },
-
-    /**
-     * Moves the language down in the list.
-     * @private
-     */
-    onMoveDownTap_() {
-      /** @type {!CrActionMenuElement} */ (this.$.menu.get()).close();
-      this.languageHelper.moveLanguage(
-          this.detailLanguage_.language.code, false /* upDirection */);
-      settings.recordSettingChange();
-    },
-
-    /**
-     * Disables the language.
-     * @private
-     */
-    onRemoveLanguageTap_() {
-      /** @type {!CrActionMenuElement} */ (this.$.menu.get()).close();
-      this.languageHelper.disableLanguage(this.detailLanguage_.language.code);
-      settings.recordSettingChange();
-    },
-
-    /**
-     * Checks whether the prospective UI language (the pref that indicates what
-     * language to use in Chrome) matches the current language.
-     * @param {string} languageCode The language code identifying a language.
-     * @param {string} prospectiveUILanguage The prospective UI language.
-     * @return {boolean} True if the given language matches the prospective UI
-     *     pref (which may be different from the actual UI language).
-     * @private
-     */
-    isProspectiveUILanguage_(languageCode, prospectiveUILanguage) {
-      return languageCode === prospectiveUILanguage;
-    },
-
-    /**
-     * Returns either the "selected" class, if the language matches the
-     * prospective UI language, or an empty string.
-     * @param {string} languageCode The language code identifying a language.
-     * @param {string} prospectiveUILanguage The prospective UI language.
-     * @return {string} The class name for the language item.
-     * @private
-     */
-    getLanguageItemClass_(languageCode, prospectiveUILanguage) {
-      if (languageCode === prospectiveUILanguage) {
-        return 'selected';
-      }
-      return '';
-    },
-
-    /**
-     * @param {string} id The input method ID.
-     * @param {string} currentId The ID of the currently enabled input method.
-     * @return {boolean} True if the IDs match.
-     * @private
-     */
-    isCurrentInputMethod_(id, currentId) {
-      return id === currentId;
-    },
-
-    /**
-     * @param {string} id The input method ID.
-     * @param {string} currentId The ID of the currently enabled input method.
-     * @return {string} The class for the input method item.
-     * @private
-     */
-    getInputMethodItemClass_(id, currentId) {
-      return this.isCurrentInputMethod_(id, currentId) ? 'selected' : '';
-    },
-
-    /**
-     * @param {!Event} e
-     * @private
-     */
-    onDotsTap_(e) {
-      // Set a copy of the LanguageState object since it is not data-bound to
-      // the languages model directly.
-      this.detailLanguage_ = /** @type {!LanguageState} */ (Object.assign(
-          {},
-          /** @type {!{model: !{item: !LanguageState}}} */ (e).model.item));
-
-      // Ensure the template has been stamped.
-      let menu =
-          /** @type {?CrActionMenuElement} */ (this.$.menu.getIfExists());
-      if (!menu) {
-        menu = /** @type {!CrActionMenuElement} */ (this.$.menu.get());
-
-        // In a CrOS multi-user session, the primary user controls the UI
-        // language.
-        // TODO(michaelpg): The language selection should not be hidden, but
-        // should show a policy indicator. crbug.com/648498
-        if (this.isSecondaryUser_()) {
-          menu.querySelector('#uiLanguageItem').hidden = true;
-        }
-      }
-
-      menu.showAt(/** @type {!Element} */ (e.target));
-    },
-
-    /**
-     * Closes the shared action menu after a short delay, so when a checkbox is
-     * clicked it can be seen to change state before disappearing.
-     * @private
-     */
-    closeMenuSoon_() {
-      const menu = /** @type {!CrActionMenuElement} */ (this.$.menu.get());
-      setTimeout(function() {
-        if (menu.open) {
-          menu.close();
-        }
-      }, settings.kMenuCloseDelay);
-    },
-
-    /**
-     * Handler for the restart button.
-     * @private
-     */
-    onRestartTap_() {
-      settings.recordSettingChange();
-      this.languagesMetricsProxy_.recordInteraction(
-          settings.LanguagesPageInteraction.RESTART);
-      settings.LifetimeBrowserProxyImpl.getInstance().signOutAndRestart();
-    },
-
-    /**
-     * Toggles the expand button within the element being listened to.
-     * @param {!Event} e
-     * @private
-     */
-    toggleExpandButton_(e) {
-      // The expand button handles toggling itself.
-      const expandButtonTag = 'CR-EXPAND-BUTTON';
-      if (e.target.tagName === expandButtonTag) {
-        return;
-      }
-
-      if (!e.currentTarget.hasAttribute('actionable')) {
-        return;
-      }
-
-      /** @type {!CrExpandButtonElement} */
-      const expandButton = e.currentTarget.querySelector(expandButtonTag);
-      assert(expandButton);
-      expandButton.expanded = !expandButton.expanded;
-      cr.ui.focusWithoutInk(expandButton);
-    },
-
-    /**
-     * @param {string} id The selected input method ID.
-     * @param {string} currentId The ID of the currently enabled input method.
-     * @return {string} The default tab index '0' if the selected input method
-     *     is not currently enabled; otherwise, returns an empty string which
-     *     effectively unsets the tabindex attribute.
-     * @private
-     */
-    getInputMethodTabIndex_(id, currentId) {
-      return id === currentId ? '' : '0';
-    },
-
-    /**
-     * Handles the mousedown even by preventing focusing an input method list
-     * item. This is only registered by the input method list item to avoid
-     * unwanted focus.
-     * @param {!Event} e
-     * @private
-     */
-    onMouseDown_(e) {
-      // Preventing the mousedown event from propagating prevents focus being
-      // set.
-      e.preventDefault();
-    },
-
-    /**
-     * @param {string} language The language displayed in the row
-     * @return {string}
-     * @private
-     */
-    getRestartButtonDescription_(language) {
-      return this.i18n('displayLanguageRestart', language);
-    },
-  });
-  // #cr_define_end
-  return {kMenuCloseDelay};
-});
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.html b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.html
index 4f10531..c0c411c 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.html
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.html
@@ -2,14 +2,13 @@
 
 <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
 <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="input_page.html">
-<link rel="import" href="os_languages_page.html">
 <link rel="import" href="os_languages_page_v2.html">
 <link rel="import" href="smart_inputs_page.html">
 <link rel="import" href="input_method_options_page.html">
 <link rel="import" href="../../i18n_setup.html">
 <link rel="import" href="../../languages_page/languages.html">
-<link rel="import" href="manage_input_methods_page.html">
 <link rel="import" href="../os_route.html">
 <link rel="import" href="../../router.html">
 <link rel="import" href="../../settings_page/settings_animated_pages.html">
@@ -41,7 +40,7 @@
         <cr-link-row
             class="hr"
             id="inputPageTrigger"
-            label="$i18n{inputPageTitle}"
+            label="[[inputPageTitle_]]"
             sub-label="[[getInputMethodDisplayName_(
               languages.inputMethods.currentId, languageHelper)]]"
             on-click="onInputClick_"
@@ -75,7 +74,7 @@
       <template is="dom-if" route-path="/osLanguages/input">
         <settings-subpage
             associated-control="[[$$('#inputPageTrigger')]]"
-            page-title="$i18n{inputPageTitle}">
+            page-title="[[inputPageTitle_]]">
           <os-settings-input-page language-helper="[[languageHelper]]"
               languages="[[languages]]" prefs="{{prefs}}"
               focus-config="[[focusConfig_]]">
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.js b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.js
index cd4fd77..4365ae71 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.js
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.js
@@ -10,6 +10,10 @@
 Polymer({
   is: 'os-settings-languages-section',
 
+  behaviors: [
+    I18nBehavior,
+  ],
+
   properties: {
     prefs: Object,
 
@@ -36,6 +40,16 @@
       },
     },
 
+    /** @private */
+    inputPageTitle_: {
+      type: String,
+      value() {
+        const isUpdate2 =
+            loadTimeData.getBoolean('enableLanguageSettingsV2Update2');
+        return this.i18n(isUpdate2 ? 'inputPageTitleV2' : 'inputPageTitle');
+      },
+    },
+
     /**
      * This is enabled when any of the smart inputs features is allowed.
      * @private
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.html b/chrome/browser/resources/settings/languages_page/languages_page.html
index ea7b16be..0f4315d 100644
--- a/chrome/browser/resources/settings/languages_page/languages_page.html
+++ b/chrome/browser/resources/settings/languages_page/languages_page.html
@@ -1,3 +1,6 @@
+    <!-- TODO(crbug.com/1097328): Remove all chromeos references here, and move
+         #openChromeOSLanguagesSettings to the parent component instead
+         (settings-basic-page). -->
     <style include="cr-shared-style settings-shared action-link iron-flex">
       #languagesCollapse .list-item.selected {
         min-height: var(--settings-row-two-line-min-height);
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.js b/chrome/browser/resources/settings/languages_page/languages_page.js
index 90dc2d397..5bbd753 100644
--- a/chrome/browser/resources/settings/languages_page/languages_page.js
+++ b/chrome/browser/resources/settings/languages_page/languages_page.js
@@ -6,6 +6,8 @@
  * @fileoverview 'settings-languages-page' is the settings page
  * for language and input method settings.
  */
+
+// TODO(crbug.com/1097328): Remove all chromeos references here.
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.m.js';
 import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
diff --git a/chrome/browser/resources/settings/languages_page/languages_subpage.html b/chrome/browser/resources/settings/languages_page/languages_subpage.html
index 890632f..85ffb30 100644
--- a/chrome/browser/resources/settings/languages_page/languages_subpage.html
+++ b/chrome/browser/resources/settings/languages_page/languages_subpage.html
@@ -34,11 +34,6 @@
     hidden="[[isHelpTextHidden_(languages.enabled.*)]]">
     <div class="cr-padded-text">
     <span>$i18n{orderBrowserLanguagesInstructions}</span>
-<if expr="chromeos">
-    <a href="$i18n{languagesLearnMoreURL}" target="_blank">
-      $i18n{learnMore}
-    </a>
-</if> <!-- chromeos -->
     </div>
   </div>
   <div class="list-frame vertical-list">
@@ -54,16 +49,16 @@
           <div class="target-info secondary">
             $i18n{translateTargetLabel}
           </div>
-<if expr="chromeos or is_win">
+<if expr="is_win">
           <div class="explain-selected"
               hidden="[[!isProspectiveUILanguage_(
                   item.language.code,
                   languages.prospectiveUILanguage)]]">
             $i18n{isDisplayedInThisLanguage}
           </div>
-</if> <!-- chromeos or is_win -->
+</if> <!-- is_win -->
         </div>
-<if expr="chromeos or is_win">
+<if expr="is_win">
         <template is="dom-if" if="[[isRestartRequired_(
             item.language.code, languages.prospectiveUILanguage)]]"
             restamp>
@@ -71,7 +66,7 @@
             $i18n{restart}
           </cr-button>
         </template>
-</if> <!-- chromeos or is_win -->
+</if> <!-- is_win -->
         <cr-icon-button class="icon-more-vert"
             title="$i18n{moreActions}"
             id="more-[[item.language.code]]"
@@ -144,11 +139,11 @@
   <cr-lazy-render id="menu">
       <template>
         <cr-action-menu role-description="$i18n{menu}"
-<if expr="chromeos or is_win">
+<if expr="is_win">
             on-close="onCloseMenu_"
 </if>
             class$="[[getMenuClass_(prefs.translate.enabled.value)]]">
-<if expr="chromeos or is_win">
+<if expr="is_win">
           <cr-checkbox id="uiLanguageItem"
               class="dropdown-item"
               checked="[[isProspectiveUILanguage_(
@@ -162,7 +157,7 @@
                 !detailLanguage_.language.isProhibitedLanguage]]">
             </iron-icon>
           </cr-checkbox>
-</if> <!-- chromeos or is_win -->
+</if> <!-- is_win -->
           <template is="dom-if" if="[[!enableDesktopDetailedLanguageSettings_]]">
             <cr-checkbox id="offerTranslations"
                 class="dropdown-item"
diff --git a/chrome/browser/resources/settings/languages_page/languages_subpage.js b/chrome/browser/resources/settings/languages_page/languages_subpage.js
index 5f8b288334..d1f9d64 100644
--- a/chrome/browser/resources/settings/languages_page/languages_subpage.js
+++ b/chrome/browser/resources/settings/languages_page/languages_subpage.js
@@ -6,6 +6,8 @@
  * @fileoverview 'settings-languages-page' is the settings page
  * for language and input method settings.
  */
+
+// TODO(crbug.com/1097328): Remove all chromeos references here.
 import 'chrome://resources/cr_components/managed_dialog/managed_dialog.js';
 import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.m.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
diff --git a/chrome/browser/resources/settings/route.js b/chrome/browser/resources/settings/route.js
index d1bb364b..fe6ea73 100644
--- a/chrome/browser/resources/settings/route.js
+++ b/chrome/browser/resources/settings/route.js
@@ -143,7 +143,11 @@
     r.PRIVACY = r.BASIC.createSection('/privacy', 'privacy');
     addPrivacyChildRoutes(r);
 
-    r.SAFETY_CHECK = r.BASIC.createSection('/safetyCheck', 'safetyCheck');
+    if (loadTimeData.getBoolean('enableLandingPageRedesign')) {
+      r.SAFETY_CHECK = r.PRIVACY.createSection('/safetyCheck', 'safetyCheck');
+    } else {
+      r.SAFETY_CHECK = r.BASIC.createSection('/safetyCheck', 'safetyCheck');
+    }
   }
 
   // <if expr="not chromeos and not lacros">
diff --git a/chrome/browser/resources/settings/settings_menu/settings_menu.html b/chrome/browser/resources/settings/settings_menu/settings_menu.html
index 2ecb987..eace8e27 100644
--- a/chrome/browser/resources/settings/settings_menu/settings_menu.html
+++ b/chrome/browser/resources/settings/settings_menu/settings_menu.html
@@ -111,12 +111,14 @@
             <iron-icon icon="settings:assignment"></iron-icon>
             $i18n{autofillPageTitle}
           </a>
-          <a role="menuitem" href="/safetyCheck"
-              hidden="[[!pageVisibility.safetyCheck]]"
-              id="safetyCheck">
-            <iron-icon icon="settings20:safety-check"></iron-icon>
-            $i18n{safetyCheckSectionTitle}
-          </a>
+          <template is="dom-if" if="[[!enableLandingPageRedesign_]]">
+            <a role="menuitem" href="/safetyCheck"
+                hidden="[[!pageVisibility.safetyCheck]]"
+                id="safetyCheck">
+              <iron-icon icon="settings20:safety-check"></iron-icon>
+              $i18n{safetyCheckSectionTitle}
+            </a>
+          </template>
           <a role="menuitem" href="/privacy"
               hidden="[[!pageVisibility.privacy]]">
             <iron-icon icon="cr:security"></iron-icon>
diff --git a/chrome/browser/resources/settings/settings_menu/settings_menu.js b/chrome/browser/resources/settings/settings_menu/settings_menu.js
index a10c4d72..c1e430e 100644
--- a/chrome/browser/resources/settings/settings_menu/settings_menu.js
+++ b/chrome/browser/resources/settings/settings_menu/settings_menu.js
@@ -13,13 +13,12 @@
 import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js';
-import '../i18n_setup.js';
 import '../icons.js';
 import '../settings_shared_css.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 {loadTimeData} from '../i18n_setup.js';
 import {PageVisibility} from '../page_visibility.js';
 import {Route, RouteObserverBehavior, Router} from '../router.js';
 
@@ -42,6 +41,12 @@
      * @type {!PageVisibility}
      */
     pageVisibility: Object,
+
+    /** @private */
+    enableLandingPageRedesign_: {
+      type: Boolean,
+      value: () => loadTimeData.getBoolean('enableLandingPageRedesign'),
+    },
   },
 
   /** @param {!Route} newRoute */
diff --git a/chrome/browser/resources/settings/settings_page/main_page_behavior.js b/chrome/browser/resources/settings/settings_page/main_page_behavior.js
index 746b2e7..333dccfc 100644
--- a/chrome/browser/resources/settings/settings_page/main_page_behavior.js
+++ b/chrome/browser/resources/settings/settings_page/main_page_behavior.js
@@ -199,6 +199,41 @@
     },
 
     /**
+     * Finds the settings-section instances corresponding to the given route. If
+     * the section is lazily loaded it force-renders it.
+     * Note: If the section resides within "advanced" settings, a
+     * 'hide-container' event is fired (necessary to avoid flashing). Callers
+     * are responsible for firing a 'show-container' event.
+     * @param {!Route} route
+     * @return {!Promise<!Array<!SettingsSectionElement>>}
+     * @private
+     */
+    ensureSectionsForRoute_(route) {
+      const sections = this.querySettingsSections_(route.section);
+      if (sections.length > 0) {
+        return Promise.resolve(sections);
+      }
+
+      // The function to use to wait for <dom-if>s to render.
+      const waitFn = beforeNextRender.bind(null, this);
+
+      return new Promise(resolve => {
+        if (this.shouldExpandAdvanced_(route)) {
+          this.fire('hide-container');
+          waitFn(() => {
+            this.$$('#advancedPageTemplate').get().then(() => {
+              resolve(this.querySettingsSections_(route.section));
+            });
+          });
+        } else {
+          waitFn(() => {
+            resolve(this.querySettingsSections_(route.section));
+          });
+        }
+      });
+    },
+
+    /**
      * @param {!Route} route
      * @private
      */
@@ -255,19 +290,23 @@
     },
 
     /**
-     * Shows the section corresponding to |newRoute| and hides the previously
-     * |active| section (if any).
+     * Shows the section(s) corresponding to |newRoute| and hides the previously
+     * |active| section(s), if any.
      * @param {!Route} newRoute
      */
-    switchToSection_(newRoute) {
-      this.ensureSectionForRoute_(newRoute).then(section => {
+    switchToSections_(newRoute) {
+      this.ensureSectionsForRoute_(newRoute).then(sections => {
         // Clear any previously |active| section.
-        const oldSection = this.$$(`settings-section[active]`);
-        if (oldSection) {
-          oldSection.toggleAttribute('active', false);
+        const oldSections =
+            this.shadowRoot.querySelectorAll(`settings-section[active]`);
+        for (const s of oldSections) {
+          s.toggleAttribute('active', false);
         }
 
-        section.toggleAttribute('active', true);
+        for (const s of sections) {
+          s.toggleAttribute('active', true);
+        }
+
         this.fire('show-container');
       });
     },
@@ -431,13 +470,13 @@
     processTransitionRedesign_(oldRoute, newRoute, oldState, newState) {
       if (oldState === RouteState.TOP_LEVEL) {
         if (newState === RouteState.SECTION) {
-          this.switchToSection_(newRoute);
+          this.switchToSections_(newRoute);
         } else if (newState === RouteState.SUBPAGE) {
           this.enterSubpage_(newRoute);
         } else if (newState === RouteState.TOP_LEVEL) {
           // Case when navigating from '/?search=foo' to '/' (clearing search
           // results).
-          this.switchToSection_(TOP_LEVEL_EQUIVALENT_ROUTE);
+          this.switchToSections_(TOP_LEVEL_EQUIVALENT_ROUTE);
         }
         // Nothing to do here for the case of RouteState.DIALOG.
         return;
@@ -445,12 +484,12 @@
 
       if (oldState === RouteState.SECTION) {
         if (newState === RouteState.SECTION) {
-          this.switchToSection_(newRoute);
+          this.switchToSections_(newRoute);
         } else if (newState === RouteState.SUBPAGE) {
-          this.switchToSection_(newRoute);
+          this.switchToSections_(newRoute);
           this.enterSubpage_(newRoute);
         } else if (newState === RouteState.TOP_LEVEL) {
-          this.switchToSection_(TOP_LEVEL_EQUIVALENT_ROUTE);
+          this.switchToSections_(TOP_LEVEL_EQUIVALENT_ROUTE);
           this.scroller.scrollTop = 0;
         }
         // Nothing to do here for the case of RouteState.DIALOG.
@@ -460,7 +499,7 @@
       if (oldState === RouteState.SUBPAGE) {
         if (newState === RouteState.SECTION) {
           this.enterMainPage_(/** @type {!Route} */ (oldRoute));
-          this.switchToSection_(newRoute);
+          this.switchToSections_(newRoute);
         } else if (newState === RouteState.SUBPAGE) {
           // Handle case where the two subpages belong to
           // different sections, but are linked to each other. For example
@@ -488,12 +527,12 @@
 
       if (oldState === RouteState.INITIAL) {
         if ([RouteState.SECTION, RouteState.DIALOG].includes(newState)) {
-          this.switchToSection_(newRoute);
+          this.switchToSections_(newRoute);
         } else if (newState === RouteState.SUBPAGE) {
-          this.switchToSection_(newRoute);
+          this.switchToSections_(newRoute);
           this.enterSubpage_(newRoute);
         } else if (newState === RouteState.TOP_LEVEL) {
-          this.switchToSection_(TOP_LEVEL_EQUIVALENT_ROUTE);
+          this.switchToSections_(TOP_LEVEL_EQUIVALENT_ROUTE);
         }
         return;
       }
@@ -515,4 +554,24 @@
       return /** @type {?SettingsSectionElement} */ (
           this.$$(`settings-section[section="${section}"]`));
     },
+
+    /*
+     * @param {string} sectionName Section name of the element to get.
+     * @return {!Array<!SettingsSectionElement>}
+     */
+    querySettingsSections_(sectionName) {
+      const result = [];
+      const section = this.getSection(sectionName);
+
+      if (section) {
+        result.push(section);
+      }
+
+      const extraSections = this.shadowRoot.querySelectorAll(
+          `settings-section[nest-under-section="${sectionName}"]`);
+      if (extraSections.length > 0) {
+        result.push(...extraSections);
+      }
+      return result;
+    }
   };
diff --git a/chrome/browser/safe_browsing/incident_reporting/last_download_finder.cc b/chrome/browser/safe_browsing/incident_reporting/last_download_finder.cc
index 70993af..06b7198 100644
--- a/chrome/browser/safe_browsing/incident_reporting/last_download_finder.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/last_download_finder.cc
@@ -327,7 +327,7 @@
                        weak_ptr_factory_.GetWeakPtr(), profile));
   } else {
     // else wait until history is loaded.
-    history_service_observer_.Add(history_service);
+    history_service_observations_.AddObservation(history_service);
   }
 }
 
@@ -436,7 +436,7 @@
 
 void LastDownloadFinder::HistoryServiceBeingDeleted(
     history::HistoryService* history_service) {
-  history_service_observer_.Remove(history_service);
+  history_service_observations_.RemoveObservation(history_service);
 }
 
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h b/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h
index 59e266e..3e8b8da 100644
--- a/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h
+++ b/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h
@@ -13,7 +13,7 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "base/scoped_observer.h"
+#include "base/scoped_multi_source_observation.h"
 #include "chrome/browser/profiles/profile_manager_observer.h"
 #include "chrome/browser/profiles/profile_observer.h"
 #include "chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.h"
@@ -134,8 +134,9 @@
   history::DownloadRow most_recent_non_binary_row_;
 
   // HistoryServiceObserver
-  ScopedObserver<history::HistoryService, history::HistoryServiceObserver>
-      history_service_observer_{this};
+  base::ScopedMultiSourceObservation<history::HistoryService,
+                                     history::HistoryServiceObserver>
+      history_service_observations_{this};
 
   // A factory for asynchronous operations on profiles' HistoryService.
   base::WeakPtrFactory<LastDownloadFinder> weak_ptr_factory_{this};
diff --git a/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc b/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
index 77b5ba5f..7baf4483 100644
--- a/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
+++ b/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
@@ -550,7 +550,7 @@
   operation_runner()->Copy(
       src_url, dest_url, storage::FileSystemOperation::OPTION_NONE,
       storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
-      storage::FileSystemOperationRunner::CopyProgressCallback(),
+      storage::FileSystemOperation::CopyOrMoveProgressCallback(),
       std::move(callback));
 }
 
@@ -559,9 +559,11 @@
                                       StatusCallback callback) {
   EXPECT_TRUE(io_task_runner_->RunsTasksInCurrentSequence());
   EXPECT_TRUE(is_filesystem_opened_);
-  operation_runner()->Move(src_url, dest_url,
-                           storage::FileSystemOperation::OPTION_NONE,
-                           std::move(callback));
+  operation_runner()->Move(
+      src_url, dest_url, storage::FileSystemOperation::OPTION_NONE,
+      storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
+      storage::FileSystemOperation::CopyOrMoveProgressCallback(),
+      std::move(callback));
 }
 
 void CannedSyncableFileSystem::DoTruncateFile(const FileSystemURL& url,
diff --git a/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc b/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc
index 892cf65..fecc34be 100644
--- a/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc
+++ b/chrome/browser/sync_file_system/local/syncable_file_operation_runner_unittest.cc
@@ -260,12 +260,12 @@
   file_system_.operation_runner()->Copy(
       URL(kDir), URL("dest-copy"), storage::FileSystemOperation::OPTION_NONE,
       storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
-      storage::FileSystemOperationRunner::CopyProgressCallback(),
+      storage::FileSystemOperation::CopyOrMoveProgressCallback(),
       ExpectStatus(FROM_HERE, File::FILE_OK));
   file_system_.operation_runner()->Move(
-      URL(kDir),
-      URL("dest-move"),
-      storage::FileSystemOperation::OPTION_NONE,
+      URL(kDir), URL("dest-move"), storage::FileSystemOperation::OPTION_NONE,
+      storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
+      storage::FileSystemOperation::CopyOrMoveProgressCallback(),
       ExpectStatus(FROM_HERE, File::FILE_OK));
   content::RunAllTasksUntilIdle();
   EXPECT_EQ(1, callback_count_);
@@ -284,7 +284,7 @@
   file_system_.operation_runner()->Copy(
       URL(kDir), URL("dest-copy2"), storage::FileSystemOperation::OPTION_NONE,
       storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
-      storage::FileSystemOperationRunner::CopyProgressCallback(),
+      storage::FileSystemOperation::CopyOrMoveProgressCallback(),
       ExpectStatus(FROM_HERE, File::FILE_OK));
   content::RunAllTasksUntilIdle();
   EXPECT_EQ(0, callback_count_);
diff --git a/chrome/browser/sync_file_system/local/syncable_file_system_operation.cc b/chrome/browser/sync_file_system/local/syncable_file_system_operation.cc
index 71da3087..be238be 100644
--- a/chrome/browser/sync_file_system/local/syncable_file_system_operation.cc
+++ b/chrome/browser/sync_file_system/local/syncable_file_system_operation.cc
@@ -124,7 +124,7 @@
     const FileSystemURL& dest_url,
     CopyOrMoveOption option,
     ErrorBehavior error_behavior,
-    const CopyProgressCallback& progress_callback,
+    const CopyOrMoveProgressCallback& progress_callback,
     StatusCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   if (!operation_runner_.get()) {
@@ -143,10 +143,13 @@
   operation_runner_->PostOperationTask(std::move(task));
 }
 
-void SyncableFileSystemOperation::Move(const FileSystemURL& src_url,
-                                       const FileSystemURL& dest_url,
-                                       CopyOrMoveOption option,
-                                       StatusCallback callback) {
+void SyncableFileSystemOperation::Move(
+    const FileSystemURL& src_url,
+    const FileSystemURL& dest_url,
+    CopyOrMoveOption option,
+    ErrorBehavior error_behavior,
+    const CopyOrMoveProgressCallback& progress_callback,
+    StatusCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   if (!operation_runner_.get()) {
     std::move(callback).Run(base::File::FILE_ERROR_NOT_FOUND);
@@ -160,7 +163,7 @@
       weak_factory_.GetWeakPtr(),
       base::BindOnce(
           &FileSystemOperation::Move, base::Unretained(impl_.get()), src_url,
-          dest_url, option,
+          dest_url, option, error_behavior, progress_callback,
           base::BindOnce(&self::DidFinish, weak_factory_.GetWeakPtr())));
   operation_runner_->PostOperationTask(std::move(task));
 }
diff --git a/chrome/browser/sync_file_system/local/syncable_file_system_operation.h b/chrome/browser/sync_file_system/local/syncable_file_system_operation.h
index b90fc66..065080fd 100644
--- a/chrome/browser/sync_file_system/local/syncable_file_system_operation.h
+++ b/chrome/browser/sync_file_system/local/syncable_file_system_operation.h
@@ -43,11 +43,13 @@
             const storage::FileSystemURL& dest_url,
             CopyOrMoveOption option,
             ErrorBehavior error_behavior,
-            const CopyProgressCallback& progress_callback,
+            const CopyOrMoveProgressCallback& progress_callback,
             StatusCallback callback) override;
   void Move(const storage::FileSystemURL& src_url,
             const storage::FileSystemURL& dest_url,
             CopyOrMoveOption option,
+            ErrorBehavior error_behavior,
+            const CopyOrMoveProgressCallback& progress_callback,
             StatusCallback callback) override;
   void DirectoryExists(const storage::FileSystemURL& url,
                        StatusCallback callback) override;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index a362920..1a492b4 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1835,6 +1835,8 @@
       "app_list/search/omnibox_result.h",
       "app_list/search/os_settings_provider.cc",
       "app_list/search/os_settings_provider.h",
+      "app_list/search/ranking/category_ranker.cc",
+      "app_list/search/ranking/category_ranker.h",
       "app_list/search/ranking/ranker.h",
       "app_list/search/ranking/ranker_delegate.cc",
       "app_list/search/ranking/ranker_delegate.h",
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
index 6b1df05..11a98fc 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -1841,15 +1841,19 @@
   icon->icon_png_data =
       std::vector<uint8_t>(icon_png_data.begin(), icon_png_data.end());
   for (auto& observer : observer_list_)
-    observer.OnTaskDescriptionChanged(task_id, label, *icon);
+    observer.OnTaskDescriptionChanged(task_id, label, *icon, 0, 0);
 }
 
 void ArcAppListPrefs::OnTaskDescriptionChanged(
     int32_t task_id,
     const std::string& label,
-    arc::mojom::RawIconPngDataPtr icon) {
-  for (auto& observer : observer_list_)
-    observer.OnTaskDescriptionChanged(task_id, label, *icon);
+    arc::mojom::RawIconPngDataPtr icon,
+    uint32_t primary_color,
+    uint32_t status_bar_color) {
+  for (auto& observer : observer_list_) {
+    observer.OnTaskDescriptionChanged(task_id, label, *icon, primary_color,
+                                      status_bar_color);
+  }
 }
 
 void ArcAppListPrefs::OnTaskDestroyed(int32_t task_id) {
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h
index 33e92fb..a0cc2fb8 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h
+++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h
@@ -194,7 +194,9 @@
     virtual void OnTaskDescriptionChanged(
         int32_t task_id,
         const std::string& label,
-        const arc::mojom::RawIconPngData& icon) {}
+        const arc::mojom::RawIconPngData& icon,
+        uint32_t primary_color,
+        uint32_t status_bar_color) {}
     // Notifies that task has been destroyed.
     virtual void OnTaskDestroyed(int32_t task_id) {}
     // Notifies that task has been activated and moved to the front.
@@ -450,7 +452,9 @@
       const std::vector<uint8_t>& icon_png_data) override;
   void OnTaskDescriptionChanged(int32_t task_id,
                                 const std::string& label,
-                                arc::mojom::RawIconPngDataPtr icon) override;
+                                arc::mojom::RawIconPngDataPtr icon,
+                                uint32_t primary_color,
+                                uint32_t status_bar_color) override;
   void OnTaskDestroyed(int32_t task_id) override;
   void OnTaskSetActive(int32_t task_id) override;
   void OnNotificationsEnabledChanged(const std::string& package_name,
diff --git a/chrome/browser/ui/app_list/arc/mock_arc_app_list_prefs_observer.h b/chrome/browser/ui/app_list/arc/mock_arc_app_list_prefs_observer.h
index 3efa0002..48f31e5c 100644
--- a/chrome/browser/ui/app_list/arc/mock_arc_app_list_prefs_observer.h
+++ b/chrome/browser/ui/app_list/arc/mock_arc_app_list_prefs_observer.h
@@ -35,10 +35,12 @@
                     const std::string& activity,
                     const std::string& intent,
                     int32_t session_id));
-  MOCK_METHOD3(OnTaskDescriptionChanged,
+  MOCK_METHOD5(OnTaskDescriptionChanged,
                void(int32_t task_id,
                     const std::string& label,
-                    const arc::mojom::RawIconPngData& icon));
+                    const arc::mojom::RawIconPngData& icon,
+                    uint32_t primary_color,
+                    uint32_t status_bar_color));
   MOCK_METHOD1(OnTaskDestroyed, void(int32_t task_id));
   MOCK_METHOD1(OnTaskSetActive, void(int32_t task_id));
   MOCK_METHOD2(OnNotificationsEnabledChanged,
diff --git a/chrome/browser/ui/app_list/search/help_app_provider.cc b/chrome/browser/ui/app_list/search/help_app_provider.cc
index f3bdbe1f..b8abdd6 100644
--- a/chrome/browser/ui/app_list/search/help_app_provider.cc
+++ b/chrome/browser/ui/app_list/search/help_app_provider.cc
@@ -45,8 +45,8 @@
 constexpr char kHelpAppUpdatesResult[] = "help-app://updates";
 constexpr float kScoreEps = 1e-5f;
 
-constexpr size_t kMinQueryLength = 5u;
-constexpr float kMinScore = 0.35f;
+constexpr size_t kMinQueryLength = 3u;
+constexpr float kMinScore = 0.4f;
 constexpr size_t kNumRequestedResults = 5u;
 constexpr size_t kMaxShownResults = 2u;
 
diff --git a/chrome/browser/ui/app_list/search/ranking/category_ranker.cc b/chrome/browser/ui/app_list/search/ranking/category_ranker.cc
new file mode 100644
index 0000000..ce4043c
--- /dev/null
+++ b/chrome/browser/ui/app_list/search/ranking/category_ranker.cc
@@ -0,0 +1,153 @@
+// 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 "chrome/browser/ui/app_list/search/ranking/category_ranker.h"
+#include "base/strings/string_number_conversions.h"
+#include "chrome/browser/ash/profiles/profile_helper.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_list/search/chrome_search_result.h"
+#include "chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h"
+
+namespace app_list {
+namespace {
+
+// The different categories of search result to display in launcher search.
+// Every search result type maps to one category. These values are not stable,
+// and should not be used for metrics.
+enum class Category {
+  kApp = 1,
+  kWeb = 2,
+  kFiles = 3,
+  kAssistant = 4,
+  kSettings = 5,
+  kHelp = 6,
+  kMaxValue = kHelp,
+};
+
+Category ResultTypeToCategory(ResultType result_type) {
+  switch (result_type) {
+    case ResultType::kInstalledApp:
+    case ResultType::kPlayStoreApp:
+    case ResultType::kInstantApp:
+    case ResultType::kInternalApp:
+    case ResultType::kPlayStoreReinstallApp:
+    case ResultType::kArcAppShortcut:
+      return Category::kApp;
+    case ResultType::kOmnibox:
+    case ResultType::kAnswerCard:
+      return Category::kWeb;
+    case ResultType::kZeroStateFile:
+    case ResultType::kZeroStateDrive:
+    case ResultType::kFileChip:
+    case ResultType::kDriveChip:
+    case ResultType::kFileSearch:
+    case ResultType::kDriveSearch:
+      return Category::kFiles;
+    case ResultType::kAssistantChip:
+    case ResultType::kAssistantText:
+      return Category::kAssistant;
+    case ResultType::kOsSettings:
+      return Category::kSettings;
+    case ResultType::kHelpApp:
+      return Category::kHelp;
+    // Never used in the search backend.
+    case ResultType::kUnknown:
+    // Suggested content toggle fake result type. Used only in ash, not in the
+    // search backend.
+    case ResultType::kInternalPrivacyInfo:
+    // Deprecated.
+    case ResultType::kLauncher:
+      NOTREACHED();
+      return Category::kApp;
+  }
+}
+
+std::string CategoryToString(const Category value) {
+  return base::NumberToString(static_cast<int>(value));
+}
+
+Category StringToCategory(const std::string& value) {
+  int number;
+  base::StringToInt(value, &number);
+  return static_cast<Category>(number);
+}
+
+}  // namespace
+
+CategoryRanker::CategoryRanker(Profile* profile) {
+  // Initialize category ranking as a most-frecently-used list.
+  RecurrenceRankerConfigProto config;
+  config.set_min_seconds_between_saves(1u);
+  config.set_condition_limit(1u);
+  config.set_condition_decay(0.5);
+  config.set_target_limit(20);
+  config.set_target_decay(0.8);
+  config.mutable_predictor()->mutable_default_predictor();
+
+  category_ranker_ = std::make_unique<RecurrenceRanker>(
+      "CategoryRanker", profile->GetPath().AppendASCII("category_ranker.pb"),
+      config, chromeos::ProfileHelper::IsEphemeralUserProfile(profile));
+}
+
+void CategoryRanker::InitializeCategoryScores() {
+  // Set a default ranking for categories by recording every category once. The
+  // |category_ranker_| has a small recency component to its scores, so the
+  // categories will appear in reverse order to the Record calls. This must
+  // record every category.
+  category_ranker_->Record(CategoryToString(Category::kAssistant));
+  category_ranker_->Record(CategoryToString(Category::kWeb));
+  category_ranker_->Record(CategoryToString(Category::kFiles));
+  category_ranker_->Record(CategoryToString(Category::kHelp));
+  category_ranker_->Record(CategoryToString(Category::kSettings));
+  category_ranker_->Record(CategoryToString(Category::kApp));
+
+  // Check we've recorded every category.
+  DCHECK_EQ(category_ranker_->Rank().size(),
+            static_cast<size_t>(Category::kMaxValue));
+}
+
+CategoryRanker::~CategoryRanker() {}
+
+void CategoryRanker::Start() {
+  if (!category_ranker_->is_initialized())
+    return;
+
+  // If the ranker is empty, seed it with a default ordering for each category.
+  if (category_ranker_->empty())
+    InitializeCategoryScores();
+
+  // Retrieve all category scores, sorted low-to-high.
+  const auto scores = category_ranker_->RankSorted();
+
+  // Convert the scores into ranks.
+  category_ranks_.clear();
+  for (int i = 0; i < scores.size(); ++i) {
+    const auto category = StringToCategory(scores[i].first);
+    category_ranks_[category] = i + 1;
+  }
+}
+
+void CategoryRanker::Rank(ResultsMap& results, ProviderType provider) {
+  // Update each result's score to be:
+  //  10*(category rank) + (result relevance)
+  // TODO(crbug.com/1199206): Move the number 10 into a constants.h file that
+  // describes how the space of scores is divided up.
+
+  const auto it = results.find(provider);
+  DCHECK(it != results.end());
+  for (const auto& result : it->second) {
+    const double old_relevance = result->relevance();
+    DCHECK(0.0 <= old_relevance && old_relevance <= 1);
+    const auto category = ResultTypeToCategory(result->result_type());
+    const double new_relevance = 10 * category_ranks_[category] + old_relevance;
+    result->set_relevance(new_relevance);
+  }
+}
+
+void CategoryRanker::Train(const AppLaunchData& launch) {
+  // TODO(crbug.com/1199206): Add the info we need to AppLaunchData and train
+  // |category_ranker_|.
+}
+
+}  // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/ranking/category_ranker.h b/chrome/browser/ui/app_list/search/ranking/category_ranker.h
new file mode 100644
index 0000000..0eb08b5
--- /dev/null
+++ b/chrome/browser/ui/app_list/search/ranking/category_ranker.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 CHROME_BROWSER_UI_APP_LIST_SEARCH_RANKING_CATEGORY_RANKER_H_
+#define CHROME_BROWSER_UI_APP_LIST_SEARCH_RANKING_CATEGORY_RANKER_H_
+
+#include "chrome/browser/ui/app_list/search/ranking/ranker.h"
+
+class Profile;
+
+namespace app_list {
+namespace {
+enum class Category;
+}  // namespace
+
+class RecurrenceRanker;
+
+// A ranker that groups results into categories.
+class CategoryRanker : public Ranker {
+ public:
+  explicit CategoryRanker(Profile* profile);
+  ~CategoryRanker() override;
+
+  CategoryRanker(const CategoryRanker&) = delete;
+  CategoryRanker& operator=(const CategoryRanker&) = delete;
+
+  // Ranker:
+  void Start() override;
+  void Rank(ResultsMap& results, ProviderType provider) override;
+  void Train(const AppLaunchData& launch) override;
+
+ private:
+  void InitializeCategoryScores();
+
+  std::unique_ptr<RecurrenceRanker> category_ranker_;
+
+  base::flat_map<Category, int> category_ranks_;
+};
+
+}  // namespace app_list
+
+#endif  // CHROME_BROWSER_UI_APP_LIST_SEARCH_RANKING_CATEGORY_RANKER_H_
diff --git a/chrome/browser/ui/app_list/search/ranking/ranker.h b/chrome/browser/ui/app_list/search/ranking/ranker.h
index 123124a..834f427 100644
--- a/chrome/browser/ui/app_list/search/ranking/ranker.h
+++ b/chrome/browser/ui/app_list/search/ranking/ranker.h
@@ -19,6 +19,10 @@
   Ranker(const Ranker&) = delete;
   Ranker& operator=(const Ranker&) = delete;
 
+  // Called each time a new search session begins, eg. when the user types a
+  // character.
+  virtual void Start() {}
+
   // Called each time a search provider sets new results. Passed the |provider|
   // type that triggered this call, and all |results| received so far for this
   // search session.
diff --git a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc
index 073d6e2..082896d 100644
--- a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc
+++ b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.cc
@@ -11,6 +11,11 @@
 
 RankerDelegate::~RankerDelegate() {}
 
+void RankerDelegate::Start() {
+  for (auto& ranker : rankers_)
+    ranker->Start();
+}
+
 void RankerDelegate::Rank(ResultsMap& results, ProviderType provider) {
   for (auto& ranker : rankers_)
     ranker->Rank(results, provider);
diff --git a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h
index 67cd9800..a440aa1e 100644
--- a/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h
+++ b/chrome/browser/ui/app_list/search/ranking/ranker_delegate.h
@@ -29,6 +29,7 @@
   void AddRanker(std::unique_ptr<Ranker> ranker);
 
   // Ranker:
+  void Start() override;
   void Rank(ResultsMap& results, ProviderType provider) override;
   void Train(const AppLaunchData& launch) override;
 
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc
index 5f8042b..bb7b204 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.cc
@@ -79,8 +79,7 @@
   return proto;
 }
 
-std::vector<std::pair<std::string, float>> SortAndTruncateRanks(
-    int n,
+std::vector<std::pair<std::string, float>> SortRanks(
     const std::map<std::string, float>& ranks) {
   std::vector<std::pair<std::string, float>> sorted_ranks(ranks.begin(),
                                                           ranks.end());
@@ -89,14 +88,15 @@
                const std::pair<std::string, float>& b) {
               return a.second > b.second;
             });
-
-  // vector::resize simply truncates the array if there are more than n
-  // elements. Note this is still O(N).
-  if (sorted_ranks.size() > static_cast<size_t>(n))
-    sorted_ranks.resize(n);
   return sorted_ranks;
 }
 
+void TruncateRanks(std::vector<std::pair<std::string, float>>& ranks,
+                   const int n) {
+  if (ranks.size() > static_cast<size_t>(n))
+    ranks.resize(n);
+}
+
 // Given a FrecencyStore's map from target names to IDs, and a
 // RecurrencePredictor's map of IDs to scores, returns a pair containing the
 // following:
@@ -304,13 +304,24 @@
 }
 
 std::vector<std::pair<std::string, float>> RecurrenceRanker::RankTopN(
-    int n,
+    const int n,
     const std::string& condition) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!load_from_disk_completed_)
     return {};
 
-  return SortAndTruncateRanks(n, Rank(condition));
+  auto ranks = SortRanks(Rank(condition));
+  TruncateRanks(ranks, n);
+  return ranks;
+}
+
+std::vector<std::pair<std::string, float>> RecurrenceRanker::RankSorted(
+    const std::string& condition) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!load_from_disk_completed_)
+    return {};
+
+  return SortRanks(Rank(condition));
 }
 
 std::map<std::string, FrecencyStore::ValueData>*
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h
index c38fbb9..80cb17c 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h
@@ -64,14 +64,21 @@
   std::map<std::string, float> Rank(
       const std::string& condition = std::string());
 
+  // Returns a sorted vector of at most N <target, score> pairs.
+  //  - Higher scores are better.
+  //  - Score are guaranteed to be in the range [0,1].
+  //  - Pairs are sorted in descending order of score.
+  // The user-supplied |condition| can be ignored if it isn't needed.
+  std::vector<std::pair<std::string, float>> RankTopN(
+      int n,
+      const std::string& condition = std::string());
+
   // Returns a sorted vector of <target, score> pairs.
   //  - Higher scores are better.
   //  - Score are guaranteed to be in the range [0,1].
   //  - Pairs are sorted in descending order of score.
-  //  - At most n results will be returned.
   // The user-supplied |condition| can be ignored if it isn't needed.
-  std::vector<std::pair<std::string, float>> RankTopN(
-      int n,
+  std::vector<std::pair<std::string, float>> RankSorted(
       const std::string& condition = std::string());
 
   // Returns whether this ranker contains no targets.
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc
index daa51a3b..45a38904 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker_unittest.cc
@@ -207,6 +207,19 @@
                           Pair("C", FloatEq(2.0f)), Pair("D", FloatEq(1.0f))));
 }
 
+TEST_F(RecurrenceRankerTest, RankSorted) {
+  auto ranker = MakeSimpleRanker();
+
+  const std::vector<std::string> targets = {"B", "A", "A", "B", "C",
+                                            "B", "D", "C", "A", "A"};
+  for (auto target : targets)
+    ranker->Record(target);
+
+  EXPECT_THAT(ranker->RankSorted(),
+              ElementsAre(Pair("A", FloatEq(4.0f)), Pair("B", FloatEq(3.0f)),
+                          Pair("C", FloatEq(2.0f)), Pair("D", FloatEq(1.0f))));
+}
+
 TEST_F(RecurrenceRankerTest, Empty) {
   auto ranker = MakeSimpleRanker();
 
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_constants.h b/chrome/browser/ui/ash/sharesheet/sharesheet_constants.h
index 5c229bb..1dd7318 100644
--- a/chrome/browser/ui/ash/sharesheet/sharesheet_constants.h
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_constants.h
@@ -34,7 +34,6 @@
 constexpr int kImagePreviewCornerRadius = 4;
 constexpr int kImagePreviewIconCornerRadius = 2;
 constexpr int kImagePreviewPlaceholderIconContentSize = 20;
-constexpr SkColor kImagePreviewPlaceholderIconColor = gfx::kGoogleBlue600;
 constexpr SkColor kImagePreviewPlaceholderBackgroundColor = gfx::kGoogleBlue050;
 
 constexpr int kHeaderViewBetweenChildSpacing = 12;
@@ -44,6 +43,8 @@
 constexpr int kSubtitleTextLineHeight = 22;
 constexpr int kPrimaryTextLineHeight = 20;
 
+// TODO(crbug.com/1156343) : Go through code and replace all color constants
+// with colors from ColorProvider.
 constexpr SkColor kTitleTextColor = gfx::kGoogleGrey900;
 constexpr SkColor kPrimaryTextColor = gfx::kGoogleGrey700;
 constexpr SkColor kSecondaryTextColor = gfx::kGoogleGrey600;
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc
index d9de03eb..80ce42d5 100644
--- a/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc
@@ -10,6 +10,7 @@
 
 #include "ash/public/cpp/ash_typography.h"
 #include "ash/public/cpp/file_icon_util.h"
+#include "ash/public/cpp/style/color_provider.h"
 #include "base/bind.h"
 #include "base/files/file_util.h"
 #include "base/optional.h"
@@ -51,13 +52,14 @@
   return base::ASCIIToUTF16(all_file_names);
 }
 
-gfx::ImageSkia CreatePlaceholderIcon(const gfx::VectorIcon& icon,
-                                     const gfx::Size& size) {
+gfx::ImageSkia CreateMimeTypeIcon(const gfx::VectorIcon& icon,
+                                  const gfx::Size& image_size) {
   gfx::ImageSkia file_type_icon = gfx::CreateVectorIcon(
       icon, ash::sharesheet::kImagePreviewPlaceholderIconContentSize,
-      ash::sharesheet::kImagePreviewPlaceholderIconColor);
+      ash::ColorProvider::Get()->GetContentLayerColor(
+          ash::ColorProvider::ContentLayerType::kIconColorProminent));
   return ash::HoldingSpaceImage::SuperimposeOverEmptyImage(file_type_icon,
-                                                           size);
+                                                           image_size);
 }
 
 gfx::Size GetImagePreviewSize(size_t index, int grid_icon_count) {
@@ -238,10 +240,9 @@
     if (has_files) {
       ResolveImages();
     } else {
-      // TODO(crbug.com/2650014): Update to text icon.
       DCHECK_GT(image_preview_->GetImageViewCount(), 0);
-      image_preview_->GetImageViewAt(0)->SetImage(CreatePlaceholderIcon(
-          chromeos::kFiletypeGenericIcon, kImagePreviewFullSize));
+      image_preview_->GetImageViewAt(0)->SetImage(
+          CreateMimeTypeIcon(GetTextVectorIcon(), kImagePreviewFullSize));
     }
   }
 }
@@ -324,6 +325,7 @@
     GURL drive_share_url = intent_->drive_share_url.value();
     if (drive_share_url.is_valid()) {
       text_fields.push_back(base::ASCIIToUTF16(drive_share_url.spec()));
+      text_icon_ = TextPlaceholderIcon::kLink;
     }
   }
 
@@ -346,8 +348,10 @@
     if (!extracted_text.empty())
       text_fields.push_back(base::ASCIIToUTF16(extracted_text));
 
-    if (extracted_url.is_valid())
+    if (extracted_url.is_valid()) {
       text_fields.push_back(base::ASCIIToUTF16(extracted_url.spec()));
+      text_icon_ = TextPlaceholderIcon::kLink;
+    }
   }
 
   // There will always be at least 1 text field.
@@ -355,6 +359,15 @@
   return text_fields;
 }
 
+const gfx::VectorIcon& SharesheetHeaderView::GetTextVectorIcon() {
+  switch (text_icon_) {
+    case (TextPlaceholderIcon::kGenericText):
+      return kSharesheetTextIcon;
+    case (TextPlaceholderIcon::kLink):
+      return kSharesheetLinkIcon;
+  }
+}
+
 void SharesheetHeaderView::ResolveImages() {
   for (int i = 0; i < image_preview_->GetImageViewCount(); ++i) {
     ResolveImage(i);
@@ -376,7 +389,7 @@
       base::BindRepeating(&SharesheetHeaderView::LoadImage,
                           weak_ptr_factory_.GetWeakPtr()),
       base::Optional<gfx::ImageSkia>(
-          CreatePlaceholderIcon(chromeos::kFiletypeImageIcon, size)));
+          CreateMimeTypeIcon(chromeos::kFiletypeImageIcon, size)));
   DCHECK_GT(image_preview_->GetImageViewCount(), index);
   image_preview_->GetImageViewAt(index)->SetImage(image->GetImageSkia(size));
   image_subscription_.push_back(image->AddImageSkiaChangedCallback(
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.h b/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.h
index 5ddc6f2d..376b205e 100644
--- a/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.h
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.h
@@ -13,6 +13,7 @@
 #include "chrome/browser/ui/ash/thumbnail_loader.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "ui/base/metadata/metadata_header_macros.h"
+#include "ui/gfx/vector_icon_types.h"
 #include "ui/views/view.h"
 
 class Profile;
@@ -36,6 +37,11 @@
  private:
   class SharesheetImagePreview;
 
+  enum class TextPlaceholderIcon {
+    kGenericText = 0,
+    kLink,
+  };
+
   // Adds the view for text preview.
   void ShowTextPreview();
 
@@ -49,6 +55,7 @@
   // TODO(crbug.com/2650014): Move the existing ExtractSharedFields function
   // from share_target_utils.h to a common place and reuse the function here.
   std::vector<std::u16string> ExtractShareText();
+  const gfx::VectorIcon& GetTextVectorIcon();
 
   void ResolveImages();
   void ResolveImage(size_t index);
@@ -60,6 +67,9 @@
   // Contains the share title and text preview views.
   views::View* text_view_ = nullptr;
   SharesheetImagePreview* image_preview_;
+  // |text_icon_| is only used when we have no icons to show in the image
+  // preview.
+  TextPlaceholderIcon text_icon_ = TextPlaceholderIcon::kGenericText;
 
   Profile* profile_;
   apps::mojom::IntentPtr intent_;
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.cc
index 2abc72c..c50455d 100644
--- a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.cc
+++ b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.cc
@@ -171,7 +171,9 @@
 void AppServiceAppWindowArcTracker::OnTaskDescriptionChanged(
     int32_t task_id,
     const std::string& label,
-    const arc::mojom::RawIconPngData& icon) {
+    const arc::mojom::RawIconPngData& icon,
+    uint32_t primary_color,
+    uint32_t status_bar_color) {
   auto it = task_id_to_arc_app_window_info_.find(task_id);
   if (it == task_id_to_arc_app_window_info_.end())
     return;
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.h b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.h
index d7566fa5..9f082b00 100644
--- a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.h
+++ b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.h
@@ -71,10 +71,11 @@
                      const std::string& activity,
                      const std::string& intent,
                      int32_t session_id) override;
-  void OnTaskDescriptionChanged(
-      int32_t task_id,
-      const std::string& label,
-      const arc::mojom::RawIconPngData& icon) override;
+  void OnTaskDescriptionChanged(int32_t task_id,
+                                const std::string& label,
+                                const arc::mojom::RawIconPngData& icon,
+                                uint32_t primary_color,
+                                uint32_t status_bar_color) override;
   void OnTaskDestroyed(int32_t task_id) override;
   void OnTaskSetActive(int32_t task_id) override;
 
diff --git a/chrome/browser/ui/ash/shelf/arc_app_shelf_browsertest.cc b/chrome/browser/ui/ash/shelf/arc_app_shelf_browsertest.cc
index 6bb3f6a8..801c0f2 100644
--- a/chrome/browser/ui/ash/shelf/arc_app_shelf_browsertest.cc
+++ b/chrome/browser/ui/ash/shelf/arc_app_shelf_browsertest.cc
@@ -722,7 +722,8 @@
   app_host()->OnTaskDescriptionChanged(
       1, kTestWindowTitles[1],
       arc_instance()->GenerateIconResponse(kGeneratedIconSize,
-                                           false /* app_icon */));
+                                           false /* app_icon */),
+      0, 0);
   WaitForDecompressTask();
   ash::ShelfItemDelegate* delegate1 = GetShelfItemDelegate(shelf_id1);
 
@@ -737,7 +738,8 @@
   app_host()->OnTaskDescriptionChanged(
       2, kTestWindowTitles[2],
       arc_instance()->GenerateIconResponse(kGeneratedIconSize,
-                                           false /* app_icon */));
+                                           false /* app_icon */),
+      0, 0);
 
   WaitForDecompressTask();
   ASSERT_EQ(delegate1, GetShelfItemDelegate(shelf_id1));
@@ -754,7 +756,8 @@
     app_host()->OnTaskDescriptionChanged(
         task_id, kTestWindowTitles[task_id],
         arc_instance()->GenerateIconResponse(kGeneratedIconSize,
-                                             false /* app_icon */));
+                                             false /* app_icon */),
+        0, 0);
   }
 
   WaitForDecompressTask();
@@ -771,7 +774,8 @@
   app_host()->OnTaskDescriptionChanged(
       6, kTestWindowTitles[6],
       arc_instance()->GenerateIconResponse(kGeneratedIconSize,
-                                           false /* app_icon */));
+                                           false /* app_icon */),
+      0, 0);
   ash::ShelfItemDelegate* delegate2 = GetShelfItemDelegate(shelf_id2);
 
   WaitForDecompressTask();
@@ -787,7 +791,8 @@
   app_host()->OnTaskDescriptionChanged(
       7, kTestWindowTitles[7],
       arc_instance()->GenerateIconResponse(kGeneratedIconSize,
-                                           false /* app_icon */));
+                                           false /* app_icon */),
+      0, 0);
 
   WaitForDecompressTask();
   ASSERT_EQ(delegate2, GetShelfItemDelegate(shelf_id2));
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
index 9c89e26..535b907 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
@@ -139,7 +139,7 @@
              const content::NativeWebKeyboardEvent& event) {
             return weak_this && weak_this->HandleKeyPressEvent(event);
           },
-          GetWeakPtr()));
+          weak_this));
 
   delegate_->OnPopupShown();
 }
diff --git a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
index a464e077..edd788e 100644
--- a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
+++ b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h"
 
 #include "build/build_config.h"
+#include "chrome/browser/content_settings/chrome_content_settings_utils.h"
 #include "chrome/browser/permissions/permission_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
@@ -19,23 +20,6 @@
                                                    const GURL& site_url)
     : profile_(profile), site_url_(site_url) {}
 
-permissions::PermissionResult ChromePageInfoUiDelegate::GetPermissionStatus(
-    ContentSettingsType type) {
-  return PermissionManagerFactory::GetForProfile(profile_)->GetPermissionStatus(
-      type, site_url_, site_url_);
-}
-
-#if !defined(OS_ANDROID)
-
-bool ChromePageInfoUiDelegate::IsBlockAutoPlayEnabled() {
-  return profile_->GetPrefs()->GetBoolean(prefs::kBlockAutoplayEnabled);
-}
-
-bool ChromePageInfoUiDelegate::ShouldShowSiteSettings() {
-  return !profile_->IsGuestSession();
-}
-#endif
-
 bool ChromePageInfoUiDelegate::ShouldShowAllow(ContentSettingsType type) {
   switch (type) {
     // Notifications and idle detection do not support CONTENT_SETTING_ALLOW in
@@ -75,3 +59,24 @@
       return false;
   }
 }
+
+#if !defined(OS_ANDROID)
+bool ChromePageInfoUiDelegate::ShouldShowSiteSettings() {
+  return !profile_->IsGuestSession();
+}
+
+std::u16string ChromePageInfoUiDelegate::GetPermissionDetail(
+    ContentSettingsType type) {
+  return content_settings::GetPermissionDetailString(profile_, type, site_url_);
+}
+
+bool ChromePageInfoUiDelegate::IsBlockAutoPlayEnabled() {
+  return profile_->GetPrefs()->GetBoolean(prefs::kBlockAutoplayEnabled);
+}
+#endif
+
+permissions::PermissionResult ChromePageInfoUiDelegate::GetPermissionStatus(
+    ContentSettingsType type) {
+  return PermissionManagerFactory::GetForProfile(profile_)->GetPermissionStatus(
+      type, site_url_, site_url_);
+}
diff --git a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h
index c03301c..c0f9bea 100644
--- a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h
+++ b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h
@@ -5,8 +5,11 @@
 #ifndef CHROME_BROWSER_UI_PAGE_INFO_CHROME_PAGE_INFO_UI_DELEGATE_H_
 #define CHROME_BROWSER_UI_PAGE_INFO_CHROME_PAGE_INFO_UI_DELEGATE_H_
 
+#include <string>
+
 #include "build/build_config.h"
 #include "components/page_info/page_info_ui_delegate.h"
+#include "url/gurl.h"
 
 class Profile;
 
@@ -15,15 +18,27 @@
   ChromePageInfoUiDelegate(Profile* profile, const GURL& site_url);
   ~ChromePageInfoUiDelegate() override = default;
 
-  // PageInfoUiDelegate implementation
+  // Whether the combobox option for allowing a permission should be shown for
+  // `type`.
+  bool ShouldShowAllow(ContentSettingsType type);
+
+  // Whether the combobox option to ask a permission should be shown for `type`.
+  bool ShouldShowAsk(ContentSettingsType type);
+
 #if !defined(OS_ANDROID)
+  // Whether to show a link that takes the user to the chrome://settings subpage
+  // for `site_url_`.
+  bool ShouldShowSiteSettings();
+
+  // The returned string, if non-empty, should be added as a sublabel that gives
+  // extra details to the user concerning the granted permission.
+  std::u16string GetPermissionDetail(ContentSettingsType type);
+
+  // PageInfoUiDelegate implementation
   bool IsBlockAutoPlayEnabled() override;
-  bool ShouldShowSiteSettings() override;
-#endif
+#endif  // !defined(OS_ANDROID)
   permissions::PermissionResult GetPermissionStatus(
       ContentSettingsType type) override;
-  bool ShouldShowAllow(ContentSettingsType type) override;
-  bool ShouldShowAsk(ContentSettingsType type) override;
 
  private:
   Profile* profile_;
diff --git a/chrome/browser/ui/page_info/permission_menu_model.cc b/chrome/browser/ui/page_info/permission_menu_model.cc
index 8332cbb..87285cd 100644
--- a/chrome/browser/ui/page_info/permission_menu_model.cc
+++ b/chrome/browser/ui/page_info/permission_menu_model.cc
@@ -36,7 +36,7 @@
 }
 }  // namespace
 
-PermissionMenuModel::PermissionMenuModel(PageInfoUiDelegate* delegate,
+PermissionMenuModel::PermissionMenuModel(ChromePageInfoUiDelegate* delegate,
                                          const PageInfo::PermissionInfo& info,
                                          ChangeCallback callback)
     : ui::SimpleMenuModel(this),
diff --git a/chrome/browser/ui/page_info/permission_menu_model.h b/chrome/browser/ui/page_info/permission_menu_model.h
index 172d9bc..2f075d7 100644
--- a/chrome/browser/ui/page_info/permission_menu_model.h
+++ b/chrome/browser/ui/page_info/permission_menu_model.h
@@ -12,6 +12,8 @@
 #include "ui/base/models/simple_menu_model.h"
 #include "url/gurl.h"
 
+class ChromePageInfoUiDelegate;
+
 class PermissionMenuModel : public ui::SimpleMenuModel,
                             public ui::SimpleMenuModel::Delegate {
  public:
@@ -19,7 +21,7 @@
       ChangeCallback;
 
   // Create a new menu model for permission settings.
-  PermissionMenuModel(PageInfoUiDelegate* delegate,
+  PermissionMenuModel(ChromePageInfoUiDelegate* delegate,
                       const PageInfo::PermissionInfo& info,
                       ChangeCallback callback);
   ~PermissionMenuModel() override;
diff --git a/chrome/browser/ui/page_info/permission_menu_model_unittest.cc b/chrome/browser/ui/page_info/permission_menu_model_unittest.cc
index c105df2..b9769cc 100644
--- a/chrome/browser/ui/page_info/permission_menu_model_unittest.cc
+++ b/chrome/browser/ui/page_info/permission_menu_model_unittest.cc
@@ -34,7 +34,7 @@
 
  protected:
   TestingProfile* profile() { return &profile_; }
-  PageInfoUiDelegate* delegate() { return delegate_.get(); }
+  ChromePageInfoUiDelegate* delegate() { return delegate_.get(); }
 
   void SetOffTheRecordProfile() {
     delegate_ = std::make_unique<ChromePageInfoUiDelegate>(
@@ -50,7 +50,7 @@
  private:
   content::BrowserTaskEnvironment task_environment_;
   TestingProfile profile_;
-  std::unique_ptr<PageInfoUiDelegate> delegate_;
+  std::unique_ptr<ChromePageInfoUiDelegate> delegate_;
 };
 
 }  // namespace
diff --git a/chrome/browser/ui/views/autofill/save_address_profile_view.cc b/chrome/browser/ui/views/autofill/save_address_profile_view.cc
index 4d5f5cfa..164d646 100644
--- a/chrome/browser/ui/views/autofill/save_address_profile_view.cc
+++ b/chrome/browser/ui/views/autofill/save_address_profile_view.cc
@@ -38,6 +38,15 @@
                                      views::style::STYLE_PRIMARY);
 }
 
+// Maps an AddressField to a ServerFieldType making sure
+// NAME_FULL_WITH_HONORIFIC_PREFIX is returned instead of NAME_FULL for
+// RECIPIENT type.
+ServerFieldType AddressFieldToServerFieldTypeWithHonorificPrefix(
+    ::i18n::addressinput::AddressField address_field) {
+  ServerFieldType type = autofill::AddressFieldToServerFieldType(address_field);
+  return type == NAME_FULL ? NAME_FULL_WITH_HONORIFIC_PREFIX : type;
+}
+
 int ComboboxIconSize() {
   // Use the line height of the body small text. This allows the icons to adapt
   // if the user changes the font size.
@@ -132,7 +141,8 @@
       std::u16string field_value =
           component.literal.empty()
               ? profile.GetInfo(
-                    autofill::AddressFieldToServerFieldType(component.field),
+                    AddressFieldToServerFieldTypeWithHonorificPrefix(
+                        component.field),
                     locale)
               : base::UTF8ToUTF16(component.literal);
       if (!field_value.empty())
diff --git a/chrome/browser/ui/views/autofill/update_address_profile_view.cc b/chrome/browser/ui/views/autofill/update_address_profile_view.cc
index 8b5761e..f5319dd 100644
--- a/chrome/browser/ui/views/autofill/update_address_profile_view.cc
+++ b/chrome/browser/ui/views/autofill/update_address_profile_view.cc
@@ -39,8 +39,7 @@
 const gfx::VectorIcon& GetVectorIconForType(ServerFieldType type) {
   // TODO(crbug.com/1167060): Update icons upon having final mocks.
   switch (type) {
-    case NAME_FULL:
-    case NAME_HONORIFIC_PREFIX:
+    case NAME_FULL_WITH_HONORIFIC_PREFIX:
       return kUserAccountAvatarIcon;
     case EMAIL_ADDRESS:
       return vector_icons::kEmailIcon;
@@ -210,11 +209,12 @@
       AddChildView(std::make_unique<views::View>());
 
   base::flat_map<ServerFieldType, std::pair<std::u16string, std::u16string>>
-      profile_diff_map =
-          AutofillProfileComparator::GetSettingsVisibleProfileDifferenceMap(
-              controller_->GetProfileToSave(),
-              *controller_->GetOriginalProfile(),
-              g_browser_process->GetApplicationLocale());
+      profile_diff_map = AutofillProfileComparator::GetProfileDifferenceMap(
+          controller_->GetProfileToSave(), *controller_->GetOriginalProfile(),
+          autofill::ServerFieldTypeSet(
+              std::begin(kVisibleTypesForProfileDifferences),
+              std::end(kVisibleTypesForProfileDifferences)),
+          g_browser_process->GetApplicationLocale());
 
   bool has_non_empty_original_values =
       HasNonEmptySecondValues(profile_diff_map);
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.h b/chrome/browser/ui/views/page_info/page_info_bubble_view.h
index e3992f6..22f36ef 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view.h
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.h
@@ -30,6 +30,7 @@
 #include "ui/views/controls/styled_label.h"
 #include "ui/views/widget/widget.h"
 
+class ChromePageInfoUiDelegate;
 class GURL;
 class Profile;
 
@@ -169,7 +170,7 @@
   SecurityInformationView* header_ = nullptr;
 
   // The raw details of the status of the identity check for this site.
-  std::u16string details_text_ = std::u16string();
+  std::u16string details_text_;
 
   // The view that contains the certificate, cookie, and permissions sections.
   views::View* site_settings_view_ = nullptr;
@@ -203,7 +204,7 @@
   PageInfoUI::SecurityDescriptionType security_description_type_ =
       PageInfoUI::SecurityDescriptionType::CONNECTION;
 
-  std::unique_ptr<PageInfoUiDelegate> ui_delegate_;
+  std::unique_ptr<ChromePageInfoUiDelegate> ui_delegate_;
 
   base::WeakPtrFactory<PageInfoBubbleView> weak_factory_{this};
 };
diff --git a/chrome/browser/ui/views/page_info/page_info_main_view.cc b/chrome/browser/ui/views/page_info/page_info_main_view.cc
index 71aee253..4acea69 100644
--- a/chrome/browser/ui/views/page_info/page_info_main_view.cc
+++ b/chrome/browser/ui/views/page_info/page_info_main_view.cc
@@ -7,6 +7,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/browser/reputation/safety_tip_ui_helper.h"
+#include "chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
@@ -16,7 +17,6 @@
 #include "chrome/browser/ui/views/page_info/page_info_security_content_view.h"
 #include "chrome/browser/vr/vr_tab_helper.h"
 #include "chrome/common/url_constants.h"
-#include "components/page_info/page_info_ui_delegate.h"
 #include "components/strings/grit/components_chromium_strings.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -58,7 +58,7 @@
 
 PageInfoMainView::PageInfoMainView(
     PageInfo* presenter,
-    PageInfoUiDelegate* ui_delegate,
+    ChromePageInfoUiDelegate* ui_delegate,
     PageInfoNavigationHandler* navigation_handler)
     : presenter_(presenter),
       ui_delegate_(ui_delegate),
diff --git a/chrome/browser/ui/views/page_info/page_info_main_view.h b/chrome/browser/ui/views/page_info/page_info_main_view.h
index e3ea046..2fd3201 100644
--- a/chrome/browser/ui/views/page_info/page_info_main_view.h
+++ b/chrome/browser/ui/views/page_info/page_info_main_view.h
@@ -15,6 +15,7 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "ui/views/view.h"
 
+class ChromePageInfoUiDelegate;
 class PageInfoSecurityContentView;
 class PageInfoNavigationHandler;
 
@@ -30,7 +31,7 @@
   static constexpr int kIconColumnWidth = 16;
 
   PageInfoMainView(PageInfo* presenter,
-                   PageInfoUiDelegate* ui_delegate,
+                   ChromePageInfoUiDelegate* ui_delegate,
                    PageInfoNavigationHandler* navigation_handler);
   ~PageInfoMainView() override;
 
@@ -91,7 +92,7 @@
 
   PageInfo* presenter_;
 
-  PageInfoUiDelegate* ui_delegate_;
+  ChromePageInfoUiDelegate* ui_delegate_;
 
   PageInfoNavigationHandler* navigation_handler_;
 
diff --git a/chrome/browser/ui/views/page_info/page_info_new_bubble_view.h b/chrome/browser/ui/views/page_info/page_info_new_bubble_view.h
index c81f993..7be3da9 100644
--- a/chrome/browser/ui/views/page_info/page_info_new_bubble_view.h
+++ b/chrome/browser/ui/views/page_info/page_info_new_bubble_view.h
@@ -9,6 +9,7 @@
 #include "chrome/browser/ui/views/page_info/page_info_bubble_view_base.h"
 #include "chrome/browser/ui/views/page_info/page_info_navigation_handler.h"
 
+class ChromePageInfoUiDelegate;
 class PageSwitcherView;
 class PageInfoViewFactory;
 
@@ -47,7 +48,7 @@
 
   PageInfoClosingCallback closing_callback_;
 
-  std::unique_ptr<PageInfoUiDelegate> ui_delegate_;
+  std::unique_ptr<ChromePageInfoUiDelegate> ui_delegate_;
 
   std::unique_ptr<PageInfoViewFactory> view_factory_;
 
diff --git a/chrome/browser/ui/views/page_info/page_info_view_factory.cc b/chrome/browser/ui/views/page_info/page_info_view_factory.cc
index e621faf9..bbcacba 100644
--- a/chrome/browser/ui/views/page_info/page_info_view_factory.cc
+++ b/chrome/browser/ui/views/page_info/page_info_view_factory.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
 
+#include "chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/page_info/page_info_main_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_navigation_handler.h"
@@ -55,7 +56,7 @@
 
 PageInfoViewFactory::PageInfoViewFactory(
     PageInfo* presenter,
-    PageInfoUiDelegate* ui_delegate,
+    ChromePageInfoUiDelegate* ui_delegate,
     PageInfoNavigationHandler* navigation_handler)
     : presenter_(presenter),
       ui_delegate_(ui_delegate),
diff --git a/chrome/browser/ui/views/page_info/page_info_view_factory.h b/chrome/browser/ui/views/page_info/page_info_view_factory.h
index 2143b9c..b05462f 100644
--- a/chrome/browser/ui/views/page_info/page_info_view_factory.h
+++ b/chrome/browser/ui/views/page_info/page_info_view_factory.h
@@ -7,15 +7,15 @@
 
 #include "ui/views/view.h"
 
+class ChromePageInfoUiDelegate;
 class PageInfo;
-class PageInfoUiDelegate;
 class PageInfoNavigationHandler;
 
 // A factory class that creates pages and individual views for page info.
 class PageInfoViewFactory {
  public:
   PageInfoViewFactory(PageInfo* presenter,
-                      PageInfoUiDelegate* ui_delegate,
+                      ChromePageInfoUiDelegate* ui_delegate,
                       PageInfoNavigationHandler* navigation_handler);
 
   // Creates a separator view with padding on top and bottom. Use with flex
@@ -48,7 +48,7 @@
       WARN_UNUSED_RESULT;
 
   PageInfo* presenter_;
-  PageInfoUiDelegate* ui_delegate_;
+  ChromePageInfoUiDelegate* ui_delegate_;
   PageInfoNavigationHandler* navigation_handler_;
 };
 
diff --git a/chrome/browser/ui/views/page_info/permission_selector_row.cc b/chrome/browser/ui/views/page_info/permission_selector_row.cc
index 58b78754..26fd12b 100644
--- a/chrome/browser/ui/views/page_info/permission_selector_row.cc
+++ b/chrome/browser/ui/views/page_info/permission_selector_row.cc
@@ -157,7 +157,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 PermissionSelectorRow::PermissionSelectorRow(
-    PageInfoUiDelegate* delegate,
+    ChromePageInfoUiDelegate* delegate,
     const PageInfo::PermissionInfo& permission,
     views::GridLayout* layout) {
   const int list_item_padding = ChromeLayoutProvider::Get()->GetDistanceMetric(
@@ -182,43 +182,20 @@
   // Create the permission combobox.
   InitializeComboboxView(layout, permission);
 
+  // Add extra details as sublabel.
+  std::u16string detail = delegate->GetPermissionDetail(permission.type);
+  if (!detail.empty())
+    AddSecondaryLabelRow(layout, detail);
+
   // Show the permission decision reason, if it was not the user.
   std::u16string reason =
       PageInfoUI::PermissionDecisionReasonToUIString(delegate, permission);
-  if (!reason.empty()) {
-    layout->StartRow(1.0, PageInfoBubbleView::kPermissionColumnSetId);
-    layout->SkipColumns(1);
-    auto secondary_label = std::make_unique<views::Label>(reason);
-    secondary_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-    secondary_label->SetEnabledColor(PageInfoUI::GetSecondaryTextColor());
-    // The |secondary_label| should wrap when it's too long instead of
-    // stretching its parent view horizontally, but also ensure long strings
-    // aren't wrapped too early.
-    int preferred_width = secondary_label->GetPreferredSize().width();
-    secondary_label->SetMultiLine(true);
+  if (!reason.empty())
+    AddSecondaryLabelRow(layout, reason);
 
-    views::ColumnSet* column_set =
-        layout->GetColumnSet(PageInfoBubbleView::kPermissionColumnSetId);
-    DCHECK(column_set);
-    // Secondary labels in Harmony may not overlap into space shared with the
-    // combobox column.
-    const int column_span = 1;
-
-    // Long labels that cannot fit in the existing space under the permission
-    // label should be allowed to use up to |kMaxSecondaryLabelWidth| for
-    // display.
-    constexpr int kMaxSecondaryLabelWidth = 140;
-    if (preferred_width > kMaxSecondaryLabelWidth) {
-      layout->AddView(std::move(secondary_label), column_span, 1.0,
-                      views::GridLayout::LEADING, views::GridLayout::CENTER,
-                      kMaxSecondaryLabelWidth, 0);
-    } else {
-      layout->AddView(std::move(secondary_label), column_span, 1.0,
-                      views::GridLayout::FILL, views::GridLayout::CENTER);
-    }
-  }
-  layout->AddPaddingRow(views::GridLayout::kFixedSize,
-                        CalculatePaddingBeneathPermissionRow(!reason.empty()));
+  layout->AddPaddingRow(
+      views::GridLayout::kFixedSize,
+      CalculatePaddingBeneathPermissionRow(!detail.empty() || !reason.empty()));
 }
 
 PermissionSelectorRow::~PermissionSelectorRow() {
@@ -232,6 +209,40 @@
   delete combobox_;
 }
 
+void PermissionSelectorRow::AddSecondaryLabelRow(views::GridLayout* layout,
+                                                 const std::u16string& text) {
+  layout->StartRow(1.0, PageInfoBubbleView::kPermissionColumnSetId);
+  layout->SkipColumns(1);
+  auto sublabel = std::make_unique<views::Label>(text);
+  sublabel->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  sublabel->SetEnabledColor(PageInfoUI::GetSecondaryTextColor());
+  // The |sublabel| should wrap when it's too long instead of
+  // stretching its parent view horizontally, but also ensure long strings
+  // aren't wrapped too early.
+  int preferred_width = sublabel->GetPreferredSize().width();
+  sublabel->SetMultiLine(true);
+
+  views::ColumnSet* column_set =
+      layout->GetColumnSet(PageInfoBubbleView::kPermissionColumnSetId);
+  DCHECK(column_set);
+  // Secondary labels in Harmony may not overlap into space shared with the
+  // combobox column.
+  const int column_span = 1;
+
+  // Long labels that cannot fit in the existing space under the permission
+  // label should be allowed to use up to |kMaxSecondaryLabelWidth| for
+  // display.
+  constexpr int kMaxSecondaryLabelWidth = 140;
+  if (preferred_width > kMaxSecondaryLabelWidth) {
+    layout->AddView(std::move(sublabel), column_span, 1.0,
+                    views::GridLayout::LEADING, views::GridLayout::CENTER,
+                    kMaxSecondaryLabelWidth, 0);
+  } else {
+    layout->AddView(std::move(sublabel), column_span, 1.0,
+                    views::GridLayout::FILL, views::GridLayout::CENTER);
+  }
+}
+
 int PermissionSelectorRow::CalculatePaddingBeneathPermissionRow(
     bool has_reason) {
   const int list_item_padding = ChromeLayoutProvider::Get()->GetDistanceMetric(
diff --git a/chrome/browser/ui/views/page_info/permission_selector_row.h b/chrome/browser/ui/views/page_info/permission_selector_row.h
index 8525aa4c..d318b8b 100644
--- a/chrome/browser/ui/views/page_info/permission_selector_row.h
+++ b/chrome/browser/ui/views/page_info/permission_selector_row.h
@@ -41,22 +41,16 @@
 class PermissionSelectorRow {
  public:
   // The |PermissionSelectorRow|'s constituent views are added to |layout|.
-  PermissionSelectorRow(PageInfoUiDelegate* delegate,
+  PermissionSelectorRow(ChromePageInfoUiDelegate* delegate,
                         const PageInfo::PermissionInfo& permission,
                         views::GridLayout* layout);
   virtual ~PermissionSelectorRow();
 
-  // Calculates the amount of padding to add beneath a |PermissionSelectorRow|
-  // depending on whether it has an accompanying permission decision reason.
-  int CalculatePaddingBeneathPermissionRow(bool has_reason);
-
   // Retrieve the minimum height a |PermissionSelectorRow| can be.
   int MinHeightForPermissionRow();
 
   void AddObserver(PermissionSelectorRowObserver* observer);
 
-  void PermissionChanged(const PageInfo::PermissionInfo& permission);
-
   // Returns the preferred width for the currently selected combobox option
   // (unchanged by any minimum width set using SetMinComboboxWidth()).
   int GetComboboxWidth() const;
@@ -67,6 +61,16 @@
  private:
   friend class test::PageInfoBubbleViewTestApi;
 
+  // Adds a row showing `text` in `layout`.
+  void AddSecondaryLabelRow(views::GridLayout* layout,
+                            const std::u16string& text);
+
+  // Calculates the amount of padding to add beneath a |PermissionSelectorRow|
+  // depending on whether it has an accompanying permission decision reason.
+  int CalculatePaddingBeneathPermissionRow(bool has_reason);
+
+  void PermissionChanged(const PageInfo::PermissionInfo& permission);
+
   void InitializeComboboxView(views::GridLayout* layout,
                               const PageInfo::PermissionInfo& permission);
 
diff --git a/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.h b/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.h
index 3e02443..d6616f8 100644
--- a/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.h
+++ b/chrome/browser/ui/web_applications/test/web_app_navigation_browsertest.h
@@ -114,7 +114,7 @@
   bool TestTabActionDoesNotOpenAppWindow(const GURL& target_url,
                                          base::OnceClosure action);
 
-  const net::EmbeddedTestServer& https_server() { return https_server_; }
+  net::EmbeddedTestServer& https_server() { return https_server_; }
 
   const AppId& test_web_app_id() const { return test_web_app_; }
 
diff --git a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
index 9664b2a..cef7bc527 100644
--- a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
@@ -47,7 +47,9 @@
 
   void SetUpOnMainThread() override {
     WebAppNavigationBrowserTest::SetUpOnMainThread();
+    ASSERT_TRUE(https_server().Start());
     ASSERT_TRUE(embedded_test_server()->Start());
+    out_of_scope_ = https_server().GetURL("/");
   }
 
   void InstallTestApp(const char* path, bool await_metric) {
@@ -92,9 +94,11 @@
     observer.Wait();
   }
 
-  void Navigate(Browser* browser, const GURL& url) {
+  void Navigate(Browser* browser,
+                const GURL& url,
+                LinkTarget link_target = LinkTarget::SELF) {
     ClickLinkAndWait(browser->tab_strip_model()->GetActiveWebContents(), url,
-                     LinkTarget::SELF, "");
+                     link_target, "");
   }
 
   Browser* GetNewBrowserFromNavigation(Browser* browser, const GURL& url) {
@@ -144,9 +148,9 @@
   GURL in_scope_1_;
   GURL in_scope_2_;
   GURL scope_;
+  GURL out_of_scope_;
 
   const GURL about_blank_{"about:blank"};
-  const GURL out_of_scope_{"https://other-domain.org/"};
 
   ScopedOsHooksSuppress os_hooks_supress_;
 };
@@ -429,11 +433,16 @@
   ExpectTabs(browser(), {out_of_scope_});
   ExpectTabs(app_browser, {in_scope_2_});
 
-  // In scope navigation should navigate the existing app window.
-  Navigate(browser(), in_scope_1_);
-  EXPECT_EQ(app_browser, BrowserList::GetInstance()->GetLastActive());
-  ExpectTabs(browser(), {out_of_scope_});
-  ExpectTabs(app_browser, {in_scope_1_});
+  // target=_blank in scope navigation should navigate the existing app window.
+  Navigate(browser(), in_scope_1_, LinkTarget::BLANK);
+  // TODO(crbug.com/1209082): The app window should now be focused.
+  // EXPECT_EQ(app_browser, BrowserList::GetInstance()->GetLastActive());
+  // TODO(crbug.com/1209096): With IntentPickerPWAPersistence we don't close the
+  // new about:blank tab after capturing.
+  if (!IsIntentPickerPersistenceEnabled()) {
+    ExpectTabs(browser(), {out_of_scope_});
+    ExpectTabs(app_browser, {in_scope_1_});
+  }
 }
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.h
index 62609f7..90e682a 100644
--- a/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.h
@@ -9,9 +9,11 @@
 
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 
-namespace chromeos {
-
+namespace ash {
 class ActiveDirectoryLoginScreen;
+}
+
+namespace chromeos {
 
 // Interface for dependency injection between ActiveDirectoryLoginScreen and its
 // WebUI representation.
@@ -25,7 +27,7 @@
   virtual void Show() = 0;
 
   // Binds `screen` to the view.
-  virtual void Bind(ActiveDirectoryLoginScreen* screen) = 0;
+  virtual void Bind(ash::ActiveDirectoryLoginScreen* screen) = 0;
 
   // Unbinds the screen from the view.
   virtual void Unbind() = 0;
@@ -58,7 +60,7 @@
 
   // ActiveDirectoryLoginView:
   void Show() override;
-  void Bind(ActiveDirectoryLoginScreen* screen) override;
+  void Bind(ash::ActiveDirectoryLoginScreen* screen) override;
   void Unbind() override;
   void Reset() override;
   void SetErrorState(const std::string& username, int errorState) override;
@@ -69,7 +71,7 @@
       ::login::LocalizedValuesBuilder* builder) override;
   void Initialize() override;
 
-  ActiveDirectoryLoginScreen* screen_ = nullptr;
+  ash::ActiveDirectoryLoginScreen* screen_ = nullptr;
 
   // Whether the screen should be shown right after initialization.
   bool show_on_init_ = false;
@@ -77,4 +79,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::ActiveDirectoryLoginView;
+}
+
 #endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_ACTIVE_DIRECTORY_LOGIN_SCREEN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.cc
index 9743c6d..5f9d9dc 100644
--- a/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h"
 
+#include "chrome/browser/ash/login/screens/active_directory_password_change_screen.h"
 #include "chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/login/localized_values_builder.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h
index b807db35..8a978fee 100644
--- a/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h
@@ -8,12 +8,13 @@
 #include <string>
 
 #include "base/macros.h"
-#include "chrome/browser/ash/login/screens/active_directory_password_change_screen.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 
-namespace chromeos {
-
+namespace ash {
 class ActiveDirectoryPasswordChangeScreen;
+}
+
+namespace chromeos {
 
 // Interface for dependency injection between
 // ActiveDirectoryPasswordChangeScreen and its WebUI representation.
@@ -27,7 +28,7 @@
   virtual void Show(const std::string& username, int error) = 0;
 
   // Binds `screen` to the view.
-  virtual void Bind(ActiveDirectoryPasswordChangeScreen* screen) = 0;
+  virtual void Bind(ash::ActiveDirectoryPasswordChangeScreen* screen) = 0;
 
   // Unbinds the screen from the view.
   virtual void Unbind() = 0;
@@ -57,7 +58,7 @@
 
   // ActiveDirectoryPasswordChangeView:
   void Show(const std::string& username, int error) override;
-  void Bind(ActiveDirectoryPasswordChangeScreen* screen) override;
+  void Bind(ash::ActiveDirectoryPasswordChangeScreen* screen) override;
   void Unbind() override;
   void ShowSignInError(const std::string& error_text) override;
 
@@ -66,11 +67,17 @@
   void HandleComplete(const std::string& old_password,
                       const std::string& new_password);
 
-  ActiveDirectoryPasswordChangeScreen* screen_ = nullptr;
+  ash::ActiveDirectoryPasswordChangeScreen* screen_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(ActiveDirectoryPasswordChangeScreenHandler);
 };
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::ActiveDirectoryPasswordChangeView;
+}
+
 #endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_ACTIVE_DIRECTORY_PASSWORD_CHANGE_SCREEN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/app_downloading_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/app_downloading_screen_handler.h
index 71d5798..26d0c75 100644
--- a/chrome/browser/ui/webui/chromeos/login/app_downloading_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/app_downloading_screen_handler.h
@@ -8,9 +8,11 @@
 #include "base/macros.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 
-namespace chromeos {
-
+namespace ash {
 class AppDownloadingScreen;
+}
+
+namespace chromeos {
 
 class AppDownloadingScreenView {
  public:
@@ -19,7 +21,7 @@
   virtual ~AppDownloadingScreenView() = default;
 
   // Sets screen this view belongs to.
-  virtual void Bind(AppDownloadingScreen* screen) = 0;
+  virtual void Bind(ash::AppDownloadingScreen* screen) = 0;
 
   // Shows the contents of the screen.
   virtual void Show() = 0;
@@ -43,7 +45,7 @@
   void RegisterMessages() override;
 
   // AppDownloadingScreenView:
-  void Bind(AppDownloadingScreen* screen) override;
+  void Bind(ash::AppDownloadingScreen* screen) override;
   void Show() override;
   void Hide() override;
 
@@ -51,11 +53,17 @@
   // BaseScreenHandler:
   void Initialize() override;
 
-  AppDownloadingScreen* screen_ = nullptr;
+  ash::AppDownloadingScreen* screen_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(AppDownloadingScreenHandler);
 };
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::AppDownloadingScreenView;
+}
+
 #endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_APP_DOWNLOADING_SCREEN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.h
index 9835f181..1cfcbe5 100644
--- a/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.h
@@ -20,9 +20,12 @@
 class ArcOptInPreferenceHandler;
 }
 
+namespace ash {
+class ArcTermsOfServiceScreen;
+}
+
 namespace chromeos {
 
-class ArcTermsOfServiceScreen;
 class ArcTermsOfServiceScreenView;
 
 class ArcTermsOfServiceScreenViewObserver {
@@ -60,7 +63,7 @@
   virtual void Hide() = 0;
 
   // Sets view and screen.
-  virtual void Bind(ArcTermsOfServiceScreen* screen) = 0;
+  virtual void Bind(ash::ArcTermsOfServiceScreen* screen) = 0;
 
  protected:
   ArcTermsOfServiceScreenView() = default;
@@ -95,7 +98,7 @@
   void RemoveObserver(ArcTermsOfServiceScreenViewObserver* observer) override;
   void Show() override;
   void Hide() override;
-  void Bind(ArcTermsOfServiceScreen* screen) override;
+  void Bind(ash::ArcTermsOfServiceScreen* screen) override;
 
   // OobeUI::Observer:
   void OnCurrentScreenChanged(OobeScreenId current_screen,
@@ -180,6 +183,7 @@
 // source migration is finished.
 namespace ash {
 using ::chromeos::ArcTermsOfServiceScreenView;
+using ::chromeos::ArcTermsOfServiceScreenViewObserver;
 }
 
 #endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_ARC_TERMS_OF_SERVICE_SCREEN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h
index febf7be..2611a15 100644
--- a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h
@@ -17,9 +17,11 @@
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 
-namespace chromeos {
-
+namespace ash {
 class AssistantOptInFlowScreen;
+}
+
+namespace chromeos {
 
 // Interface for dependency injection between AssistantOptInFlowScreen
 // and its WebUI representation.
@@ -29,7 +31,7 @@
 
   virtual ~AssistantOptInFlowScreenView() = default;
 
-  virtual void Bind(AssistantOptInFlowScreen* screen) = 0;
+  virtual void Bind(ash::AssistantOptInFlowScreen* screen) = 0;
   virtual void Unbind() = 0;
   virtual void Show() = 0;
   virtual void Hide() = 0;
@@ -67,7 +69,7 @@
   void GetAdditionalParameters(base::DictionaryValue* dict) override;
 
   // AssistantOptInFlowScreenView:
-  void Bind(AssistantOptInFlowScreen* screen) override;
+  void Bind(ash::AssistantOptInFlowScreen* screen) override;
   void Unbind() override;
   void Show() override;
   void Hide() override;
@@ -134,7 +136,7 @@
   // Power related
   bool DeviceHasBattery();
 
-  AssistantOptInFlowScreen* screen_ = nullptr;
+  ash::AssistantOptInFlowScreen* screen_ = nullptr;
 
   base::OnceClosure on_initialized_;
 
@@ -178,4 +180,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::AssistantOptInFlowScreenView;
+}
+
 #endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_ASSISTANT_OPTIN_FLOW_SCREEN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
index 998bf11..e8afe300 100644
--- a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
@@ -8,11 +8,11 @@
 #include "base/macros.h"
 #include "chrome/browser/ash/login/oobe_screen.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h"
+// TODO(https://crbug.com/1164001): move to forward declaration
+#include "chrome/browser/ash/login/screens/base_screen.h"
 
 namespace chromeos {
 
-class BaseScreen;
-
 // Base class for the OOBE/Login WebUI handlers which provide methods specific
 // to a particular OobeScreen.
 class BaseScreenHandler : public BaseWebUIHandler {
diff --git a/chrome/browser/ui/webui/chromeos/login/demo_preferences_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/demo_preferences_screen_handler.h
index 903b4e76..b4c3c44 100644
--- a/chrome/browser/ui/webui/chromeos/login/demo_preferences_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/demo_preferences_screen_handler.h
@@ -9,9 +9,11 @@
 
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 
-namespace chromeos {
-
+namespace ash {
 class DemoPreferencesScreen;
+}
+
+namespace chromeos {
 
 // Interface of the demo mode preferences screen view.
 class DemoPreferencesScreenView {
@@ -27,7 +29,7 @@
   virtual void Hide() = 0;
 
   // Sets view and screen.
-  virtual void Bind(DemoPreferencesScreen* screen) = 0;
+  virtual void Bind(ash::DemoPreferencesScreen* screen) = 0;
 
   // Called to set the input method id on JS side.
   virtual void SetInputMethodId(const std::string& input_method) = 0;
@@ -45,7 +47,7 @@
   // DemoPreferencesScreenView:
   void Show() override;
   void Hide() override;
-  void Bind(DemoPreferencesScreen* screen) override;
+  void Bind(ash::DemoPreferencesScreen* screen) override;
   void SetInputMethodId(const std::string& input_method) override;
 
   // BaseScreenHandler:
@@ -61,7 +63,7 @@
   void HandleSetInputMethodId(const std::string& language_id);
   void HandleSetDemoModeCountry(const std::string& country_id);
 
-  DemoPreferencesScreen* screen_ = nullptr;
+  ash::DemoPreferencesScreen* screen_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(DemoPreferencesScreenHandler);
 };
diff --git a/chrome/browser/ui/webui/chromeos/login/demo_setup_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/demo_setup_screen_handler.h
index 746f3d4..d8db533 100644
--- a/chrome/browser/ui/webui/chromeos/login/demo_setup_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/demo_setup_screen_handler.h
@@ -8,9 +8,11 @@
 #include "chrome/browser/ash/login/demo_mode/demo_setup_controller.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 
-namespace chromeos {
-
+namespace ash {
 class DemoSetupScreen;
+}
+
+namespace chromeos {
 
 // Interface of the demo mode setup screen view.
 class DemoSetupScreenView {
@@ -26,7 +28,7 @@
   virtual void Hide() = 0;
 
   // Sets view and screen.
-  virtual void Bind(DemoSetupScreen* screen) = 0;
+  virtual void Bind(ash::DemoSetupScreen* screen) = 0;
 
   // Updates current setup step.
   virtual void SetCurrentSetupStep(
@@ -53,7 +55,7 @@
   // DemoSetupScreenView:
   void Show() override;
   void Hide() override;
-  void Bind(DemoSetupScreen* screen) override;
+  void Bind(ash::DemoSetupScreen* screen) override;
   void SetCurrentSetupStep(
       DemoSetupController::DemoSetupStep current_step) override;
   void OnSetupFailed(const DemoSetupController::DemoSetupError& error) override;
@@ -68,7 +70,7 @@
   void GetAdditionalParameters(base::DictionaryValue* parameters) override;
 
  private:
-  DemoSetupScreen* screen_ = nullptr;
+  ash::DemoSetupScreen* screen_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(DemoSetupScreenHandler);
 };
diff --git a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h
index 2098029..78a45e9 100644
--- a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h
@@ -8,9 +8,11 @@
 #include "base/macros.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 
-namespace chromeos {
-
+namespace ash {
 class DeviceDisabledScreen;
+}
+
+namespace chromeos {
 
 // Interface between the device disabled screen and its representation.
 class DeviceDisabledScreenView {
@@ -23,7 +25,7 @@
                     const std::string& domain,
                     const std::string& message) = 0;
   virtual void Hide() = 0;
-  virtual void Bind(DeviceDisabledScreen* screen) = 0;
+  virtual void Bind(ash::DeviceDisabledScreen* screen) = 0;
   virtual void UpdateMessage(const std::string& message) = 0;
 };
 
@@ -41,7 +43,7 @@
             const std::string& domain,
             const std::string& message) override;
   void Hide() override;
-  void Bind(DeviceDisabledScreen* screen) override;
+  void Bind(ash::DeviceDisabledScreen* screen) override;
   void UpdateMessage(const std::string& message) override;
 
   // BaseScreenHandler:
@@ -53,7 +55,7 @@
   // WebUIMessageHandler:
   void RegisterMessages() override;
 
-  DeviceDisabledScreen* screen_ = nullptr;
+  ash::DeviceDisabledScreen* screen_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(DeviceDisabledScreenHandler);
 };
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
index 5fd1e09..f976df8 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
@@ -208,4 +208,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::ActiveDirectoryErrorState;
+}
+
 #endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_ENROLLMENT_SCREEN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
index b3ebd53..18f8d24 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -423,6 +423,7 @@
 // TODO(https://crbug.com/1164001): remove when moved to ash.
 namespace ash {
 using ::chromeos::GaiaScreenHandler;
+using ::chromeos::GaiaView;
 }
 
 #endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_GAIA_SCREEN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/l10n_util.h b/chrome/browser/ui/webui/chromeos/login/l10n_util.h
index c38f8d1..199d88a8 100644
--- a/chrome/browser/ui/webui/chromeos/login/l10n_util.h
+++ b/chrome/browser/ui/webui/chromeos/login/l10n_util.h
@@ -95,8 +95,10 @@
 // TODO(https://crbug.com/1164001): remove when ch/br/ui/webui/chromeos is moved
 // to ash.
 namespace ash {
+using ::chromeos::FindMostRelevantLocale;
 using ::chromeos::GetUILanguageList;
 using ::chromeos::kMostRelevantLanguagesDivider;
+using ::chromeos::ResolveUILanguageList;
 }  // namespace ash
 
 #endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_L10N_UTIL_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h
index 7c4214c..6fc8131 100644
--- a/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h
@@ -12,14 +12,16 @@
 #include "chrome/browser/ash/accessibility/accessibility_manager.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 
+namespace ash {
+class WelcomeScreen;
+}
+
 namespace base {
 class ListValue;
 }
 
 namespace chromeos {
-
 class CoreOobeView;
-class WelcomeScreen;
 
 // Interface for WelcomeScreenHandler.
 class WelcomeView {
@@ -35,7 +37,7 @@
   virtual void Hide() = 0;
 
   // Binds `screen` to the view.
-  virtual void Bind(WelcomeScreen* screen) = 0;
+  virtual void Bind(ash::WelcomeScreen* screen) = 0;
 
   // Unbinds model from the view.
   virtual void Unbind() = 0;
@@ -69,7 +71,7 @@
   // WelcomeView:
   void Show() override;
   void Hide() override;
-  void Bind(WelcomeScreen* screen) override;
+  void Bind(ash::WelcomeScreen* screen) override;
   void Unbind() override;
   void ReloadLocalizedContent() override;
   void SetInputMethodId(const std::string& input_method_id) override;
@@ -112,7 +114,7 @@
   static std::unique_ptr<base::ListValue> GetTimezoneList();
 
   CoreOobeView* core_oobe_view_ = nullptr;
-  WelcomeScreen* screen_ = nullptr;
+  ash::WelcomeScreen* screen_ = nullptr;
 
   // Keeps whether screen should be shown right after initialization.
   bool show_on_init_ = false;
diff --git a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
index ca66dd75..970f827 100644
--- a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
@@ -383,35 +383,19 @@
 
 void LanguagesSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
   static constexpr webui::LocalizedString kLocalizedStrings[] = {
-      {"orderLanguagesInstructions",
-       IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_ORDERING_INSTRUCTIONS},
       {"osLanguagesPageTitle", IDS_OS_SETTINGS_LANGUAGES_AND_INPUT_PAGE_TITLE},
       {"languagesPageTitle", IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PAGE_TITLE},
       {"inputPageTitle", IDS_OS_SETTINGS_LANGUAGES_INPUT_PAGE_TITLE},
-      {"osLanguagesListTitle", IDS_OS_SETTINGS_LANGUAGES_LIST_TITLE},
-      {"inputMethodsListTitle",
-       IDS_SETTINGS_LANGUAGES_INPUT_METHODS_LIST_TITLE},
+      {"inputPageTitleV2", IDS_OS_SETTINGS_LANGUAGES_INPUT_PAGE_TITLE_V2},
       {"inputMethodEnabled", IDS_SETTINGS_LANGUAGES_INPUT_METHOD_ENABLED},
-      {"inputMethodsExpandA11yLabel",
-       IDS_SETTINGS_LANGUAGES_INPUT_METHODS_EXPAND_ACCESSIBILITY_LABEL},
       {"inputMethodsManagedbyPolicy",
        IDS_SETTINGS_LANGUAGES_INPUT_METHODS_MANAGED_BY_POLICY},
-      {"manageInputMethods", IDS_SETTINGS_LANGUAGES_INPUT_METHODS_MANAGE},
-      // TODO(crbug.com/1097328): Remove this string, as it is unused.
-      {"manageInputMethodsPageTitle",
-       IDS_SETTINGS_LANGUAGES_MANAGE_INPUT_METHODS_TITLE},
       {"showImeMenu", IDS_SETTINGS_LANGUAGES_SHOW_IME_MENU},
-      {"displayLanguageRestart",
-       IDS_SETTINGS_LANGUAGES_RESTART_TO_DISPLAY_LANGUAGE},
       {"moveDown", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_DOWN},
-      {"displayInThisLanguage",
-       IDS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE},
       {"searchLanguages", IDS_SETTINGS_LANGUAGE_SEARCH},
       {"addLanguagesDialogTitle",
        IDS_SETTINGS_LANGUAGES_MANAGE_LANGUAGES_TITLE},
       {"moveToTop", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_TO_TOP},
-      {"isDisplayedInThisLanguage",
-       IDS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE},
       {"removeLanguage", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_REMOVE},
       {"addLanguages", IDS_SETTINGS_LANGUAGES_LANGUAGES_ADD},
       {"moveUp", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_UP},
@@ -423,9 +407,6 @@
   AddLanguagesPageStringsV2(html_source);
   AddInputPageStringsV2(html_source);
 
-  html_source->AddString(
-      "languagesLearnMoreURL",
-      base::ASCIIToUTF16(chrome::kLanguageSettingsLearnMoreUrl));
   html_source->AddBoolean("imeOptionsInSettings",
                           base::FeatureList::IsEnabled(
                               ::chromeos::features::kImeOptionsInSettings));
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index 2277bd6..5dcc4bc4 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -667,6 +667,7 @@
 void AddLanguagesStrings(content::WebUIDataSource* html_source,
                          Profile* profile) {
   static constexpr webui::LocalizedString kLocalizedStrings[] = {
+    {"languagesPageTitle", IDS_SETTINGS_LANGUAGES_PAGE_TITLE},
     {"languagesListTitle", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_TITLE},
     {"searchLanguages", IDS_SETTINGS_LANGUAGE_SEARCH},
     {"languagesExpandA11yLabel",
@@ -681,9 +682,11 @@
     {"addLanguagesDialogTitle", IDS_SETTINGS_LANGUAGES_MANAGE_LANGUAGES_TITLE},
     {"allLanguages", IDS_SETTINGS_LANGUAGES_ALL_LANGUAGES},
     {"enabledLanguages", IDS_SETTINGS_LANGUAGES_ENABLED_LANGUAGES},
+#if defined(OS_WIN)
     {"isDisplayedInThisLanguage",
      IDS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE},
     {"displayInThisLanguage", IDS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE},
+#endif
     {"offerToTranslateInThisLanguage",
      IDS_SETTINGS_LANGUAGES_OFFER_TO_TRANSLATE_IN_THIS_LANGUAGE},
     {"offerToEnableTranslate",
@@ -730,20 +733,6 @@
   html_source->AddLocalizedStrings(kLocalizedStrings);
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  // Only the Chrome OS help article explains how language order affects website
-  // language.
-  html_source->AddString(
-      "languagesLearnMoreURL",
-      base::ASCIIToUTF16(chrome::kLanguageSettingsLearnMoreUrl));
-  html_source->AddString(
-      "languagesPageTitle",
-      l10n_util::GetStringUTF16(IDS_SETTINGS_LANGUAGES_PAGE_TITLE));
-#else
-  html_source->AddString(
-      "languagesPageTitle",
-      l10n_util::GetStringUTF16(IDS_SETTINGS_LANGUAGES_PAGE_TITLE));
-#endif
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
   const user_manager::User* user =
       chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
diff --git a/chrome/browser/web_applications/components/file_handling_permission_request_impl.cc b/chrome/browser/web_applications/components/file_handling_permission_request_impl.cc
index c47de69c..c6f199b 100644
--- a/chrome/browser/web_applications/components/file_handling_permission_request_impl.cc
+++ b/chrome/browser/web_applications/components/file_handling_permission_request_impl.cc
@@ -34,7 +34,7 @@
   DCHECK(profile);
 
   std::u16string extensions_list =
-      web_app::GetFileExtensionsHandledByWebAppDisplayedAsList(
+      web_app::GetFileTypeAssociationsHandledByWebAppDisplayedAsList(
           profile, web_contents->GetLastCommittedURL());
   message_text_fragment_ = l10n_util::GetStringFUTF16(
       IDS_WEB_APP_FILE_HANDLING_PERMISSION_TEXT, extensions_list);
diff --git a/chrome/browser/web_applications/components/web_app_install_utils.cc b/chrome/browser/web_applications/components/web_app_install_utils.cc
index d545683..e393d35e 100644
--- a/chrome/browser/web_applications/components/web_app_install_utils.cc
+++ b/chrome/browser/web_applications/components/web_app_install_utils.cc
@@ -249,9 +249,6 @@
     DCHECK(!icon.purpose.empty());
 
     for (IconPurpose purpose : icon.purpose) {
-      if (purpose != IconPurpose::ANY && purpose != IconPurpose::MASKABLE)
-        continue;
-
       WebApplicationIconInfo info;
 
       if (!icon.sizes.empty()) {
@@ -381,6 +378,7 @@
 
   std::vector<WebApplicationIconInfo> icon_infos_any;
   std::vector<WebApplicationIconInfo> icon_infos_maskable;
+  std::vector<WebApplicationIconInfo> icon_infos_monochrome;
   for (WebApplicationIconInfo& icon_info : web_app_info->icon_infos) {
     switch (icon_info.purpose) {
       case IconPurpose::ANY:
@@ -390,18 +388,21 @@
         icon_infos_maskable.push_back(icon_info);
         break;
       case IconPurpose::MONOCHROME:
-        // Not used.
+        icon_infos_monochrome.push_back(icon_info);
         break;
     }
   }
 
   std::vector<SkBitmap> square_icons_any;
   std::vector<SkBitmap> square_icons_maskable;
+  std::vector<SkBitmap> square_icons_monochrome;
   if (icons_map) {
     AddSquareIconsFromMapMatchingIconInfos(&square_icons_any, icon_infos_any,
                                            *icons_map);
     AddSquareIconsFromMapMatchingIconInfos(&square_icons_maskable,
                                            icon_infos_maskable, *icons_map);
+    AddSquareIconsFromMapMatchingIconInfos(&square_icons_monochrome,
+                                           icon_infos_monochrome, *icons_map);
     // Fall back to using all icons from |icons_map| if none match icon_infos.
     if (square_icons_any.empty())
       AddSquareIconsFromMap(&square_icons_any, *icons_map);
@@ -414,6 +415,12 @@
       web_app_info->icon_bitmaps.maskable[bitmap.width()] = std::move(bitmap);
   }
 
+  for (SkBitmap& bitmap : square_icons_monochrome) {
+    // Retain any bitmaps provided as input to the installation.
+    if (web_app_info->icon_bitmaps.monochrome.count(bitmap.width()) == 0)
+      web_app_info->icon_bitmaps.monochrome[bitmap.width()] = std::move(bitmap);
+  }
+
   char16_t icon_letter =
       web_app_info->title.empty()
           ? GenerateIconLetterFromUrl(web_app_info->start_url)
diff --git a/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc b/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc
index 9f76acb..0816e19 100644
--- a/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc
+++ b/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc
@@ -107,16 +107,21 @@
   manifest.display = DisplayMode::kMinimalUi;
 
   blink::Manifest::ImageResource icon;
+
   const GURL kAppIcon2("fav2.png");
   icon.src = kAppIcon2;
   icon.purpose = {Purpose::ANY, Purpose::MONOCHROME};
   manifest.icons.push_back(icon);
+
   const GURL kAppIcon3("fav3.png");
   icon.src = kAppIcon3;
+  icon.purpose = {Purpose::ANY, Purpose::MONOCHROME};
   manifest.icons.push_back(icon);
+
   // Add an icon without purpose ANY (expect to be ignored).
   icon.purpose = {Purpose::MONOCHROME};
   manifest.icons.push_back(icon);
+
   manifest.display_override.push_back(DisplayMode::kMinimalUi);
   manifest.display_override.push_back(DisplayMode::kStandalone);
 
@@ -127,9 +132,13 @@
   EXPECT_EQ(DisplayMode::kMinimalUi, web_app_info.display_override[0]);
   EXPECT_EQ(DisplayMode::kStandalone, web_app_info.display_override[1]);
 
-  EXPECT_EQ(2u, web_app_info.icon_infos.size());
+  // We currently duplicate the app icons with multiple Purposes.
+  EXPECT_EQ(5u, web_app_info.icon_infos.size());
   EXPECT_EQ(kAppIcon2, web_app_info.icon_infos[0].url);
   EXPECT_EQ(kAppIcon3, web_app_info.icon_infos[1].url);
+  EXPECT_EQ(kAppIcon2, web_app_info.icon_infos[2].url);
+  EXPECT_EQ(kAppIcon3, web_app_info.icon_infos[3].url);
+  EXPECT_EQ(kAppIcon3, web_app_info.icon_infos[4].url);
 
   // Check file handlers were updated
   EXPECT_EQ(1u, web_app_info.file_handlers.size());
@@ -175,20 +184,20 @@
   // Produces 1 icon_info.
   icon.purpose = {Purpose::MASKABLE};
   manifest.icons.push_back(icon);
-  // Not converted to an icon_info (for now).
+  // Produces 1 icon_info.
   icon.purpose = {Purpose::MONOCHROME};
   manifest.icons.push_back(icon);
   WebApplicationInfo web_app_info;
 
   UpdateWebAppInfoFromManifest(
       manifest, GURL("http://www.chromium.org/manifest.json"), &web_app_info);
-  EXPECT_EQ(3U, web_app_info.icon_infos.size());
+  EXPECT_EQ(4u, web_app_info.icon_infos.size());
   std::map<IconPurpose, int> purpose_to_count;
   for (const auto& icon_info : web_app_info.icon_infos) {
     purpose_to_count[icon_info.purpose]++;
   }
   EXPECT_EQ(1, purpose_to_count[IconPurpose::ANY]);
-  EXPECT_EQ(0, purpose_to_count[IconPurpose::MONOCHROME]);
+  EXPECT_EQ(1, purpose_to_count[IconPurpose::MONOCHROME]);
   EXPECT_EQ(2, purpose_to_count[IconPurpose::MASKABLE]);
 }
 
@@ -372,13 +381,17 @@
   manifest.display = DisplayMode::kMinimalUi;
 
   blink::Manifest::ImageResource icon;
+
   const GURL kAppIcon2("fav2.png");
   icon.src = kAppIcon2;
   icon.purpose = {Purpose::ANY, Purpose::MONOCHROME};
   manifest.icons.push_back(icon);
+
   const GURL kAppIcon3("fav3.png");
   icon.src = kAppIcon3;
+  icon.purpose = {Purpose::ANY, Purpose::MONOCHROME};
   manifest.icons.push_back(icon);
+
   // Add an icon without purpose ANY (expect to be ignored).
   icon.purpose = {Purpose::MONOCHROME};
   manifest.icons.push_back(icon);
@@ -409,9 +422,13 @@
   EXPECT_EQ(kAppTitle, web_app_info.title);
   EXPECT_EQ(DisplayMode::kMinimalUi, web_app_info.display_mode);
 
-  EXPECT_EQ(2u, web_app_info.icon_infos.size());
+  // We currently duplicate the app icons with multiple Purposes.
+  EXPECT_EQ(5u, web_app_info.icon_infos.size());
   EXPECT_EQ(kAppIcon2, web_app_info.icon_infos[0].url);
   EXPECT_EQ(kAppIcon3, web_app_info.icon_infos[1].url);
+  EXPECT_EQ(kAppIcon2, web_app_info.icon_infos[2].url);
+  EXPECT_EQ(kAppIcon3, web_app_info.icon_infos[3].url);
+  EXPECT_EQ(kAppIcon3, web_app_info.icon_infos[4].url);
 
   EXPECT_EQ(2u, web_app_info.shortcuts_menu_item_infos.size());
   EXPECT_EQ(1u, web_app_info.shortcuts_menu_item_infos[0]
diff --git a/chrome/browser/web_applications/components/web_app_shortcut_linux.cc b/chrome/browser/web_applications/components/web_app_shortcut_linux.cc
index e78d01a..a151db5 100644
--- a/chrome/browser/web_applications/components/web_app_shortcut_linux.cc
+++ b/chrome/browser/web_applications/components/web_app_shortcut_linux.cc
@@ -182,7 +182,7 @@
     return false;
   }
 
-  if (!base::WriteFileDescriptor(fd, contents.c_str(), contents.size())) {
+  if (!base::WriteFileDescriptor(fd, contents)) {
     // Delete the file. No shortcut is better than corrupted one. Use unlinkat
     // to make sure we're deleting the file in the directory we think we are.
     // Even if an attacker manager to put something other at
diff --git a/chrome/browser/web_applications/components/web_app_utils.cc b/chrome/browser/web_applications/components/web_app_utils.cc
index 56b7dc8..58875b5 100644
--- a/chrome/browser/web_applications/components/web_app_utils.cc
+++ b/chrome/browser/web_applications/components/web_app_utils.cc
@@ -7,13 +7,13 @@
 #include "base/files/file_path.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/grit/generated_resources.h"
-#include "components/services/app_service/public/cpp/file_handler.h"
 #include "components/site_engagement/content/site_engagement_service.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "url/gurl.h"
@@ -139,8 +139,8 @@
 #endif
 }
 
-std::vector<std::string> GetFileExtensionsHandledByWebApp(Profile* profile,
-                                                          const GURL& url) {
+const apps::FileHandlers GetFileHandlersForWebApp(Profile* profile,
+                                                  const GURL& url) {
   auto* provider = WebAppProviderBase::GetProviderBase(profile);
   if (!provider)
     return {};
@@ -150,26 +150,37 @@
   if (!app_id)
     return {};
 
-  std::set<std::string> extensions = apps::GetFileExtensionsFromFileHandlers(
-      *registrar.GetAppFileHandlers(*app_id));
-  return std::vector<std::string>(extensions.begin(), extensions.end());
+  return *registrar.GetAppFileHandlers(*app_id);
 }
 
-std::u16string GetFileExtensionsHandledByWebAppDisplayedAsList(
+std::u16string GetFileTypeAssociationsHandledByWebAppDisplayedAsList(
     Profile* profile,
     const GURL& url) {
-  std::vector<std::string> extensions =
-      GetFileExtensionsHandledByWebApp(profile, url);
+  const apps::FileHandlers file_handlers =
+      GetFileHandlersForWebApp(profile, url);
+  std::vector<std::string> associations;
+#if defined(OS_LINUX)
+  std::set<std::string> mime_types_set =
+      apps::GetMimeTypesFromFileHandlers(file_handlers);
+  associations.reserve(mime_types_set.size());
+  associations.insert(associations.end(), mime_types_set.begin(),
+                      mime_types_set.end());
+#else   // !defined(OS_LINUX)
+  std::set<std::string> extensions_set =
+      apps::GetFileExtensionsFromFileHandlers(file_handlers);
+  associations.reserve(extensions_set.size());
 
   // Convert file types from formats like ".txt" to "TXT".
-  std::transform(extensions.begin(), extensions.end(), extensions.begin(),
+  std::transform(extensions_set.begin(), extensions_set.end(),
+                 std::back_inserter(associations),
                  [](const std::string& extension) {
                    return base::ToUpperASCII(extension.substr(1));
                  });
+#endif  // defined(OS_LINUX)
 
   return base::UTF8ToUTF16(base::JoinString(
-      extensions, l10n_util::GetStringUTF8(
-                      IDS_WEB_APP_FILE_HANDLING_EXTENSION_LIST_SEPARATOR)));
+      associations, l10n_util::GetStringUTF8(
+                        IDS_WEB_APP_FILE_HANDLING_EXTENSION_LIST_SEPARATOR)));
 }
 
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_utils.h b/chrome/browser/web_applications/components/web_app_utils.h
index a083f0f1..4bd389a 100644
--- a/chrome/browser/web_applications/components/web_app_utils.h
+++ b/chrome/browser/web_applications/components/web_app_utils.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "chrome/browser/web_applications/components/web_app_id.h"
+#include "components/services/app_service/public/cpp/file_handler.h"
 
 class GURL;
 class Profile;
@@ -71,17 +72,18 @@
 // Returns true if the WebApp should have `web_app::WebAppChromeOsData()`.
 bool IsChromeOs();
 
-// Returns a vector of file extensions of the form ".csv" which are handled by
-// the app for `url`. It is an error to call this with a URL that doesn't
-// correspond to an app in `profile`.
-std::vector<std::string> GetFileExtensionsHandledByWebApp(Profile* profile,
-                                                          const GURL& url);
+// Returns file handlers associated with the app at `url`, in the `profile`.
+const apps::FileHandlers GetFileHandlersForWebApp(Profile* profile,
+                                                  const GURL& url);
 
-// Returns a display-ready string that holds all the file extensions handled by
-// the app for `url`. It is an error to call this with a URL that doesn't
-// correspond to an app in `profile`.
-std::u16string GetFileExtensionsHandledByWebAppDisplayedAsList(Profile* profile,
-                                                               const GURL& url);
+// Returns a display-ready string that holds all file type associations handled
+// by the app at `url`. On Linux, where files are associated via MIME types,
+// this will return MIME types like "text/plain, image/png". On all other
+// platforms, where files are associated via file extensions, this will return
+// capitalized file extensions with the period truncated, like "TXT, PNG".
+std::u16string GetFileTypeAssociationsHandledByWebAppDisplayedAsList(
+    Profile* profile,
+    const GURL& url);
 
 }  // namespace web_app
 
diff --git a/chrome/browser/web_applications/components/web_application_info.cc b/chrome/browser/web_applications/components/web_application_info.cc
index b7fa0c25..63f6cfd6 100644
--- a/chrome/browser/web_applications/components/web_application_info.cc
+++ b/chrome/browser/web_applications/components/web_application_info.cc
@@ -24,9 +24,7 @@
     IconPurpose purpose) const {
   switch (purpose) {
     case IconPurpose::MONOCHROME:
-      // TODO (crbug.com/1114638): Monochrome support.
-      NOTREACHED();
-      FALLTHROUGH;
+      return monochrome;
     case IconPurpose::ANY:
       return any;
     case IconPurpose::MASKABLE:
@@ -42,8 +40,7 @@
       any = std::move(bitmaps);
       return;
     case IconPurpose::MONOCHROME:
-      // TODO (crbug.com/1114638): Monochrome support.
-      NOTREACHED();
+      monochrome = std::move(bitmaps);
       return;
     case IconPurpose::MASKABLE:
       maskable = std::move(bitmaps);
@@ -52,8 +49,7 @@
 }
 
 bool IconBitmaps::empty() const {
-  // TODO (crbug.com/1114638): Check Monochrome if supported.
-  return any.empty() && maskable.empty();
+  return any.empty() && maskable.empty() && monochrome.empty();
 }
 
 // IconSizes
@@ -73,9 +69,7 @@
     IconPurpose purpose) const {
   switch (purpose) {
     case IconPurpose::MONOCHROME:
-      // TODO (crbug.com/1114638): Monochrome support.
-      NOTREACHED();
-      FALLTHROUGH;
+      return monochrome;
     case IconPurpose::ANY:
       return any;
     case IconPurpose::MASKABLE:
@@ -90,8 +84,7 @@
       any = std::move(sizes);
       return;
     case IconPurpose::MONOCHROME:
-      // TODO (crbug.com/1114638): Monochrome support.
-      NOTREACHED();
+      monochrome = std::move(sizes);
       return;
     case IconPurpose::MASKABLE:
       maskable = std::move(sizes);
@@ -100,8 +93,7 @@
 }
 
 bool IconSizes::empty() const {
-  // TODO (crbug.com/1114638): Check Monochrome if supported.
-  return any.empty() && maskable.empty();
+  return any.empty() && maskable.empty() && monochrome.empty();
 }
 
 // WebApplicationIconInfo
@@ -251,9 +243,10 @@
 }
 
 bool operator==(const IconSizes& icon_sizes1, const IconSizes& icon_sizes2) {
-  // TODO (crbug.com/1114638): Add Monochrome support.
-  return std::tie(icon_sizes1.any, icon_sizes1.maskable) ==
-         std::tie(icon_sizes2.any, icon_sizes2.maskable);
+  return std::tie(icon_sizes1.any, icon_sizes1.maskable,
+                  icon_sizes1.monochrome) == std::tie(icon_sizes2.any,
+                                                      icon_sizes2.maskable,
+                                                      icon_sizes2.monochrome);
 }
 
 bool operator==(const WebApplicationShortcutsMenuItemInfo::Icon& icon1,
diff --git a/chrome/browser/web_applications/components/web_application_info.h b/chrome/browser/web_applications/components/web_application_info.h
index f59fad8..134e962 100644
--- a/chrome/browser/web_applications/components/web_application_info.h
+++ b/chrome/browser/web_applications/components/web_application_info.h
@@ -56,7 +56,9 @@
   // See https://www.w3.org/TR/appmanifest/#dfn-maskable-purpose
   std::map<SquareSizePx, SkBitmap> maskable;
 
-  // TODO (crbug.com/1114638): Monochrome support.
+  // Monochrome bitmaps designed for any context, keyed by their square size.
+  // See https://www.w3.org/TR/appmanifest/#purpose-member
+  std::map<SquareSizePx, SkBitmap> monochrome;
 };
 
 // Icon sizes for each IconPurpose.
@@ -82,7 +84,9 @@
   // See https://www.w3.org/TR/appmanifest/#dfn-maskable-purpose
   std::vector<SquareSizePx> maskable;
 
-  // TODO (crbug.com/1114638): Monochrome support.
+  // Sizes of monochrome bitmaps, keyed by their square size.
+  // See https://www.w3.org/TR/appmanifest/#purpose-member
+  std::vector<SquareSizePx> monochrome;
 };
 
 using ShortcutsMenuIconBitmaps = std::vector<IconBitmaps>;
@@ -100,7 +104,6 @@
 
   GURL url;
   base::Optional<SquareSizePx> square_size_px;
-  // TODO (crbug.com/1114638): Support Monochrome.
   IconPurpose purpose = IconPurpose::ANY;
 };
 
diff --git a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
index af29313..0d369f1 100644
--- a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
+++ b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
@@ -1781,8 +1781,14 @@
   OverrideManifest(kFileHandlerManifestTemplate, {kInstallableIconList});
   InstallWebApp();
 
-  EXPECT_EQ(u"TXT", GetFileExtensionsHandledByWebAppDisplayedAsList(
-                        browser()->profile(), GetAppURL()));
+  std::u16string associations_list =
+      GetFileTypeAssociationsHandledByWebAppDisplayedAsList(
+          browser()->profile(), GetAppURL());
+#if defined(OS_LINUX)
+  EXPECT_EQ(u"text/plain", associations_list);
+#else
+  EXPECT_EQ(u"TXT", associations_list);
+#endif  // defined(OS_LINUX)
 }
 
 IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTestWithFileHandling,
@@ -1809,8 +1815,14 @@
   OverrideManifest(kFileHandlerManifestTemplate, {kInstallableIconList});
   InstallWebApp();
 
-  EXPECT_EQ(u"MD, TXT", GetFileExtensionsHandledByWebAppDisplayedAsList(
-                            browser()->profile(), GetAppURL()));
+  std::u16string associations_list =
+      GetFileTypeAssociationsHandledByWebAppDisplayedAsList(
+          browser()->profile(), GetAppURL());
+#if defined(OS_LINUX)
+  EXPECT_EQ(u"text/plain", associations_list);
+#else
+  EXPECT_EQ(u"MD, TXT", associations_list);
+#endif  // defined(OS_LINUX)
 }
 
 IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTestWithFileHandling,
@@ -1844,8 +1856,14 @@
   OverrideManifest(kFileHandlerManifestTemplate, {kInstallableIconList});
   InstallWebApp();
 
-  EXPECT_EQ(u"LONGTYPE, TXT", GetFileExtensionsHandledByWebAppDisplayedAsList(
-                                  browser()->profile(), GetAppURL()));
+  std::u16string associations_list =
+      GetFileTypeAssociationsHandledByWebAppDisplayedAsList(
+          browser()->profile(), GetAppURL());
+#if defined(OS_LINUX)
+  EXPECT_EQ(u"long/type, text/plain", associations_list);
+#else
+  EXPECT_EQ(u"LONGTYPE, TXT", associations_list);
+#endif  // defined(OS_LINUX)
 }
 
 class ManifestUpdateManagerBrowserTestWithShortcutsMenu
diff --git a/chrome/browser/web_applications/manifest_update_task.cc b/chrome/browser/web_applications/manifest_update_task.cc
index 4fe8d7e..ea08be6f 100644
--- a/chrome/browser/web_applications/manifest_update_task.cc
+++ b/chrome/browser/web_applications/manifest_update_task.cc
@@ -57,11 +57,12 @@
 
 bool HaveIconBitmapsChanged(const IconBitmaps& disk_icon_bitmaps,
                             const IconBitmaps& downloaded_icon_bitmaps) {
-  // TODO (crbug.com/1114638): Check Monochrome icons if supported.
   return HaveIconContentsChanged(disk_icon_bitmaps.any,
                                  downloaded_icon_bitmaps.any) ||
          HaveIconContentsChanged(disk_icon_bitmaps.maskable,
-                                 downloaded_icon_bitmaps.maskable);
+                                 downloaded_icon_bitmaps.maskable) ||
+         HaveIconContentsChanged(disk_icon_bitmaps.monochrome,
+                                 downloaded_icon_bitmaps.monochrome);
 }
 
 // Some apps, such as pre-installed apps, have been vetted and are therefore
diff --git a/chrome/browser/web_applications/proto/web_app.proto b/chrome/browser/web_applications/proto/web_app.proto
index e4d5084..8cfc3e1 100644
--- a/chrome/browser/web_applications/proto/web_app.proto
+++ b/chrome/browser/web_applications/proto/web_app.proto
@@ -113,7 +113,8 @@
 
   // A list of icon sizes we successfully downloaded to store on disk, for icons
   // that are suitable for any purpose (ie. IconPurpose::ANY). See also:
-  // |downloaded_icon_sizes_purpose_maskable|.
+  // |downloaded_icon_sizes_purpose_maskable|,
+  // |downloaded_icon_sizes_purpose_monochrome|.
   repeated int32 downloaded_icon_sizes_purpose_any = 11;
 
   // A list of file handlers.
@@ -197,4 +198,10 @@
   optional int64 last_badging_time = 31;
 
   optional bool file_handler_permission_blocked = 32;
+
+  // A list of icon sizes we successfully downloaded to store on disk for
+  // monochrome icons. (IconPurpose::MONOCHROME). See also:
+  // |downloaded_icon_sizes_purpose_any|,
+  // |downloaded_icon_sizes_purpose_maskable|.
+  repeated int32 downloaded_icon_sizes_purpose_monochrome = 33;
 }
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.cc b/chrome/browser/web_applications/test/web_app_test_utils.cc
index 1cb7841..1fed556 100644
--- a/chrome/browser/web_applications/test/web_app_test_utils.cc
+++ b/chrome/browser/web_applications/test/web_app_test_utils.cc
@@ -282,12 +282,14 @@
     if (random.next_bool())
       icon.square_size_px = size;
 
-    int purpose = random.next_uint(3);
+    int purpose = random.next_uint(4);
     if (purpose == 0)
       icon.purpose = blink::mojom::ManifestImageResource_Purpose::ANY;
     if (purpose == 1)
       icon.purpose = blink::mojom::ManifestImageResource_Purpose::MASKABLE;
-    // if (purpose == 2), leave purpose unset. Should default to ANY.
+    if (purpose == 2)
+      icon.purpose = blink::mojom::ManifestImageResource_Purpose::MONOCHROME;
+    // if (purpose == 3), leave purpose unset. Should default to ANY.
 
     icon_infos[i] = icon;
   }
@@ -296,6 +298,8 @@
     app->SetDownloadedIconSizes(IconPurpose::ANY, {size});
   if (random.next_bool())
     app->SetDownloadedIconSizes(IconPurpose::MASKABLE, {size});
+  if (random.next_bool())
+    app->SetDownloadedIconSizes(IconPurpose::MONOCHROME, {size});
   app->SetIsGeneratedIcon(random.next_bool());
 
   app->SetFileHandlers(CreateRandomFileHandlers(random.next_uint()));
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc
index 9b127af5..40626c4 100644
--- a/chrome/browser/web_applications/web_app.cc
+++ b/chrome/browser/web_applications/web_app.cc
@@ -48,8 +48,6 @@
     case IconPurpose::ANY:
       return downloaded_icon_sizes_any_;
     case IconPurpose::MONOCHROME:
-      // TODO (crbug.com/1114638): Download monochrome icons.
-      NOTREACHED();
       return downloaded_icon_sizes_monochrome_;
     case IconPurpose::MASKABLE:
       return downloaded_icon_sizes_maskable_;
@@ -216,8 +214,7 @@
       downloaded_icon_sizes_any_ = std::move(sizes);
       break;
     case IconPurpose::MONOCHROME:
-      // TODO (crbug.com/1114638): Add monochrome icons support.
-      NOTREACHED();
+      downloaded_icon_sizes_monochrome_ = std::move(sizes);
       break;
     case IconPurpose::MASKABLE:
       downloaded_icon_sizes_maskable_ = std::move(sizes);
diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h
index 8bcc9bce..03b34f3a 100644
--- a/chrome/browser/web_applications/web_app.h
+++ b/chrome/browser/web_applications/web_app.h
@@ -291,7 +291,6 @@
   bool is_uninstalling_ = false;
   std::vector<WebApplicationIconInfo> icon_infos_;
   SortedSizesPx downloaded_icon_sizes_any_;
-  // TODO (crbug.com/1114638): Monochrome icons are not currently downloaded.
   SortedSizesPx downloaded_icon_sizes_monochrome_;
   SortedSizesPx downloaded_icon_sizes_maskable_;
   bool is_generated_icon_ = false;
diff --git a/chrome/browser/web_applications/web_app_database.cc b/chrome/browser/web_applications/web_app_database.cc
index 201f5f3b..5233a9ea 100644
--- a/chrome/browser/web_applications/web_app_database.cc
+++ b/chrome/browser/web_applications/web_app_database.cc
@@ -256,6 +256,10 @@
        web_app.downloaded_icon_sizes(IconPurpose::MASKABLE)) {
     local_data->add_downloaded_icon_sizes_purpose_maskable(size);
   }
+  for (SquareSizePx size :
+       web_app.downloaded_icon_sizes(IconPurpose::MONOCHROME)) {
+    local_data->add_downloaded_icon_sizes_purpose_monochrome(size);
+  }
 
   local_data->set_is_generated_icon(web_app.is_generated_icon());
 
@@ -560,6 +564,12 @@
   web_app->SetDownloadedIconSizes(
       IconPurpose::MASKABLE, SortedSizesPx(std::move(icon_sizes_maskable)));
 
+  std::vector<SquareSizePx> icon_sizes_monochrome;
+  for (int32_t size : local_data.downloaded_icon_sizes_purpose_monochrome())
+    icon_sizes_monochrome.push_back(size);
+  web_app->SetDownloadedIconSizes(
+      IconPurpose::MONOCHROME, SortedSizesPx(std::move(icon_sizes_monochrome)));
+
   web_app->SetIsGeneratedIcon(local_data.is_generated_icon());
 
   apps::FileHandlers file_handlers;
diff --git a/chrome/browser/web_applications/web_app_database_unittest.cc b/chrome/browser/web_applications/web_app_database_unittest.cc
index 16be832..8116e7f 100644
--- a/chrome/browser/web_applications/web_app_database_unittest.cc
+++ b/chrome/browser/web_applications/web_app_database_unittest.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
+#include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/proto/web_app.pb.h"
 #include "chrome/browser/web_applications/test/test_web_app_database_factory.h"
 #include "chrome/browser/web_applications/test/test_web_app_registry_controller.h"
@@ -302,6 +303,7 @@
   EXPECT_TRUE(app->icon_infos().empty());
   EXPECT_TRUE(app->downloaded_icon_sizes(IconPurpose::ANY).empty());
   EXPECT_TRUE(app->downloaded_icon_sizes(IconPurpose::MASKABLE).empty());
+  EXPECT_TRUE(app->downloaded_icon_sizes(IconPurpose::MONOCHROME).empty());
   EXPECT_FALSE(app->is_generated_icon());
   EXPECT_FALSE(app->is_in_sync_install());
   EXPECT_TRUE(app->sync_fallback_data().name.empty());
@@ -365,6 +367,7 @@
   EXPECT_TRUE(app_copy->icon_infos().empty());
   EXPECT_TRUE(app_copy->downloaded_icon_sizes(IconPurpose::ANY).empty());
   EXPECT_TRUE(app_copy->downloaded_icon_sizes(IconPurpose::MASKABLE).empty());
+  EXPECT_TRUE(app_copy->downloaded_icon_sizes(IconPurpose::MONOCHROME).empty());
   EXPECT_FALSE(app_copy->is_generated_icon());
   EXPECT_FALSE(app_copy->is_in_sync_install());
   EXPECT_TRUE(app_copy->sync_fallback_data().name.empty());
@@ -385,24 +388,40 @@
 TEST_F(WebAppDatabaseTest, WebAppWithManyIcons) {
   controller().Init();
 
-  const int num_icons = 32;
+  const int min_purpose_type = static_cast<int>(IconPurpose::kMinValue);
+  const int max_purpose_type = static_cast<int>(IconPurpose::kMaxValue);
+  const int num_icon_purpose_types = max_purpose_type - min_purpose_type + 1;
+
   const GURL base_url("https://example.com/path");
+  // A number of icons of each IconPurpose.
+  const int num_icons = 32;
 
   std::unique_ptr<WebApp> app = test::CreateRandomWebApp(base_url, /*seed=*/0);
   AppId app_id = app->app_id();
 
   std::vector<WebApplicationIconInfo> icons;
-  std::vector<SquareSizePx> sizes;
-  for (int i = 1; i <= num_icons; ++i) {
-    WebApplicationIconInfo icon;
-    icon.url = base_url.Resolve("icon" + base::NumberToString(num_icons));
-    // Let size equals the icon's number squared.
-    icon.square_size_px = i * i;
-    sizes.push_back(*icon.square_size_px);
-    icons.push_back(std::move(icon));
+
+  std::vector<SquareSizePx> sizes[num_icon_purpose_types];
+
+  // Iterates over each icon purpose.
+  for (int p = min_purpose_type; p <= max_purpose_type; ++p) {
+    auto purpose = static_cast<IconPurpose>(p);
+
+    for (int i = 1; i <= num_icons; ++i) {
+      WebApplicationIconInfo icon;
+      icon.url = base_url.Resolve("icon" + base::NumberToString(num_icons));
+      // Let size equals the icon's number squared.
+      icon.square_size_px = i * i;
+
+      icon.purpose = purpose;
+      sizes[p].push_back(*icon.square_size_px);
+      icons.push_back(std::move(icon));
+    }
+
+    app->SetDownloadedIconSizes(purpose, std::move(sizes[p]));
   }
+
   app->SetIconInfos(std::move(icons));
-  app->SetDownloadedIconSizes(IconPurpose::ANY, std::move(sizes));
   app->SetIsGeneratedIcon(false);
 
   controller().RegisterApp(std::move(app));
@@ -411,7 +430,8 @@
   EXPECT_EQ(1UL, registry.size());
 
   std::unique_ptr<WebApp>& app_copy = registry.at(app_id);
-  EXPECT_EQ(static_cast<unsigned>(num_icons), app_copy->icon_infos().size());
+  EXPECT_EQ(static_cast<unsigned>(num_icons * num_icon_purpose_types),
+            app_copy->icon_infos().size());
   for (int i = 1; i <= num_icons; ++i) {
     const int icon_size_in_px = i * i;
     EXPECT_EQ(icon_size_in_px, app_copy->icon_infos()[i - 1].square_size_px);
diff --git a/chrome/browser/web_applications/web_app_icon_manager.cc b/chrome/browser/web_applications/web_app_icon_manager.cc
index 4642725..3bb74df8 100644
--- a/chrome/browser/web_applications/web_app_icon_manager.cc
+++ b/chrome/browser/web_applications/web_app_icon_manager.cc
@@ -20,6 +20,7 @@
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
+#include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/file_utils_wrapper.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
@@ -227,18 +228,15 @@
     return false;
   }
 
-  if (!WriteIcons(
-          utils.get(),
-          GetAppIconsDirectory(app_temp_dir.GetPath(), IconPurpose::ANY),
-          icon_bitmaps.any)) {
-    return false;
-  }
-  // TODO (crbug.com/1114638): Write Monochrome icons here.
-  if (!WriteIcons(
-          utils.get(),
-          GetAppIconsDirectory(app_temp_dir.GetPath(), IconPurpose::MASKABLE),
-          icon_bitmaps.maskable)) {
-    return false;
+  // Iterates over each icon purpose.
+  for (int p = static_cast<int>(IconPurpose::kMinValue);
+       p <= static_cast<int>(IconPurpose::kMaxValue); ++p) {
+    auto purpose = static_cast<IconPurpose>(p);
+    if (!WriteIcons(utils.get(),
+                    GetAppIconsDirectory(app_temp_dir.GetPath(), purpose),
+                    icon_bitmaps.GetBitmapsForPurpose(purpose))) {
+      return false;
+    }
   }
 
   base::FilePath manifest_resources_directory =
diff --git a/chrome/browser/web_applications/web_app_icon_manager_unittest.cc b/chrome/browser/web_applications/web_app_icon_manager_unittest.cc
index 5f1abc8..fa8dad3c 100644
--- a/chrome/browser/web_applications/web_app_icon_manager_unittest.cc
+++ b/chrome/browser/web_applications/web_app_icon_manager_unittest.cc
@@ -64,25 +64,26 @@
   }
 
  protected:
-  void WriteIcons(const AppId& app_id,
-                  const std::vector<IconPurpose>& purposes,
-                  const std::vector<int>& sizes_px,
-                  const std::vector<SkColor>& colors) {
-    DCHECK_EQ(sizes_px.size(), colors.size());
-    DCHECK(!purposes.empty());
+  struct GeneratedIconsInfo {
+    IconPurpose purpose;
+    std::vector<SquareSizePx> sizes_px;
+    std::vector<SkColor> colors;
+  };
 
+  void WriteGeneratedIcons(const AppId& app_id,
+                           const std::vector<GeneratedIconsInfo>& icons_info) {
     IconBitmaps icon_bitmaps;
-    for (size_t i = 0; i < sizes_px.size(); ++i) {
-      std::string icon_name = base::StringPrintf("app-%d.ico", sizes_px[i]);
-      if (base::Contains(purposes, IconPurpose::ANY)) {
-        AddGeneratedIcon(&icon_bitmaps.any, sizes_px[i], colors[i]);
-      }
-      if (base::Contains(purposes, IconPurpose::MASKABLE)) {
-        AddGeneratedIcon(&icon_bitmaps.maskable, sizes_px[i], colors[i]);
-      }
-      if (base::Contains(purposes, IconPurpose::MONOCHROME))
-        // TODO (crbug.com/1114638): Monochrome icon support.
-        NOTREACHED();
+
+    for (const GeneratedIconsInfo& info : icons_info) {
+      DCHECK_EQ(info.sizes_px.size(), info.colors.size());
+
+      std::map<SquareSizePx, SkBitmap> generated_bitmaps;
+
+      for (size_t i = 0; i < info.sizes_px.size(); ++i)
+        AddGeneratedIcon(&generated_bitmaps, info.sizes_px[i], info.colors[i]);
+
+      icon_bitmaps.SetBitmapsForPurpose(info.purpose,
+                                        std::move(generated_bitmaps));
     }
 
     base::RunLoop run_loop;
@@ -318,7 +319,7 @@
 
   const std::vector<int> sizes_px{icon_size::k256, icon_size::k512};
   const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorYELLOW};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
@@ -357,7 +358,7 @@
 
   const std::vector<int> sizes_px{icon_size::k256, icon_size::k512};
   const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorYELLOW};
-  WriteIcons(app_id, {IconPurpose::MASKABLE}, sizes_px, colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::MASKABLE, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, sizes_px);
 
@@ -389,14 +390,55 @@
   }
 }
 
+TEST_F(WebAppIconManagerTest, WriteAndReadIcons_MonochromeOnly) {
+  auto web_app = CreateWebApp();
+  const AppId app_id = web_app->app_id();
+
+  const std::vector<int> sizes_px{icon_size::k128, icon_size::k256};
+  const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorTRANSPARENT};
+  WriteGeneratedIcons(app_id, {{IconPurpose::MONOCHROME, sizes_px, colors}});
+
+  web_app->SetDownloadedIconSizes(IconPurpose::MONOCHROME, sizes_px);
+
+  controller().RegisterApp(std::move(web_app));
+
+  EXPECT_FALSE(icon_manager().HasIcons(app_id, IconPurpose::ANY, sizes_px));
+  EXPECT_FALSE(
+      icon_manager().HasIcons(app_id, IconPurpose::MASKABLE, sizes_px));
+  EXPECT_TRUE(
+      icon_manager().HasIcons(app_id, IconPurpose::MONOCHROME, sizes_px));
+  {
+    base::RunLoop run_loop;
+
+    icon_manager().ReadIcons(
+        app_id, IconPurpose::MONOCHROME, sizes_px,
+        base::BindLambdaForTesting(
+            [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) {
+              EXPECT_EQ(2u, icon_bitmaps.size());
+
+              EXPECT_FALSE(icon_bitmaps[icon_size::k128].empty());
+              EXPECT_EQ(SK_ColorGREEN,
+                        icon_bitmaps[icon_size::k128].getColor(0, 0));
+
+              EXPECT_FALSE(icon_bitmaps[icon_size::k256].empty());
+              EXPECT_EQ(SK_ColorTRANSPARENT,
+                        icon_bitmaps[icon_size::k256].getColor(0, 0));
+
+              run_loop.Quit();
+            }));
+
+    run_loop.Run();
+  }
+}
+
 TEST_F(WebAppIconManagerTest, WriteAndReadIcons_AnyAndMaskable) {
   auto web_app = CreateWebApp();
   const AppId app_id = web_app->app_id();
 
   const std::vector<int> sizes_px{icon_size::k256, icon_size::k512};
   const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorYELLOW};
-  WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px,
-             colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors},
+                               {IconPurpose::MASKABLE, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
   web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, sizes_px);
@@ -451,6 +493,76 @@
   }
 }
 
+TEST_F(WebAppIconManagerTest, WriteAndReadIcons_AnyAndMonochrome) {
+  auto web_app = CreateWebApp();
+  const AppId app_id = web_app->app_id();
+
+  const std::vector<int> sizes_px_any{icon_size::k256, icon_size::k512};
+  const std::vector<SkColor> colors_any{SK_ColorGREEN, SK_ColorYELLOW};
+
+  const std::vector<int> sizes_px_monochrome{icon_size::k64, icon_size::k128};
+  const std::vector<SkColor> colors_monochrome{SK_ColorRED, SK_ColorBLUE};
+
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px_any, colors_any},
+                               {IconPurpose::MONOCHROME, sizes_px_monochrome,
+                                colors_monochrome}});
+
+  web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px_any);
+  web_app->SetDownloadedIconSizes(IconPurpose::MONOCHROME, sizes_px_monochrome);
+
+  controller().RegisterApp(std::move(web_app));
+
+  EXPECT_TRUE(icon_manager().HasIcons(app_id, IconPurpose::ANY, sizes_px_any));
+  EXPECT_FALSE(icon_manager().HasIcons(app_id, IconPurpose::MASKABLE,
+                                       sizes_px_monochrome));
+  {
+    base::RunLoop run_loop;
+
+    icon_manager().ReadIcons(
+        app_id, IconPurpose::ANY, sizes_px_any,
+        base::BindLambdaForTesting(
+            [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) {
+              EXPECT_EQ(2u, icon_bitmaps.size());
+
+              EXPECT_FALSE(icon_bitmaps[icon_size::k256].empty());
+              EXPECT_EQ(SK_ColorGREEN,
+                        icon_bitmaps[icon_size::k256].getColor(0, 0));
+
+              EXPECT_FALSE(icon_bitmaps[icon_size::k512].empty());
+              EXPECT_EQ(SK_ColorYELLOW,
+                        icon_bitmaps[icon_size::k512].getColor(0, 0));
+
+              run_loop.Quit();
+            }));
+
+    run_loop.Run();
+  }
+  EXPECT_TRUE(icon_manager().HasIcons(app_id, IconPurpose::MONOCHROME,
+                                      sizes_px_monochrome));
+  {
+    base::RunLoop run_loop;
+
+    icon_manager().ReadIcons(
+        app_id, IconPurpose::MONOCHROME, sizes_px_monochrome,
+        base::BindLambdaForTesting(
+            [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) {
+              EXPECT_EQ(2u, icon_bitmaps.size());
+
+              EXPECT_FALSE(icon_bitmaps[icon_size::k64].empty());
+              EXPECT_EQ(SK_ColorRED,
+                        icon_bitmaps[icon_size::k64].getColor(0, 0));
+
+              EXPECT_FALSE(icon_bitmaps[icon_size::k128].empty());
+              EXPECT_EQ(SK_ColorBLUE,
+                        icon_bitmaps[icon_size::k128].getColor(0, 0));
+
+              run_loop.Quit();
+            }));
+
+    run_loop.Run();
+  }
+}
+
 TEST_F(WebAppIconManagerTest, OverwriteIcons) {
   auto web_app = CreateWebApp();
   const AppId app_id = web_app->app_id();
@@ -459,8 +571,8 @@
   {
     std::vector<int> sizes_px{icon_size::k32, icon_size::k64, icon_size::k48};
     const std::vector<SkColor> colors{SK_ColorRED, SK_ColorRED, SK_ColorRED};
-    WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px,
-               colors);
+    WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors},
+                                 {IconPurpose::MASKABLE, sizes_px, colors}});
 
     web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
     web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, std::move(sizes_px));
@@ -553,7 +665,7 @@
 
   const std::vector<int> sizes_px{icon_size::k256, icon_size::k512};
   const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorYELLOW};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
@@ -581,8 +693,8 @@
 
   const std::vector<int> sizes_px{icon_size::k256, icon_size::k512};
   const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorYELLOW};
-  WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px,
-             colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors},
+                               {IconPurpose::MASKABLE, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
   web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, sizes_px);
@@ -742,7 +854,7 @@
   const std::vector<int> sizes_px{10, 60, 50, 20, 30};
   const std::vector<SkColor> colors{SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN,
                                     SK_ColorBLUE, SK_ColorMAGENTA};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
@@ -782,8 +894,8 @@
   const std::vector<int> sizes_px{10, 60, 50, 20, 30};
   const std::vector<SkColor> colors{SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN,
                                     SK_ColorBLUE, SK_ColorMAGENTA};
-  WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px,
-             colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors},
+                               {IconPurpose::MASKABLE, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
   // Pretend we only have one size of maskable icon.
@@ -864,10 +976,10 @@
 
   const std::vector<int> sizes_px{icon_size::k128};
   const std::vector<SkColor> colors{SK_ColorMAGENTA};
-  WriteIcons(app1_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px,
-             colors);
-  WriteIcons(app2_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px,
-             colors);
+  WriteGeneratedIcons(app1_id, {{IconPurpose::ANY, sizes_px, colors},
+                                {IconPurpose::MASKABLE, sizes_px, colors}});
+  WriteGeneratedIcons(app2_id, {{IconPurpose::ANY, sizes_px, colors},
+                                {IconPurpose::MASKABLE, sizes_px, colors}});
 
   const base::FilePath web_apps_root_directory =
       GetWebAppsRootDirectory(profile());
@@ -920,7 +1032,7 @@
 
   const std::vector<int> sizes_px{icon_size::k128};
   const std::vector<SkColor> colors{SK_ColorGREEN};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
@@ -952,8 +1064,8 @@
 
   const std::vector<int> sizes_px{icon_size::k64, icon_size::k128};
   const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorGREEN};
-  WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px,
-             colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors},
+                               {IconPurpose::MASKABLE, sizes_px, colors}});
 
   int size_smaller = icon_size::k64;
   int size_larger = icon_size::k128;
@@ -1053,7 +1165,7 @@
                                   icon_size::k256, icon_size::k512};
   const std::vector<SkColor> colors{SK_ColorBLUE, SK_ColorGREEN, SK_ColorYELLOW,
                                     SK_ColorRED};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
@@ -1090,8 +1202,8 @@
                                   icon_size::k256, icon_size::k512};
   const std::vector<SkColor> colors{SK_ColorBLUE, SK_ColorGREEN, SK_ColorYELLOW,
                                     SK_ColorRED};
-  WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px,
-             colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors},
+                               {IconPurpose::MASKABLE, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
   web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, sizes_px);
@@ -1168,7 +1280,7 @@
 
   const std::vector<int> sizes_px{gfx::kFaviconSize, icon_size::k48};
   const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorRED};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
@@ -1191,7 +1303,7 @@
   const std::vector<int> sizes_px{8, icon_size::k48, icon_size::k64};
   ASSERT_FALSE(base::Contains(sizes_px, gfx::kFaviconSize));
   const std::vector<SkColor> colors{SK_ColorBLACK, SK_ColorGREEN, SK_ColorRED};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
@@ -1215,7 +1327,7 @@
 
   const std::vector<int> sizes_px{gfx::kFaviconSize, icon_size::k48};
   const std::vector<SkColor> colors{SK_ColorBLUE, SK_ColorRED};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
@@ -1251,7 +1363,7 @@
   ASSERT_TRUE(base::Contains(sizes_px, gfx::kFaviconSize));
 
   const std::vector<SkColor> colors{SK_ColorYELLOW, SK_ColorGREEN, SK_ColorRED};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
@@ -1293,7 +1405,7 @@
   ASSERT_FALSE(base::Contains(sizes_px, gfx::kFaviconSize));
 
   const std::vector<SkColor> colors{SK_ColorCYAN, SK_ColorMAGENTA};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors);
+  WriteGeneratedIcons(app_id, {{IconPurpose::ANY, sizes_px, colors}});
 
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
@@ -1339,7 +1451,8 @@
 
   // App declares only smaller icon and implementations ignore it: no upsizing.
   const std::vector<int> sizes_px{icon_size::k16};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, /*colors=*/{SK_ColorRED});
+  WriteGeneratedIcons(app_id,
+                      {{IconPurpose::ANY, sizes_px, /*colors=*/{SK_ColorRED}}});
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
   controller().RegisterApp(std::move(web_app));
@@ -1359,7 +1472,8 @@
 
   // App declares only one jumbo icon.
   const std::vector<int> sizes_px{icon_size::k512};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, /*colors=*/{SK_ColorLTGRAY});
+  WriteGeneratedIcons(
+      app_id, {{IconPurpose::ANY, sizes_px, /*colors=*/{SK_ColorLTGRAY}}});
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
   controller().RegisterApp(std::move(web_app));
@@ -1392,7 +1506,8 @@
 
   // App declares the icon which is ok for 100P but small for 300P.
   const std::vector<int> sizes_px{icon_size::k32};
-  WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, /*colors=*/{SK_ColorDKGRAY});
+  WriteGeneratedIcons(
+      app_id, {{IconPurpose::ANY, sizes_px, /*colors=*/{SK_ColorDKGRAY}}});
   web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px);
 
   controller().RegisterApp(std::move(web_app));
diff --git a/chrome/browser/web_applications/web_app_installation_utils.cc b/chrome/browser/web_applications/web_app_installation_utils.cc
index d97866f..156695d6 100644
--- a/chrome/browser/web_applications/web_app_installation_utils.cc
+++ b/chrome/browser/web_applications/web_app_installation_utils.cc
@@ -137,10 +137,12 @@
   web_app.SetIconInfos(web_app_info.icon_infos);
   web_app.SetDownloadedIconSizes(
       IconPurpose::ANY, GetSquareSizePxs(web_app_info.icon_bitmaps.any));
-  // TODO (crbug.com/1114638): Add monochrome icons support.
   web_app.SetDownloadedIconSizes(
       IconPurpose::MASKABLE,
       GetSquareSizePxs(web_app_info.icon_bitmaps.maskable));
+  web_app.SetDownloadedIconSizes(
+      IconPurpose::MONOCHROME,
+      GetSquareSizePxs(web_app_info.icon_bitmaps.monochrome));
   web_app.SetIsGeneratedIcon(web_app_info.is_generated_icon);
 
   web_app.SetShortcutsMenuItemInfos(web_app_info.shortcuts_menu_item_infos);
diff --git a/chrome/browser/web_applications/web_app_proto_utils.cc b/chrome/browser/web_applications/web_app_proto_utils.cc
index 1c2a65c..21bfbcef 100644
--- a/chrome/browser/web_applications/web_app_proto_utils.cc
+++ b/chrome/browser/web_applications/web_app_proto_utils.cc
@@ -21,6 +21,8 @@
       return blink::mojom::ManifestImageResource_Purpose::ANY;
     case sync_pb::WebAppIconInfo_Purpose_MASKABLE:
       return blink::mojom::ManifestImageResource_Purpose::MASKABLE;
+    case sync_pb::WebAppIconInfo_Purpose_MONOCHROME:
+      return blink::mojom::ManifestImageResource_Purpose::MONOCHROME;
   }
 }
 
@@ -30,9 +32,7 @@
     case blink::mojom::ManifestImageResource_Purpose::ANY:
       return sync_pb::WebAppIconInfo_Purpose_ANY;
     case blink::mojom::ManifestImageResource_Purpose::MONOCHROME:
-      // Monochrome purpose icons are never stored in icon_info.
-      NOTREACHED();
-      return sync_pb::WebAppIconInfo_Purpose_UNSPECIFIED;
+      return sync_pb::WebAppIconInfo_Purpose_MONOCHROME;
     case blink::mojom::ManifestImageResource_Purpose::MASKABLE:
       return sync_pb::WebAppIconInfo_Purpose_MASKABLE;
   }
diff --git a/chrome/browser/web_applications/web_app_unittest.cc b/chrome/browser/web_applications/web_app_unittest.cc
index 57fc66f..5a87277b 100644
--- a/chrome/browser/web_applications/web_app_unittest.cc
+++ b/chrome/browser/web_applications/web_app_unittest.cc
@@ -234,7 +234,7 @@
 last_badging_time: 1970-01-12 14:48:29.918 UTC
 last_launch_time: 1970-01-02 16:03:30.110 UTC
 install_time: 1970-01-09 06:11:52.363 UTC
-is_generated_icon: 1
+is_generated_icon: 0
 run_on_os_login_mode: minimized
 icon_infos:
   url: https://example.com/icon1783899413
@@ -244,7 +244,7 @@
     square_size_px: none
     purpose: ANY
 downloaded_icon_sizes_any: 256
-downloaded_icon_sizes_monochrome:
+downloaded_icon_sizes_monochrome: 256
 downloaded_icon_sizes_maskable:
 shortcuts_menu_item_infos:
   name: shortcut24741963851
@@ -278,53 +278,44 @@
     any: 232 77
     maskable: 113 154
 file_handlers:
-  action: https://example.com/open-33849121400
+  action: https://example.com/open-13087720410
     accept:
-      mime_type: application/33849121400+foo
-      file_extensions: .33849121400a .33849121400b
+      mime_type: application/13087720410+foo
+      file_extensions: .13087720410a .13087720410b
     accept:
-      mime_type: application/33849121400+bar
-      file_extensions: .33849121400a .33849121400b
-  action: https://example.com/open-33849121401
+      mime_type: application/13087720410+bar
+      file_extensions: .13087720410a .13087720410b
+  action: https://example.com/open-13087720411
     accept:
-      mime_type: application/33849121401+foo
-      file_extensions: .33849121401a .33849121401b
+      mime_type: application/13087720411+foo
+      file_extensions: .13087720411a .13087720411b
     accept:
-      mime_type: application/33849121401+bar
-      file_extensions: .33849121401a .33849121401b
-  action: https://example.com/open-33849121402
+      mime_type: application/13087720411+bar
+      file_extensions: .13087720411a .13087720411b
+  action: https://example.com/open-13087720412
     accept:
-      mime_type: application/33849121402+foo
-      file_extensions: .33849121402a .33849121402b
+      mime_type: application/13087720412+foo
+      file_extensions: .13087720412a .13087720412b
     accept:
-      mime_type: application/33849121402+bar
-      file_extensions: .33849121402a .33849121402b
-  action: https://example.com/open-33849121403
+      mime_type: application/13087720412+bar
+      file_extensions: .13087720412a .13087720412b
+  action: https://example.com/open-13087720413
     accept:
-      mime_type: application/33849121403+foo
-      file_extensions: .33849121403a .33849121403b
+      mime_type: application/13087720413+foo
+      file_extensions: .13087720413a .13087720413b
     accept:
-      mime_type: application/33849121403+bar
-      file_extensions: .33849121403a .33849121403b
-  action: https://example.com/open-33849121404
+      mime_type: application/13087720413+bar
+      file_extensions: .13087720413a .13087720413b
+  action: https://example.com/open-13087720414
     accept:
-      mime_type: application/33849121404+foo
-      file_extensions: .33849121404a .33849121404b
+      mime_type: application/13087720414+foo
+      file_extensions: .13087720414a .13087720414b
     accept:
-      mime_type: application/33849121404+bar
-      file_extensions: .33849121404a .33849121404b
+      mime_type: application/13087720414+bar
+      file_extensions: .13087720414a .13087720414b
 file_handler_permission_blocked:0
 share_target:
-  action: https://example.com/path/target/1210958276
-  method: POST
-  enctype: multipart/form-data
-  title: title1210958276
-  text: text1210958276
-  url: 
-  files:
-    name: files0
-      accept: .extension0
-      accept: type/subtype0
+  nullopt
 additional_search_terms:
   Foo_1234_0
   Foo_1234_1
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 431d57c2..ebaa771 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-master-1620939486-fdd70b8b1eac79789487b1f6bfb9d285d39b62c5.profdata
+chrome-win32-master-1620961007-adb1d95a6a0b4e2104986f5e493180762c515a65.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index ae24a15..62172c8a 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-master-1620916330-4bc846cd76be8e976b4e4584e2cbac2319528d52.profdata
+chrome-win64-master-1620961007-4de31d546757061b5408c87d8e8c990868445ee3.profdata
diff --git a/chrome/common/extensions/api/file_manager_private.idl b/chrome/common/extensions/api/file_manager_private.idl
index 0919eb5..6ba1bc8d 100644
--- a/chrome/common/extensions/api/file_manager_private.idl
+++ b/chrome/common/extensions/api/file_manager_private.idl
@@ -60,21 +60,37 @@
 // File transfer progress state.
 enum TransferState { in_progress, completed, failed };
 
-// The type of the progress event.
-enum CopyProgressStatusType {
-  // "begin_copy_entry" is fired for each entry (file or directory) before
-  // starting the copy operation.
-  begin_copy_entry,
+// The type of the progress event for copy or move operations.
+// A copy or a cross-filesystem move happens recursively: these events are
+// expected for each single entry (file or directory) being moved.
+// A local (same-filesystem) move only requires the top-level entries to be
+// renamed: if we move entries 'a.txt', 'b/c.txt', 'b/d.txt' (relative paths),
+// events will be received for only for 'a.txt' and 'b'.
+enum CopyOrMoveProgressStatusType {
+  // "begin" is fired for each entry (file or directory) before
+  // starting the copy or move operation.
+  begin,
 
-  // "end_copy_entry" is fired for each entry (file or directory) after ending
-  // the copy operation.
-  end_copy_entry,
-
-  // "progress" is fired periodically to report progress of a file copy (not
-  // directory).
+  // "progress" is fired periodically to report progress of a file copy or move
+  // (not directory).
   progress,
 
-  // "success" is fired after all entries are copied.
+  // "end_copy" is fired for each entry (file or directory) that has been
+  // successfully copied to its destination. This event is expected both both
+  // copies and cross-filesystem moves (implemented as copy + delete).
+  end_copy,
+
+  // "end_move" is fired for each entry (file or directory) that has been
+  // successfully moved to its destination, in the case of a "same-filesystem"
+  // move.
+  end_move,
+
+  // "end_remove_source" is fired for each entry (file or directory) that has
+  // been successfully removed from its source location as part of a
+  // "cross-filesystem" move operation.
+  end_remove_source,
+
+  // "success" is fired after all entries have been copied or moved.
   success,
 
   // "error" is fired when an error occurs.
@@ -575,10 +591,10 @@
   DOMString fileUrl;
 };
 
-// Payload data for copy status progress updates.
-dictionary CopyProgressStatus {
+// Payload data for copy or move status progress updates.
+dictionary CopyOrMoveProgressStatus {
   // The type of the progress event.
-  CopyProgressStatusType type;
+  CopyOrMoveProgressStatusType type;
 
   // URL for the entry currently being copied. This field is particularly useful
   // when a directory copy is initiated with startCopy(). The field tells what
@@ -1460,7 +1476,7 @@
 
   static void onPinTransfersUpdated(FileTransferStatus event);
 
-  static void onCopyProgress(long copyId, CopyProgressStatus status);
+  static void onCopyProgress(long copyId, CopyOrMoveProgressStatus status);
 
   static void onDirectoryChanged(FileWatchEvent event);
 
diff --git a/chrome/services/file_util/OWNERS b/chrome/services/file_util/OWNERS
new file mode 100644
index 0000000..4fd3847
--- /dev/null
+++ b/chrome/services/file_util/OWNERS
@@ -0,0 +1,3 @@
+# For the ZipFileCreator service
+fdegros@chromium.org
+noel@chromium.org
diff --git a/chrome/services/file_util/zip_file_creator.cc b/chrome/services/file_util/zip_file_creator.cc
index d05bd38b..5b775df 100644
--- a/chrome/services/file_util/zip_file_creator.cc
+++ b/chrome/services/file_util/zip_file_creator.cc
@@ -9,6 +9,7 @@
 
 #include "base/files/file.h"
 #include "base/files/file_path.h"
+#include "base/logging.h"
 #include "components/services/filesystem/public/mojom/types.mojom-shared.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "third_party/zlib/google/zip.h"
@@ -167,7 +168,7 @@
     CreateZipFileCallback callback) {
   DCHECK(zip_file.IsValid());
 
-  for (const auto& path : source_relative_paths) {
+  for (const base::FilePath& path : source_relative_paths) {
     if (path.IsAbsolute() || path.ReferencesParent()) {
       // Paths are expected to be relative. If there are not, the API is used
       // incorrectly and this is an error.
@@ -176,11 +177,19 @@
     }
   }
 
-  zip::ZipParams zip_params(source_dir, zip_file.GetPlatformFile());
-  zip_params.set_files_to_zip(source_relative_paths);
-  zip_params.set_file_accessor(std::make_unique<MojoFileAccessor>(
-      source_dir, std::move(source_dir_remote)));
-  bool success = zip::Zip(zip_params);
+  MojoFileAccessor file_accessor(source_dir, std::move(source_dir_remote));
+  const bool success = zip::Zip({
+      .src_dir = source_dir,
+      .dest_fd = zip_file.GetPlatformFile(),
+      .src_files = source_relative_paths,
+      .progress_callback =
+          base::BindRepeating([](const zip::Progress& progress) {
+            VLOG(1) << "ZIP progress: " << progress;
+            return true;
+          }),
+      .progress_period = base::TimeDelta::FromMilliseconds(500),
+      .file_accessor = &file_accessor,
+  });
   std::move(callback).Run(success);
 }
 
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index e0bfb16..9ed76ca 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -338,7 +338,6 @@
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_about_page_tests.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_edit_dictionary_page_test.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_files_page_test.m.js",
-        "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_languages_page_tests.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_languages_page_v2_tests.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_settings_main_test.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_settings_ui_test.m.js",
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn b/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn
index 1d131b7a..9eede03 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn
+++ b/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn
@@ -13,6 +13,7 @@
                   ]
   deps = [
     ":fake_shimless_rma_service_test",
+    ":onboarding_update_page_test",
     ":shimless_rma_app_test",
     ":shimless_rma_unified_test",
   ]
@@ -34,6 +35,14 @@
   externs_list = [ "$externs_path/mocha-2.5.js" ]
 }
 
+js_library("onboarding_update_page_test") {
+  deps = [
+    "../..:chai_assert",
+    "//ash/content/shimless_rma/resources:onboarding_update_page",
+  ]
+  externs_list = [ "$externs_path/mocha-2.5.js" ]
+}
+
 js_library("shimless_rma_unified_test") {
   deps = []
   externs_list = [ "$externs_path/mocha-2.5.js" ]
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js
new file mode 100644
index 0000000..ea9536ff
--- /dev/null
+++ b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js
@@ -0,0 +1,140 @@
+// 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 {FakeShimlessRmaService} from 'chrome://shimless-rma/fake_shimless_rma_service.js';
+import {getShimlessRmaService, setShimlessRmaServiceForTesting} from 'chrome://shimless-rma/mojo_interface_provider.js';
+import {OnboardingUpdatePageElement} from 'chrome://shimless-rma/onboarding_update_page.js';
+
+import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
+import {flushTasks} from '../../test_util.m.js';
+
+export function onboardingUpdatePageTest() {
+  /** @type {?OnboardingUpdatePageElement} */
+  let component = null;
+
+  /** @type {?FakeShimlessRmaService} */
+  let service = null;
+
+  suiteSetup(() => {
+    service = new FakeShimlessRmaService();
+    setShimlessRmaServiceForTesting(service);
+  });
+
+  setup(() => {
+    document.body.innerHTML = '';
+  });
+
+  teardown(() => {
+    component.remove();
+    component = null;
+    service.reset();
+  });
+
+  /**
+   * @param {string} version
+   * @param {boolean} updateAvailable
+   * @return {!Promise}
+   */
+  function initializeUpdatePage(version, updateAvailable) {
+    assertFalse(!!component);
+
+    // Initialize the fake data.
+    service.setGetCurrentChromeVersionResult(version);
+    service.setCheckForChromeUpdatesResult(updateAvailable);
+
+    component = /** @type {!OnboardingUpdatePageElement} */ (
+        document.createElement('onboarding-update-page'));
+    assertTrue(!!component);
+    document.body.appendChild(component);
+
+    return flushTasks();
+  }
+
+  /**
+   * @return {!Promise}
+   */
+  function clickCheckUpdateBtn() {
+    const checkUpdateBtn = component.shadowRoot.querySelector('#checkUpdate');
+    checkUpdateBtn.click();
+    return flushTasks();
+  }
+
+  test('UpdatePageInitializes', () => {
+    const version = '90.1.2.3';
+    const update = false;
+
+    return initializeUpdatePage(version, update).then(() => {
+      const versionComponent =
+          component.shadowRoot.querySelector('#versionInfo');
+      const updateBtn = component.shadowRoot.querySelector('#performUpdate');
+      assertTrue(versionComponent.textContent.trim().indexOf(version) !== -1);
+      assertTrue(updateBtn.hidden);
+    });
+  });
+
+  test('UpdatePageNoNetwork', () => {
+    const version = '90.1.2.3';
+    const update = false;
+
+    return initializeUpdatePage(version, update)
+        .then(() => {
+          component.networkAvailable = false;
+          return flushTasks();
+        })
+        .then(() => {
+          const networkUnavailable =
+              component.shadowRoot.querySelector('#networkUnavailable');
+          const checkUpdateBtn =
+              component.shadowRoot.querySelector('#checkUpdate');
+
+          assertFalse(networkUnavailable.hidden);
+          assertTrue(checkUpdateBtn.hidden);
+        });
+  });
+
+  test('UpdatePageNoUpdates', () => {
+    const version = '90.1.2.3';
+    const update = false;
+
+    return initializeUpdatePage(version, update)
+        .then(() => {
+          component.networkAvailable = true;
+          return flushTasks();
+        })
+        .then(() => clickCheckUpdateBtn())
+        .then(() => {
+          const versionComponent =
+              component.shadowRoot.querySelector('#versionInfo');
+          // TODO(joonbug): update with i18n string
+          const uptoDateMsg = 'is up to date';
+          assertTrue(
+              versionComponent.textContent.trim().indexOf(uptoDateMsg) !== -1);
+        });
+  });
+
+  test('UpdatePageUpdatesAvailable', () => {
+    const version = '90.1.2.3';
+    const update = true;
+
+    return initializeUpdatePage(version, update)
+        .then(() => {
+          component.networkAvailable = true;
+          return flushTasks();
+        })
+        .then(() => clickCheckUpdateBtn())
+        .then(() => {
+          const versionComponent =
+              component.shadowRoot.querySelector('#versionInfo');
+          // TODO(joonbug): update with i18n string
+          const uptoDateMsg = 'is out of date';
+          assertTrue(
+              versionComponent.textContent.trim().indexOf(uptoDateMsg) !== -1);
+        })
+        .then(() => {
+          const updateBtn =
+              component.shadowRoot.querySelector('#performUpdate');
+          assertFalse(updateBtn.hidden);
+        });
+  });
+}
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.js b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.js
index f9b8b383..c35a95f7 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.js
+++ b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.js
@@ -41,6 +41,7 @@
 const debug_suites_list = [
   'FakeShimlessRmaServiceTestSuite',
   'ShimlessRMAAppTest',
+  'OnboardingUpdatePageTest',
 ];
 
 TEST_F('ShimlessRMABrowserTest', 'All', function() {
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_unified_test.js b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_unified_test.js
index 454dc4af..c5fd49b8 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_unified_test.js
+++ b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_unified_test.js
@@ -5,6 +5,7 @@
 import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
 
 import {fakeShimlessRmaServiceTestSuite} from './fake_shimless_rma_service_test.js';
+import {onboardingUpdatePageTest} from './onboarding_update_page_test.js';
 import {shimlessRMAAppTest} from './shimless_rma_app_test.js';
 
 window.test_suites_list = [];
@@ -16,3 +17,4 @@
 
 runSuite('FakeShimlessRmaServiceTestSuite', fakeShimlessRmaServiceTestSuite);
 runSuite('ShimlessRMAAppTest', shimlessRMAAppTest);
+runSuite('OnboardingUpdatePageTest', onboardingUpdatePageTest);
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn
index 1f594a3..282b4d6 100644
--- a/chrome/test/data/webui/settings/BUILD.gn
+++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -67,7 +67,6 @@
     #":import_data_dialog_test",
     #":incompatible_applications_page_test",
     ":languages_page_metrics_test_browser",
-    ":languages_page_metrics_test_cros",
 
     #":languages_page_tests",
     #":languages_subpage_tests",
@@ -245,20 +244,6 @@
   ]
 }
 
-js_library("languages_page_metrics_test_cros") {
-  deps = [
-    ":fake_language_settings_private",
-    ":fake_settings_private",
-    ":test_languages_browser_proxy",
-    ":test_languages_metrics_proxy",
-    "..:chai_assert",
-    "..:test_util.m",
-    "//chrome/browser/resources/settings:lazy_load",
-    "//chrome/browser/resources/settings:settings",
-  ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
-}
-
 js_library("languages_page_metrics_test_browser") {
   deps = [
     ":fake_language_settings_private",
diff --git a/chrome/test/data/webui/settings/basic_page_test.js b/chrome/test/data/webui/settings/basic_page_test.js
index 15c52119..7f57821c 100644
--- a/chrome/test/data/webui/settings/basic_page_test.js
+++ b/chrome/test/data/webui/settings/basic_page_test.js
@@ -11,7 +11,7 @@
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {loadTimeData, pageVisibility, Router, routes} from 'chrome://settings/settings.js';
 
-import {flushTasks, isVisible} from '../test_util.m.js';
+import {eventToPromise, flushTasks, isVisible} from '../test_util.m.js';
 // clang-format on
 
 // Register mocha tests.
@@ -60,11 +60,35 @@
 suite('SettingsBasicPageRedesign', () => {
   let page = null;
 
-  setup(function() {
+  suiteSetup(function() {
+    assertTrue(loadTimeData.getBoolean('enableLandingPageRedesign'));
+    const attribute =
+        loadTimeData.getString('enableLandingPageRedesignAttribute');
+    assertEquals('enable-landing-page-redesign', attribute);
+
+    // Do this manually as it is normally part of settings.html, which is not
+    // part of this test.
+    document.documentElement.toggleAttribute(attribute, true);
+  });
+
+  setup(async function() {
     PolymerTest.clearBody();
     page = document.createElement('settings-basic-page');
     document.body.appendChild(page);
     page.scroller = document.body;
+
+    // Need to wait for the 'show-container' event to fire after every
+    // transition, to ensure no logic related to previous transitions is still
+    // running when later transitions are tested.
+    const whenDone = eventToPromise('show-container', page);
+
+    // Ensure that all settings-section instances are rendered.
+    flush();
+    await page.$$('#advancedPageTemplate').get();
+    const sections = page.shadowRoot.querySelectorAll('settings-section');
+    assertTrue(sections.length > 1);
+
+    await whenDone;
   });
 
   /** @param {string} section */
@@ -81,22 +105,6 @@
   }
 
   test('OnlyOneSectionShown', async () => {
-    assertTrue(loadTimeData.getBoolean('enableLandingPageRedesign'));
-    const attribute =
-        loadTimeData.getString('enableLandingPageRedesignAttribute');
-    assertEquals('enable-landing-page-redesign', attribute);
-
-
-    // Do this manually as it is normally part of settings.html, which is not
-    // part of this test.
-    document.documentElement.toggleAttribute(attribute, true);
-
-    // Ensure that all settings-section instances are rendered.
-    flush();
-    await page.$$('#advancedPageTemplate').get();
-    const sections = page.shadowRoot.querySelectorAll('settings-section');
-    assertTrue(sections.length > 1);
-
     // RouteState.INITIAL -> RoutState.TOP_LEVEL
     // Check that only one is marked as |active|.
     assertActiveSection(routes.PEOPLE.section);
@@ -105,7 +113,9 @@
 
     // RouteState.TOP_LEVEL -> RoutState.SECTION
     // Check that navigating to a different route correctly updates the page.
+    let whenDone = eventToPromise('show-container', page);
     Router.getInstance().navigateTo(routes.SEARCH);
+    await whenDone;
     await flushTasks();
     assertActiveSection(routes.SEARCH.section);
     assertTrue(!!page.shadowRoot.querySelector(
@@ -128,7 +138,9 @@
     }
 
     // RouteState.SECTION -> RoutState.SECTION
+    whenDone = eventToPromise('show-container', page);
     Router.getInstance().navigateTo(routes.APPEARANCE);
+    await whenDone;
     await flushTasks();
     assertActiveSection(routes.APPEARANCE.section);
     assertTrue(!!getCardElement());
@@ -136,7 +148,9 @@
     assertFalse(!!getSubpage());
 
     // RouteState.SECTION -> RoutState.SUBPAGE
+    whenDone = eventToPromise('show-container', page);
     Router.getInstance().navigateTo(routes.FONTS);
+    await whenDone;
     await flushTasks();
     assertActiveSection(routes.APPEARANCE.section);
     assertTrue(!!getCardElement());
@@ -144,7 +158,9 @@
     assertTrue(!!getSubpage());
 
     // RouteState.SUBPAGE -> RoutState.SECTION
+    whenDone = eventToPromise('show-container', page);
     Router.getInstance().navigateTo(routes.APPEARANCE);
+    await whenDone;
     await flushTasks();
     assertActiveSection(routes.APPEARANCE.section);
     assertTrue(!!getCardElement());
@@ -152,8 +168,29 @@
     assertFalse(!!getSubpage());
 
     // RouteState.SECTION -> RoutState.TOP_LEVEL
+    whenDone = eventToPromise('show-container', page);
     Router.getInstance().navigateTo(routes.BASIC);
+    await whenDone;
     await flushTasks();
     assertActiveSection(routes.PEOPLE.section);
   });
+
+  // Test cases where a settings-section is appearing next to another section
+  // using the |nest-under-section| attribute. Only one such case currently
+  // exists.
+  test('SometimesMoreSectionsShown', async () => {
+    const whenDone = eventToPromise('show-container', page);
+    Router.getInstance().navigateTo(routes.PRIVACY);
+    await whenDone;
+    await flushTasks();
+
+    const activeSections =
+        page.shadowRoot.querySelectorAll('settings-section[active]');
+    assertEquals(2, activeSections.length);
+    assertEquals(routes.SAFETY_CHECK.section, activeSections[0].section);
+    assertEquals(
+        routes.PRIVACY.section,
+        activeSections[0].getAttribute('nest-under-section'));
+    assertEquals(routes.PRIVACY.section, activeSections[1].section);
+  });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn
index c78df38..b95f5d881d 100644
--- a/chrome/test/data/webui/settings/chromeos/BUILD.gn
+++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -115,7 +115,6 @@
     "os_about_page_tests.js",
     "os_edit_dictionary_page_test.js",
     "os_files_page_test.js",
-    "os_languages_page_tests.js",
     "os_languages_page_v2_tests.js",
     "os_reset_page_test.js",
     "os_people_page_test.js",
diff --git a/chrome/test/data/webui/settings/chromeos/os_languages_page_tests.js b/chrome/test/data/webui/settings/chromeos/os_languages_page_tests.js
deleted file mode 100644
index cfeccf9..0000000
--- a/chrome/test/data/webui/settings/chromeos/os_languages_page_tests.js
+++ /dev/null
@@ -1,430 +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.
-
-// clang-format off
-// #import {LanguagesBrowserProxyImpl, LanguagesMetricsProxyImpl, LanguagesPageInteraction} from 'chrome://os-settings/chromeos/lazy_load.js';
-// #import {CrSettingsPrefs, Router, routes} from 'chrome://os-settings/chromeos/os_settings.js';
-// #import {assert} from 'chrome://resources/js/assert.m.js';
-// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-// #import {getFakeLanguagePrefs} from '../fake_language_settings_private.js'
-// #import {FakeSettingsPrivate} from '../fake_settings_private.js';
-// #import {TestLanguagesBrowserProxy} from './test_os_languages_browser_proxy.m.js';
-// #import {TestLanguagesMetricsProxy} from './test_os_languages_metrics_proxy.m.js';
-// #import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
-// #import {fakeDataBind} from '../../test_util.m.js';
-// #import {getDeepActiveElement} from 'chrome://resources/js/util.m.js';
-// #import {waitAfterNextRender} from 'chrome://test/test_util.m.js';
-// clang-format on
-
-// TODO(crbug/1109431): Remove these tests.
-cr.define('os_languages_page_tests', function() {
-  /** @enum {string} */
-  const TestNames = {
-    // The "add languages" dialog is tested by browser settings.
-    LanguageMenu: 'language menu',
-    InputMethods: 'input methods',
-    RecordMetrics: 'records metrics',
-    DetailsPage: 'details page',
-  };
-
-  suite('languages page', function() {
-    /** @type {?LanguageHelper} */
-    let languageHelper = null;
-    /** @type {?SettingsLanguagesPageElement} */
-    let languagesPage = null;
-    /** @type {?HTMLElement} */
-    let languagesList = null;
-    /** @type {?CrActionMenuElement} */
-    let actionMenu = null;
-    /** @type {?settings.LanguagesBrowserProxy} */
-    let browserProxy = null;
-    /** @type {!settings.LanguagesMetricsProxy} */
-    let metricsProxy;
-
-    // Enabled language pref name for the platform.
-    const languagesPref = 'settings.language.preferred_languages';
-
-    // Initial value of enabled languages pref used in tests.
-    const initialLanguages = 'en-US,sw';
-
-    suiteSetup(function() {
-      testing.Test.disableAnimationsAndTransitions();
-      PolymerTest.clearBody();
-      CrSettingsPrefs.deferInitialization = true;
-      loadTimeData.overrideValues({imeOptionsInSettings: true});
-    });
-
-    setup(async () => {
-      const settingsPrefs = document.createElement('settings-prefs');
-      const settingsPrivate =
-          new settings.FakeSettingsPrivate(settings.getFakeLanguagePrefs());
-      settingsPrefs.initialize(settingsPrivate);
-      document.body.appendChild(settingsPrefs);
-      await CrSettingsPrefs.initialized;
-      // Set up test browser proxy.
-      browserProxy = new settings.TestLanguagesBrowserProxy();
-      settings.LanguagesBrowserProxyImpl.instance_ = browserProxy;
-
-      // Sets up test metrics proxy.
-      metricsProxy = new settings.TestLanguagesMetricsProxy();
-      settings.LanguagesMetricsProxyImpl.instance_ = metricsProxy;
-
-      // Set up fake languageSettingsPrivate API.
-      const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate();
-      languageSettingsPrivate.setSettingsPrefs(settingsPrefs);
-
-      // Instantiate the data model with data bindings for prefs.
-      const settingsLanguages = document.createElement('settings-languages');
-      settingsLanguages.prefs = settingsPrefs.prefs;
-      test_util.fakeDataBind(settingsPrefs, settingsLanguages, 'prefs');
-      document.body.appendChild(settingsLanguages);
-
-      // Create page with data bindings for prefs and data model.
-      languagesPage = document.createElement('os-settings-languages-page');
-      languagesPage.prefs = settingsPrefs.prefs;
-      test_util.fakeDataBind(settingsPrefs, languagesPage, 'prefs');
-      languagesPage.languages = settingsLanguages.languages;
-      test_util.fakeDataBind(settingsLanguages, languagesPage, 'languages');
-      languagesPage.languageHelper = settingsLanguages.languageHelper;
-      test_util.fakeDataBind(
-          settingsLanguages, languagesPage, 'language-helper');
-      document.body.appendChild(languagesPage);
-
-      languagesList = languagesPage.$.languagesList;
-      actionMenu = languagesPage.$.menu.get();
-
-      languageHelper = languagesPage.languageHelper;
-      await languageHelper.whenReady();
-    });
-
-    teardown(function() {
-      PolymerTest.clearBody();
-      settings.Router.getInstance().resetRouteForTesting();
-    });
-
-    suite(TestNames.LanguageMenu, function() {
-      /*
-       * Finds, asserts and returns the menu item for the given i18n key.
-       * @param {string} i18nKey Name of the i18n string for the item's text.
-       * @return {!HTMLElement} Menu item.
-       */
-      function getMenuItem(i18nKey) {
-        const i18nString = assert(loadTimeData.getString(i18nKey));
-        const menuItems = actionMenu.querySelectorAll('.dropdown-item');
-        const menuItem = Array.from(menuItems).find(
-            item => item.textContent.trim() === i18nString);
-        return assert(menuItem, `Menu item "${i18nKey}" not found`);
-      }
-
-      /*
-       * Checks the visibility of each expected menu item button.
-       * param {!Object<boolean>} Dictionary from i18n keys to expected
-       *     visibility of those menu items.
-       */
-      function assertMenuItemButtonsVisible(buttonVisibility) {
-        assertTrue(actionMenu.open);
-        for (const buttonKey of Object.keys(buttonVisibility)) {
-          const buttonItem = getMenuItem(buttonKey);
-          assertEquals(
-              !buttonVisibility[buttonKey], buttonItem.hidden,
-              `Menu item "${buttonKey}" hidden`);
-        }
-      }
-
-      /**
-       * @return {HTMLElement} Traverses the DOM tree to find the lowest level
-       *     active element.
-       */
-      function getActiveElement() {
-        let node = document.activeElement;
-        let lastNode;
-        while (node) {
-          lastNode = node;
-          node = (node.shadowRoot || node).activeElement;
-        }
-        return lastNode;
-      }
-
-      /**
-       * Assert whether the 'restart' button should be active.
-       * @param {boolean} shouldBeActive True to assert that the 'restart'
-       *     button is present and active or false the assert the negation.
-       */
-      function assertRestartButtonActiveState(shouldBeActive) {
-        const activeElement = getActiveElement();
-        const isRestartButtonActive =
-            activeElement && (activeElement.id === 'restartButton');
-        assertEquals(isRestartButtonActive, shouldBeActive);
-      }
-
-      test('structure', function() {
-        const languageOptionsDropdownTrigger =
-            languagesList.querySelector('cr-icon-button');
-        assertTrue(!!languageOptionsDropdownTrigger);
-        languageOptionsDropdownTrigger.click();
-        assertTrue(actionMenu.open);
-
-        const separator = actionMenu.querySelector('hr');
-        assertEquals(1, separator.offsetHeight);
-      });
-
-      test('changing UI language', function() {
-        // Mock changing language.
-        languageHelper.setProspectiveUILanguage = languageCode => {
-          languagesPage.set('languages.prospectiveUILanguage', languageCode);
-        };
-
-        // Restart button is not active.
-        assertRestartButtonActiveState(false);
-
-        const swListItem = languagesList.querySelectorAll('.list-item')[1];
-        // Open options for 'sw'.
-        const languageOptionsDropdownTrigger =
-            swListItem.querySelector('cr-icon-button');
-        assertTrue(!!languageOptionsDropdownTrigger);
-        // No restart button in 'sw' list-item.
-        assertTrue(!swListItem.querySelector('#restartButton'));
-        languageOptionsDropdownTrigger.click();
-        assertTrue(actionMenu.open);
-
-        // OS language is not 'sw'
-        const uiLanguageOption = getMenuItem('displayInThisLanguage');
-        assertFalse(uiLanguageOption.disabled);
-        assertFalse(uiLanguageOption.checked);
-
-        return new Promise(resolve => {
-          actionMenu.addEventListener('close', () => {
-            // Restart button is attached to the first list item and is active.
-            const firstListItem =
-                languagesList.querySelectorAll('.list-item')[0];
-            const domRepeat = languagesList.querySelector('dom-repeat');
-            assertEquals(
-                'sw',
-                domRepeat.modelForElement(firstListItem).item.language.code);
-            assertTrue(!!firstListItem.querySelector('#restartButton'));
-            assertRestartButtonActiveState(true);
-            resolve();
-          });
-
-          // Change UI language.
-          uiLanguageOption.click();
-        });
-      });
-
-      test('remove language when starting with 3 languages', function() {
-        // Enable a language which we can then disable.
-        languageHelper.enableLanguage('no');
-
-        // Populate the dom-repeat.
-        Polymer.dom.flush();
-
-        // Find the new language item.
-        const items = languagesList.querySelectorAll('.list-item');
-        const domRepeat = assert(languagesList.querySelector('dom-repeat'));
-        const item = Array.from(items).find(function(el) {
-          return domRepeat.itemForElement(el) &&
-              domRepeat.itemForElement(el).language.code === 'no';
-        });
-
-        // Open the menu and select Remove.
-        item.querySelector('cr-icon-button').click();
-
-        assertTrue(actionMenu.open);
-        const removeMenuItem = getMenuItem('removeLanguage');
-        assertFalse(removeMenuItem.disabled);
-        assertFalse(removeMenuItem.hidden);
-        removeMenuItem.click();
-        assertFalse(actionMenu.open);
-
-        assertEquals(
-            initialLanguages, languageHelper.getPref(languagesPref).value);
-      });
-
-      test('remove language when starting with 2 languages', function() {
-        const items = languagesList.querySelectorAll('.list-item');
-        const domRepeat = assert(languagesList.querySelector('dom-repeat'));
-        const item = Array.from(items).find(function(el) {
-          return domRepeat.itemForElement(el) &&
-              domRepeat.itemForElement(el).language.code === 'sw';
-        });
-
-        // Open the menu and select Remove.
-        item.querySelector('cr-icon-button').click();
-
-        assertTrue(actionMenu.open);
-        const removeMenuItem = getMenuItem('removeLanguage');
-        assertFalse(removeMenuItem.disabled);
-        assertFalse(removeMenuItem.hidden);
-        removeMenuItem.click();
-        assertFalse(actionMenu.open);
-
-        assertEquals('en-US', languageHelper.getPref(languagesPref).value);
-      });
-
-      test('move up/down buttons', function() {
-        // Add several languages.
-        for (const language of ['en-CA', 'en-US', 'tk', 'no']) {
-          languageHelper.enableLanguage(language);
-        }
-
-        Polymer.dom.flush();
-
-        const menuButtons = languagesList.querySelectorAll(
-            '.list-item cr-icon-button.icon-more-vert');
-
-        // First language should not have "Move up" or "Move to top".
-        menuButtons[0].click();
-        assertMenuItemButtonsVisible({
-          moveToTop: false,
-          moveUp: false,
-          moveDown: true,
-        });
-        actionMenu.close();
-
-        // Second language should not have "Move up".
-        menuButtons[1].click();
-        assertMenuItemButtonsVisible({
-          moveToTop: true,
-          moveUp: false,
-          moveDown: true,
-        });
-        actionMenu.close();
-
-        // Middle languages should have all buttons.
-        menuButtons[2].click();
-        assertMenuItemButtonsVisible({
-          moveToTop: true,
-          moveUp: true,
-          moveDown: true,
-        });
-        actionMenu.close();
-
-        // Last language should not have "Move down".
-        menuButtons[menuButtons.length - 1].click();
-        assertMenuItemButtonsVisible({
-          moveToTop: true,
-          moveUp: true,
-          moveDown: false,
-        });
-        actionMenu.close();
-      });
-    });
-
-    suite(TestNames.InputMethods, function() {
-      test('displays input method list', function() {
-        const inputMethodsList = languagesPage.$.inputMethodsList;
-        assertTrue(!!inputMethodsList);
-
-        // The test input methods should appear.
-        const items = inputMethodsList.querySelectorAll('.list-item');
-        assertEquals(3, items.length);  // Two items for input methods and one
-                                        // item for manage input methods.
-        assertEquals(
-            'US keyboard',
-            items[0].querySelector('.display-name').textContent.trim());
-        assertTrue(!!items[0].querySelector('.internal-wrapper'));
-        assertFalse(!!items[0].querySelector('.external-wrapper'));
-        assertEquals(
-            'US Dvorak keyboard',
-            items[1].querySelector('.display-name').textContent.trim());
-        assertTrue(!!items[1].querySelector('.external-wrapper'));
-        assertFalse(!!items[1].querySelector('.internal-wrapper'));
-
-        const manageInputMethodsButton =
-            inputMethodsList.querySelector('#manageInputMethods');
-        assertTrue(!!manageInputMethodsButton);
-
-        // settings-manage-input-methods-page is owned by os-languages-section,
-        // not os-languages-page, and hence isn't tested here.
-      });
-
-      test('navigates to input method options page', function() {
-        const inputMethodsList = languagesPage.$.inputMethodsList;
-        const items = inputMethodsList.querySelectorAll('.list-item');
-        items[0].querySelector('.subpage-arrow').click();
-        const router = settings.Router.getInstance();
-        assertEquals(
-            router.getCurrentRoute().getAbsolutePath(),
-            'chrome://os-settings/osLanguages/inputMethodOptions');
-        assertEquals(
-            router.getQueryParameters().get('id'),
-            '_comp_ime_jkghodnilhceideoidjikpgommlajknkxkb:us::eng');
-      });
-    });
-
-    suite(TestNames.RecordMetrics, function() {
-      test('when adding languages', async () => {
-        languagesPage.$$('#addLanguages').click();
-        Polymer.dom.flush();
-        await metricsProxy.whenCalled('recordAddLanguages');
-      });
-
-      test('when deactivating show ime menu', async () => {
-        languagesPage.setPrefValue(
-            'settings.language.ime_menu_activated', true);
-        languagesPage.$$('#showImeMenu').click();
-        Polymer.dom.flush();
-
-        assertFalse(await metricsProxy.whenCalled(
-            'recordToggleShowInputOptionsOnShelf'));
-      });
-
-      test('when activating show ime menu', async () => {
-        languagesPage.setPrefValue(
-            'settings.language.ime_menu_activated', false);
-        languagesPage.$$('#showImeMenu').click();
-        Polymer.dom.flush();
-
-        assertTrue(await metricsProxy.whenCalled(
-            'recordToggleShowInputOptionsOnShelf'));
-      });
-
-      test(
-          'when switching system language and restarting', async () => {
-            // Adds several languages.
-            for (const language of ['en-CA', 'en-US', 'tk', 'no']) {
-              languageHelper.enableLanguage(language);
-            }
-
-            Polymer.dom.flush();
-
-            const languagesList = languagesPage.$$('#languagesList');
-
-            const menuButtons = languagesList.querySelectorAll(
-                '.list-item cr-icon-button.icon-more-vert');
-
-            // Chooses the second language to switch system language,
-            // as first language is the default language.
-            menuButtons[1].click();
-            const actionMenu = languagesPage.$$('#menu').get();
-            assertTrue(actionMenu.open);
-            const menuItems = actionMenu.querySelectorAll('.dropdown-item');
-            for (const item of menuItems) {
-              if (item.id === 'uiLanguageItem') {
-                assertFalse(item.checked);
-                item.click();
-
-                assertEquals(
-                    settings.LanguagesPageInteraction.SWITCH_SYSTEM_LANGUAGE,
-                    await metricsProxy.whenCalled('recordInteraction'));
-                return;
-              }
-            }
-            actionMenu.close();
-
-            // Chooses restart button after switching system language.
-            const restartButton = languagesPage.$$('#restartButton');
-            assertTrue(!!restartButton);
-            restartButton.click();
-
-            assertEquals(
-                settings.LanguagesPageInteraction.RESTART,
-                await metricsProxy.whenCalled('recordInteraction'));
-          });
-    });
-  });
-
-  // #cr_define_end
-  return {TestNames: TestNames};
-});
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
index 2df73857..d3c4389 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -34,17 +34,6 @@
   }
 };
 
-// TODO(crbug/1109431): Remove this test once migration is complete.
-// eslint-disable-next-line no-var
-var OSSettingsOsLanguagesPageV3Test = class extends OSSettingsV3BrowserTest {
-  /** @override */
-  get browsePreload() {
-    return 'chrome://os-settings/test_loader.html?module=settings/chromeos/os_languages_page_tests.m.js';
-  }
-};
-
-TEST_F('OSSettingsOsLanguagesPageV3Test', 'All', () => mocha.run());
-
 // eslint-disable-next-line no-var
 var OSSettingsDevicePageV3Test = class extends OSSettingsV3BrowserTest {
   /** @override */
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js
index 8eeec34..a1a9ff5 100644
--- a/chrome/test/data/webui/settings/cr_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -645,8 +645,7 @@
 GEN('#endif  // !defined(OS_MAC) || defined(NDEBUG)');
 
 GEN('#if BUILDFLAG(IS_CHROMEOS_ASH)');
-[['LanguagesPageMetricsChromeOS', 'languages_page_metrics_test_cros.js'],
- ['PasswordsSectionCros', 'passwords_section_test_cros.js'],
+[['PasswordsSectionCros', 'passwords_section_test_cros.js'],
  ['PeoplePageChromeOS', 'people_page_test_cros.js'],
  // Copied from Polymer 2 test. TODO(crbug.com/929455): flaky, fix.
  ['SiteListChromeOS', 'site_list_tests_cros.js', 'DISABLED_AndroidSmsInfo'],
diff --git a/chrome/test/data/webui/settings/languages_page_metrics_test_cros.js b/chrome/test/data/webui/settings/languages_page_metrics_test_cros.js
deleted file mode 100644
index 51e7510..0000000
--- a/chrome/test/data/webui/settings/languages_page_metrics_test_cros.js
+++ /dev/null
@@ -1,199 +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.
-
-import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {LanguagesBrowserProxyImpl, LanguagesMetricsProxyImpl, LanguagesPageInteraction} from 'chrome://settings/lazy_load.js';
-import {CrSettingsPrefs} from 'chrome://settings/settings.js';
-
-import {assertEquals, assertFalse, assertTrue} from '../chai_assert.js';
-import {fakeDataBind} from '../test_util.m.js';
-
-import {getFakeLanguagePrefs} from './fake_language_settings_private.js';
-import {FakeSettingsPrivate} from './fake_settings_private.js';
-import {TestLanguagesBrowserProxy} from './test_languages_browser_proxy.js';
-import {TestLanguagesMetricsProxy} from './test_languages_metrics_proxy.js';
-
-// TODO(crbug/1109431): Remove this test once migration is complete.
-suite('LanguagesPageMetricsChromeOS', function() {
-  /** @type {!LanguageHelper} */
-  let languageHelper;
-  /** @type {!SettingsLanguagesPageElement} */
-  let languagesPage;
-  /** @type {!TestLanguagesBrowserProxy} */
-  let browserProxy;
-  /** @type {!TestLanguagesMetricsProxy} */
-  let languagesMetricsProxy;
-
-  suiteSetup(function() {
-    CrSettingsPrefs.deferInitialization = true;
-  });
-
-  setup(function() {
-    document.body.innerHTML = '';
-    const settingsPrefs = document.createElement('settings-prefs');
-    const settingsPrivate = new FakeSettingsPrivate(getFakeLanguagePrefs());
-    settingsPrefs.initialize(settingsPrivate);
-    document.body.appendChild(settingsPrefs);
-    return CrSettingsPrefs.initialized.then(function() {
-      // Sets up test browser proxy.
-      browserProxy = new TestLanguagesBrowserProxy();
-      LanguagesBrowserProxyImpl.instance_ = browserProxy;
-
-      // Sets up test browser proxy.
-      languagesMetricsProxy = new TestLanguagesMetricsProxy();
-      LanguagesMetricsProxyImpl.instance_ = languagesMetricsProxy;
-
-      // Sets up fake languageSettingsPrivate API.
-      const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate();
-      languageSettingsPrivate.setSettingsPrefs(settingsPrefs);
-
-      languagesPage = /** @type {!SettingsLanguagesPageElement} */ (
-          document.createElement('settings-languages-page'));
-      /** @suppress {visibility} Temporary while removal is completed. */
-      languagesPage.isChromeOSLanguagesSettingsUpdate_ = false;
-
-      // Prefs would normally be data-bound to settings-languages-page.
-      languagesPage.prefs = settingsPrefs.prefs;
-      fakeDataBind(settingsPrefs, languagesPage, 'prefs');
-
-      document.body.appendChild(languagesPage);
-      languageHelper = languagesPage.languageHelper;
-      return languageHelper.whenReady();
-    });
-  });
-
-  test('records when adding languages', async () => {
-    languagesPage.$$('settings-languages-subpage').$$('#addLanguages').click();
-    flush();
-
-    await languagesMetricsProxy.whenCalled('recordAddLanguages');
-  });
-
-  test('records when clicking edit dictionary', async () => {
-    languagesPage.$$('#spellCheckSubpageTrigger').click();
-    flush();
-
-    assertEquals(
-        LanguagesPageInteraction.OPEN_CUSTOM_SPELL_CHECK,
-        await languagesMetricsProxy.whenCalled('recordInteraction'));
-  });
-
-  test('records when disabling translate.enable toggle', async () => {
-    languagesPage.$$('settings-languages-subpage')
-        .setPrefValue('translate.enabled', true);
-    languagesPage.$$('settings-languages-subpage')
-        .$$('#offerTranslateOtherLanguages')
-        .click();
-    flush();
-
-    assertFalse(
-        await languagesMetricsProxy.whenCalled('recordToggleTranslate'));
-  });
-
-  test('records when enabling translate.enable toggle', async () => {
-    languagesPage.$$('settings-languages-subpage')
-        .setPrefValue('translate.enabled', false);
-    languagesPage.$$('settings-languages-subpage')
-        .$$('#offerTranslateOtherLanguages')
-        .click();
-    flush();
-
-    assertTrue(await languagesMetricsProxy.whenCalled('recordToggleTranslate'));
-  });
-
-  test('records when disabling spell check toggle', async () => {
-    languagesPage.setPrefValue('browser.enable_spellchecking', true);
-    languagesPage.$$('#enableSpellcheckingToggle').click();
-    flush();
-
-    assertFalse(
-        await languagesMetricsProxy.whenCalled('recordToggleSpellCheck'));
-  });
-
-  test('records when enabling spell check toggle', async () => {
-    languagesPage.setPrefValue('browser.enable_spellchecking', false);
-    languagesPage.$$('#enableSpellcheckingToggle').click();
-    flush();
-
-    assertTrue(
-        await languagesMetricsProxy.whenCalled('recordToggleSpellCheck'));
-  });
-
-  test('records when switching system language and restarting', async () => {
-    // Adds several languages.
-    for (const language of ['en-CA', 'en-US', 'tk', 'no']) {
-      languageHelper.enableLanguage(language);
-    }
-
-    flush();
-
-    const languagesCollapse = languagesPage.$$('#languagesCollapse');
-    languagesCollapse.opened = true;
-
-    const menuButtons =
-        languagesPage.$$('settings-languages-subpage')
-            .$$('#languagesSection')
-            .querySelectorAll('.list-item cr-icon-button.icon-more-vert');
-
-    // Chooses the second language to switch system language,
-    // as first language is the default language.
-    menuButtons[1].click();
-    const actionMenu =
-        languagesPage.$$('settings-languages-subpage').$$('#menu').get();
-    assertTrue(actionMenu.open);
-    const menuItems = actionMenu.querySelectorAll('.dropdown-item');
-    for (const item of menuItems) {
-      if (item.id === 'uiLanguageItem') {
-        assertFalse(item.checked);
-        item.click();
-
-        assertEquals(
-            LanguagesPageInteraction.SWITCH_SYSTEM_LANGUAGE,
-            await languagesMetricsProxy.whenCalled('recordInteraction'));
-        return;
-      }
-    }
-    actionMenu.close();
-
-    // Chooses restart button after switching system language.
-    const restartButton =
-        languagesPage.$$('settings-languages-subpage').$$('#restartButton');
-    assertTrue(!!restartButton);
-    restartButton.click();
-
-    assertEquals(
-        LanguagesPageInteraction.RESTART,
-        await languagesMetricsProxy.whenCalled('recordInteraction'));
-  });
-
-  test('records when ticking translate checkbox', async () => {
-    const languagesCollapse = languagesPage.$$('#languagesCollapse');
-    languagesCollapse.opened = true;
-
-    const menuButtons =
-        languagesPage.$$('settings-languages-subpage')
-            .$$('#languagesSection')
-            .querySelectorAll('.list-item cr-icon-button.icon-more-vert');
-
-    // Chooses the second language to change translate checkbox
-    // as first language is the language used for translation.
-    menuButtons[1].click();
-    const actionMenu =
-        languagesPage.$$('settings-languages-subpage').$$('#menu').get();
-    assertTrue(actionMenu.open);
-    const menuItems = actionMenu.querySelectorAll('.dropdown-item');
-    for (const item of menuItems) {
-      if (item.id === 'offerTranslations') {
-        const checkedValue = item.checked;
-        item.click();
-        assertEquals(
-            await languagesMetricsProxy.whenCalled(
-                'recordTranslateCheckboxChanged'),
-            !checkedValue);
-        return;
-      }
-    }
-  });
-});
diff --git a/chromeos/components/diagnostics_ui/backend/system_routine_controller_unittest.cc b/chromeos/components/diagnostics_ui/backend/system_routine_controller_unittest.cc
index bc06b77..5d3d70d 100644
--- a/chromeos/components/diagnostics_ui/backend/system_routine_controller_unittest.cc
+++ b/chromeos/components/diagnostics_ui/backend/system_routine_controller_unittest.cc
@@ -214,8 +214,7 @@
     base::ScopedFD fd =
         base::CreateAndOpenFdForTemporaryFileInDir(temp_dir_.GetPath(), &path);
     DCHECK(fd.is_valid());
-    const bool write_success =
-        base::WriteFileDescriptor(fd.get(), contents.data(), contents.size());
+    const bool write_success = base::WriteFileDescriptor(fd.get(), contents);
     DCHECK(write_success);
     return mojo::WrapPlatformFile(std::move(fd));
   }
diff --git a/chromeos/components/eche_app_ui/eche_connector.h b/chromeos/components/eche_app_ui/eche_connector.h
index 023d258..3dc2c76 100644
--- a/chromeos/components/eche_app_ui/eche_connector.h
+++ b/chromeos/components/eche_app_ui/eche_connector.h
@@ -5,6 +5,7 @@
 #ifndef CHROMEOS_COMPONENTS_ECHE_APP_UI_ECHE_CONNECTOR_H_
 #define CHROMEOS_COMPONENTS_ECHE_APP_UI_ECHE_CONNECTOR_H_
 
+#include "base/containers/queue.h"
 #include "chromeos/components/eche_app_ui/eche_feature_status_provider.h"
 #include "chromeos/components/eche_app_ui/feature_status_provider.h"
 
diff --git a/chromeos/components/help_app_ui/search/search_handler.cc b/chromeos/components/help_app_ui/search/search_handler.cc
index 46b1c5d..8ed00d8 100644
--- a/chromeos/components/help_app_ui/search/search_handler.cc
+++ b/chromeos/components/help_app_ui/search/search_handler.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <utility>
 
+#include "base/callback.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -63,6 +64,16 @@
   DCHECK(index_remote_.is_bound());
 
   search_tag_registry_->AddObserver(this);
+
+  // Set the search params to make fuzzy and prefix matching stricter.
+  // This reduces the number of irrelevant search results.
+  index_remote_->SetSearchParams(
+      {
+          /*relevance_threshold=*/0.32,  // Same as default.
+          /*prefix_threshold=*/0.8,
+          /*fuzzy_threshold=*/0.85,
+      },
+      base::OnceCallback<void()>());
 }
 
 SearchHandler::~SearchHandler() {
diff --git a/chromeos/components/help_app_ui/search/search_handler_unittest.cc b/chromeos/components/help_app_ui/search/search_handler_unittest.cc
index 9380324..2d0fa35 100644
--- a/chromeos/components/help_app_ui/search/search_handler_unittest.cc
+++ b/chromeos/components/help_app_ui/search/search_handler_unittest.cc
@@ -150,14 +150,14 @@
       /*id=*/"test-id-less",
       /*title=*/u"Title 1",
       /*main_category=*/u"Help",
-      /*tags=*/std::vector<std::u16string>{u"less relevance"},
+      /*tags=*/std::vector<std::u16string>{u"less relevant concept"},
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   mojom::SearchConceptPtr new_concept_2 = mojom::SearchConcept::New(
       /*id=*/"test-id-more",
       /*title=*/u"Title 2",
       /*main_category=*/u"Help",
-      /*tags=*/std::vector<std::u16string>{u"more relevant tag", u"Tag 2"},
+      /*tags=*/std::vector<std::u16string>{u"more relevant tag", u"Tag"},
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   search_concepts.push_back(std::move(new_concept_1));
diff --git a/chromeos/components/smbfs/smbfs_host.cc b/chromeos/components/smbfs/smbfs_host.cc
index f490f37d8..5674f1f1 100644
--- a/chromeos/components/smbfs/smbfs_host.cc
+++ b/chromeos/components/smbfs/smbfs_host.cc
@@ -58,8 +58,7 @@
       base::ScopedFD pipe_write_end;
       CHECK(base::CreatePipe(&pipe_read_end, &pipe_write_end,
                              true /* non_blocking */));
-      CHECK(base::WriteFileDescriptor(pipe_write_end.get(), password.c_str(),
-                                      password.size()));
+      CHECK(base::WriteFileDescriptor(pipe_write_end.get(), password));
 
       creds->password = mojom::Password::New(
           mojo::WrapPlatformHandle(
diff --git a/chromeos/components/smbfs/smbfs_mounter.cc b/chromeos/components/smbfs/smbfs_mounter.cc
index e7ddcfe..80788f57 100644
--- a/chromeos/components/smbfs/smbfs_mounter.cc
+++ b/chromeos/components/smbfs/smbfs_mounter.cc
@@ -162,9 +162,7 @@
     base::ScopedFD pipe_read_end(pipe_fds[0]);
     base::ScopedFD pipe_write_end(pipe_fds[1]);
     // Write password to pipe.
-    CHECK(base::WriteFileDescriptor(pipe_write_end.get(),
-                                    options_.password.c_str(),
-                                    options_.password.size()));
+    CHECK(base::WriteFileDescriptor(pipe_write_end.get(), options_.password));
 
     mojom::PasswordPtr password = mojom::Password::New();
     password->length = static_cast<int32_t>(options_.password.size());
diff --git a/chromeos/components/sync_wifi/local_network_collector_impl.h b/chromeos/components/sync_wifi/local_network_collector_impl.h
index 6d6ff19..d8185e5 100644
--- a/chromeos/components/sync_wifi/local_network_collector_impl.h
+++ b/chromeos/components/sync_wifi/local_network_collector_impl.h
@@ -11,6 +11,7 @@
 #include "base/callback.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
+#include "base/containers/queue.h"
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
 #include "chromeos/components/sync_wifi/local_network_collector.h"
diff --git a/chromeos/dbus/lorgnette_manager/lorgnette_manager_client_unittest.cc b/chromeos/dbus/lorgnette_manager/lorgnette_manager_client_unittest.cc
index 7fea509..9d7c7ad 100644
--- a/chromeos/dbus/lorgnette_manager/lorgnette_manager_client_unittest.cc
+++ b/chromeos/dbus/lorgnette_manager/lorgnette_manager_client_unittest.cc
@@ -359,7 +359,7 @@
   // only be called when a scan job exists.
   void WriteDataToScanJob(const std::string& data) {
     ASSERT_TRUE(fd_.is_valid());
-    EXPECT_TRUE(base::WriteFileDescriptor(fd_.get(), data.data(), data.size()));
+    EXPECT_TRUE(base::WriteFileDescriptor(fd_.get(), data));
     fd_.reset();
     task_environment_.RunUntilIdle();
   }
diff --git a/chromeos/dbus/pipe_reader_unittest.cc b/chromeos/dbus/pipe_reader_unittest.cc
index fadb017..3eb8f8a0 100644
--- a/chromeos/dbus/pipe_reader_unittest.cc
+++ b/chromeos/dbus/pipe_reader_unittest.cc
@@ -33,7 +33,7 @@
 
 // Writes the |data| to |fd|, then close |fd|.
 void WriteData(base::ScopedFD fd, const std::string& data) {
-  EXPECT_TRUE(base::WriteFileDescriptor(fd.get(), data.data(), data.size()));
+  EXPECT_TRUE(base::WriteFileDescriptor(fd.get(), data));
 }
 
 }  // namespace
diff --git a/chromeos/dbus/session_manager/session_manager_client.cc b/chromeos/dbus/session_manager/session_manager_client.cc
index 4b8c56dd..abf5ea56 100644
--- a/chromeos/dbus/session_manager/session_manager_client.cc
+++ b/chromeos/dbus/session_manager/session_manager_client.cc
@@ -14,6 +14,7 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
+#include "base/containers/span.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
@@ -110,9 +111,8 @@
   const size_t data_size = data.size();
 
   base::WriteFileDescriptor(pipe_write_end.get(),
-                            reinterpret_cast<const char*>(&data_size),
-                            sizeof(data_size));
-  base::WriteFileDescriptor(pipe_write_end.get(), data.c_str(), data.size());
+                            base::as_bytes(base::make_span(&data_size, 1)));
+  base::WriteFileDescriptor(pipe_write_end.get(), data);
 
   return pipe_read_end;
 }
diff --git a/chromeos/process_proxy/process_output_watcher_unittest.cc b/chromeos/process_proxy/process_output_watcher_unittest.cc
index a5ad705..c27b41d 100644
--- a/chromeos/process_proxy/process_output_watcher_unittest.cc
+++ b/chromeos/process_proxy/process_output_watcher_unittest.cc
@@ -175,8 +175,8 @@
       ssize_t test_size = test_str.length() * sizeof(*test_str.c_str());
       if (test_cases[i].should_send_terminating_null)
         test_size += sizeof(*test_str.c_str());
-      EXPECT_TRUE(base::WriteFileDescriptor(pt_pipe[1], test_str.c_str(),
-                                            test_size));
+      EXPECT_TRUE(base::WriteFileDescriptor(
+          pt_pipe[1], base::StringPiece(test_str.c_str(), test_size)));
 
       run_loop.Run();
       EXPECT_TRUE(expectations_.IsDone());
diff --git a/chromeos/process_proxy/process_proxy.cc b/chromeos/process_proxy/process_proxy.cc
index b6afe90..858f7f1 100644
--- a/chromeos/process_proxy/process_proxy.cc
+++ b/chromeos/process_proxy/process_proxy.cc
@@ -161,10 +161,7 @@
   if (!process_launched_)
     return false;
 
-  // We don't want to write '\0' to the pipe.
-  size_t data_size = text.length() * sizeof(*text.c_str());
-  return base::WriteFileDescriptor(
-             pt_pair_[PT_MASTER_FD], text.c_str(), data_size);
+  return base::WriteFileDescriptor(pt_pair_[PT_MASTER_FD], text);
 }
 
 bool ProcessProxy::OnTerminalResize(int width, int height) {
diff --git a/chromeos/services/libassistant/file_provider_impl.cc b/chromeos/services/libassistant/file_provider_impl.cc
index 2f2d70a..d7fd133 100644
--- a/chromeos/services/libassistant/file_provider_impl.cc
+++ b/chromeos/services/libassistant/file_provider_impl.cc
@@ -43,8 +43,7 @@
     return false;
 
   // Write to the tmp file.
-  const bool success =
-      base::WriteFileDescriptor(fd.get(), data.data(), data.size());
+  const bool success = base::WriteFileDescriptor(fd.get(), data);
   if (!success)
     return false;
 
diff --git a/chromeos/services/secure_channel/nearby_connection.h b/chromeos/services/secure_channel/nearby_connection.h
index 48f152f9..984bf01b 100644
--- a/chromeos/services/secure_channel/nearby_connection.h
+++ b/chromeos/services/secure_channel/nearby_connection.h
@@ -5,6 +5,7 @@
 #ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_NEARBY_CONNECTION_H_
 #define CHROMEOS_SERVICES_SECURE_CHANNEL_NEARBY_CONNECTION_H_
 
+#include "base/containers/queue.h"
 #include "base/memory/weak_ptr.h"
 #include "chromeos/services/secure_channel/connection.h"
 #include "chromeos/services/secure_channel/public/mojom/nearby_connector.mojom.h"
diff --git a/chromeos/startup/startup_unittest.cc b/chromeos/startup/startup_unittest.cc
index 18db8808..8f2edaa 100644
--- a/chromeos/startup/startup_unittest.cc
+++ b/chromeos/startup/startup_unittest.cc
@@ -31,7 +31,7 @@
     return base::ScopedFD();
   }
 
-  if (!base::WriteFileDescriptor(file.get(), content.data(), content.size())) {
+  if (!base::WriteFileDescriptor(file.get(), content)) {
     LOG(ERROR) << "Failed to write the data";
     return base::ScopedFD();
   }
diff --git a/chromeos/system/statistics_provider.h b/chromeos/system/statistics_provider.h
index da6cc76d..f8570be 100644
--- a/chromeos/system/statistics_provider.h
+++ b/chromeos/system/statistics_provider.h
@@ -187,6 +187,7 @@
 using ::chromeos::system::kActivateDateKey;
 using ::chromeos::system::kBlockDevModeKey;
 using ::chromeos::system::kCheckEnrollmentKey;
+using ::chromeos::system::kOemKeyboardDrivenOobeKey;
 using ::chromeos::system::kSerialNumberKeyForTest;
 using ::chromeos::system::StatisticsProvider;
 }  // namespace system
diff --git a/components/arc/ime/arc_ime_service.cc b/components/arc/ime/arc_ime_service.cc
index 1f8a9a36..d6427a3 100644
--- a/components/arc/ime/arc_ime_service.cc
+++ b/components/arc/ime/arc_ime_service.cc
@@ -628,7 +628,7 @@
 bool ArcImeService::SetCompositionFromExistingText(
     const gfx::Range& range,
     const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) {
-  if (!range.IsBoundedBy(text_range_))
+  if (text_range_.IsValid() && !range.IsBoundedBy(text_range_))
     return false;
 
   InvalidateSurroundingTextAndSelectionRange();
diff --git a/components/arc/ime/arc_ime_service_unittest.cc b/components/arc/ime/arc_ime_service_unittest.cc
index 39346d4..a6fca185 100644
--- a/components/arc/ime/arc_ime_service_unittest.cc
+++ b/components/arc/ime/arc_ime_service_unittest.cc
@@ -553,6 +553,19 @@
   EXPECT_EQ(composing_range, fake_arc_ime_bridge_->composing_range());
 }
 
+TEST_F(ArcImeServiceTest, ExtendSelectionAndDeleteThenSetComposingRegion) {
+  instance_->OnWindowFocused(arc_win_.get(), nullptr);
+  instance_->OnCursorRectChangedWithSurroundingText(
+      gfx::Rect(), gfx::Range(0, 100), std::u16string(100, 'a'),
+      gfx::Range(100, 100), false);
+
+  instance_->ExtendSelectionAndDelete(1, 0);
+  const gfx::Range composing_range(0, 99);
+  instance_->SetCompositionFromExistingText(composing_range, {});
+
+  EXPECT_EQ(composing_range, fake_arc_ime_bridge_->composing_range());
+}
+
 TEST_F(ArcImeServiceTest, OnDispatchingKeyEventPostIME) {
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(
diff --git a/components/arc/mojom/app.mojom b/components/arc/mojom/app.mojom
index 0438b45d..cfe282d 100644
--- a/components/arc/mojom/app.mojom
+++ b/components/arc/mojom/app.mojom
@@ -369,7 +369,11 @@
 
   // Sends task label and icon.
   [MinVersion=46] OnTaskDescriptionChanged@18(
-      int32 task_id, string label, RawIconPngData icon);
+      int32 task_id,
+      string label,
+      RawIconPngData icon,
+      [MinVersion=49] uint32 primary_color,
+      [MinVersion=49] uint32 status_bar_color);
 
   // Notifies that task has been destroyed.
   [MinVersion=4] OnTaskDestroyed@5(int32 task_id);
diff --git a/components/arc/session/arc_vm_client_adapter.cc b/components/arc/session/arc_vm_client_adapter.cc
index 06409c3..93e4c79f 100644
--- a/components/arc/session/arc_vm_client_adapter.cc
+++ b/components/arc/session/arc_vm_client_adapter.cc
@@ -444,7 +444,7 @@
   if (!fd.is_valid())
     return false;
 
-  if (!base::WriteFileDescriptor(fd.get(), props.c_str(), props.size())) {
+  if (!base::WriteFileDescriptor(fd.get(), props)) {
     PLOG(ERROR) << "Unable to write props to "
                 << kArcVmBootNotificationServerSocketPath;
     return false;
diff --git a/components/arc/test/fake_app_instance.cc b/components/arc/test/fake_app_instance.cc
index 623ba805..fb44c04 100644
--- a/components/arc/test/fake_app_instance.cc
+++ b/components/arc/test/fake_app_instance.cc
@@ -168,7 +168,7 @@
     const std::string& icon_png_data_as_string) {
   arc::mojom::RawIconPngDataPtr icon = arc::mojom::RawIconPngData::New();
   FillRawIconPngData(icon_png_data_as_string, icon.get());
-  app_host_->OnTaskDescriptionChanged(taskId, label, std::move(icon));
+  app_host_->OnTaskDescriptionChanged(taskId, label, std::move(icon), 0, 0);
 }
 
 void FakeAppInstance::SendTaskDestroyed(int32_t taskId) {
diff --git a/components/arc/test/fake_file_system_instance.cc b/components/arc/test/fake_file_system_instance.cc
index ea640ab..65ce28a 100644
--- a/components/arc/test/fake_file_system_instance.cc
+++ b/components/arc/test/fake_file_system_instance.cc
@@ -788,8 +788,7 @@
   DCHECK_EQ(0, ret);
   base::ScopedFD fd_read(fds[0]);
   base::ScopedFD fd_write(fds[1]);
-  bool write_success =
-      base::WriteFileDescriptor(fd_write.get(), content.data(), content.size());
+  bool write_success = base::WriteFileDescriptor(fd_write.get(), content);
   DCHECK(write_success);
   return fd_read;
 }
diff --git a/components/autofill/core/browser/autofill_address_util.cc b/components/autofill/core/browser/autofill_address_util.cc
index 3cd52d0..05d5a3b 100644
--- a/components/autofill/core/browser/autofill_address_util.cc
+++ b/components/autofill/core/browser/autofill_address_util.cc
@@ -138,9 +138,11 @@
         component.field == ::i18n::addressinput::RECIPIENT) {
       continue;
     }
-    address += base::UTF16ToUTF8(profile.GetInfo(
-        autofill::AddressFieldToServerFieldType(component.field),
-        ui_language_code));
+    ServerFieldType type =
+        autofill::AddressFieldToServerFieldType(component.field);
+    if (type == NAME_FULL)
+      type = NAME_FULL_WITH_HONORIFIC_PREFIX;
+    address += base::UTF16ToUTF8(profile.GetInfo(type, ui_language_code));
   }
   if (include_country) {
     address += "\n";
@@ -152,10 +154,10 @@
   // address.
   base::TrimString(address, base::kWhitespaceASCII, &address);
 
-  // Collpase new lines to remove empty lines.
+  // Collapse new lines to remove empty lines.
   re2::RE2::GlobalReplace(&address, re2::RE2("\\n+"), "\n");
 
-  // // Collpase white spaces.
+  // Collapse white spaces.
   re2::RE2::GlobalReplace(&address, re2::RE2("[ ]+"), " ");
 
   return base::UTF8ToUTF16(address);
diff --git a/components/autofill/core/browser/autofill_address_util.h b/components/autofill/core/browser/autofill_address_util.h
index 0fe786c..d78db338 100644
--- a/components/autofill/core/browser/autofill_address_util.h
+++ b/components/autofill/core/browser/autofill_address_util.h
@@ -62,8 +62,7 @@
 
 // Fields in order they should appear in differences for AutofillProfile update.
 static constexpr ServerFieldType kVisibleTypesForProfileDifferences[] = {
-    NAME_HONORIFIC_PREFIX,
-    NAME_FULL,
+    NAME_FULL_WITH_HONORIFIC_PREFIX,
     ADDRESS_HOME_STREET_ADDRESS,
     ADDRESS_HOME_DEPENDENT_LOCALITY,
     ADDRESS_HOME_CITY,
diff --git a/components/autofill/core/browser/autofill_address_util_unittest.cc b/components/autofill/core/browser/autofill_address_util_unittest.cc
index 639ef75b..24296c4 100644
--- a/components/autofill/core/browser/autofill_address_util_unittest.cc
+++ b/components/autofill/core/browser/autofill_address_util_unittest.cc
@@ -43,7 +43,8 @@
   // some more highlevel conditions that are less probable to change.
 
   // The full name should be part of the envelope style address.
-  EXPECT_NE(address.find(profile.GetInfo(NAME_FULL, GetLocale())),
+  EXPECT_NE(address.find(
+                profile.GetInfo(NAME_FULL_WITH_HONORIFIC_PREFIX, GetLocale())),
             std::string::npos);
 
   // City should be part of the envelope style address.
diff --git a/components/embedder_support/origin_trials/component_updater_utils.cc b/components/embedder_support/origin_trials/component_updater_utils.cc
index 5ef281e..93d6992 100644
--- a/components/embedder_support/origin_trials/component_updater_utils.cc
+++ b/components/embedder_support/origin_trials/component_updater_utils.cc
@@ -41,7 +41,7 @@
   const bool manifest_has_disabled_features = manifest->GetList(
       kManifestDisabledFeaturesPath, &override_disabled_feature_list);
   if (manifest_has_disabled_features &&
-      !override_disabled_feature_list->empty()) {
+      !override_disabled_feature_list->GetList().empty()) {
     ListPrefUpdate update(local_state, prefs::kOriginTrialDisabledFeatures);
     update->Swap(override_disabled_feature_list);
   } else {
@@ -50,7 +50,8 @@
   base::ListValue* disabled_tokens_list = nullptr;
   const bool manifest_has_disabled_tokens = manifest->GetList(
       kManifestDisabledTokenSignaturesPath, &disabled_tokens_list);
-  if (manifest_has_disabled_tokens && !disabled_tokens_list->empty()) {
+  if (manifest_has_disabled_tokens &&
+      !disabled_tokens_list->GetList().empty()) {
     ListPrefUpdate update(local_state, prefs::kOriginTrialDisabledTokens);
     update->Swap(disabled_tokens_list);
   } else {
diff --git a/components/exo/data_offer.cc b/components/exo/data_offer.cc
index 315195c4..91d1f7a 100644
--- a/components/exo/data_offer.cc
+++ b/components/exo/data_offer.cc
@@ -50,9 +50,7 @@
 void WriteFileDescriptorOnWorkerThread(
     base::ScopedFD fd,
     scoped_refptr<base::RefCountedMemory> memory) {
-  if (!base::WriteFileDescriptor(fd.get(),
-                                 reinterpret_cast<const char*>(memory->front()),
-                                 memory->size()))
+  if (!base::WriteFileDescriptor(fd.get(), *memory))
     DLOG(ERROR) << "Failed to write drop data";
 }
 
diff --git a/components/exo/data_source_unittest.cc b/components/exo/data_source_unittest.cc
index 93c20a3..5e85962 100644
--- a/components/exo/data_source_unittest.cc
+++ b/components/exo/data_source_unittest.cc
@@ -34,8 +34,7 @@
   void OnDataSourceDestroying(DataSource* source) override {}
   void OnTarget(const base::Optional<std::string>& mime_type) override {}
   void OnSend(const std::string& mime_type, base::ScopedFD fd) override {
-    ASSERT_TRUE(
-        base::WriteFileDescriptor(fd.get(), kTestData, strlen(kTestData)));
+    ASSERT_TRUE(base::WriteFileDescriptor(fd.get(), kTestData));
   }
   void OnCancelled() override {}
   void OnDndDropPerformed() override {}
diff --git a/components/exo/drag_drop_operation_unittest.cc b/components/exo/drag_drop_operation_unittest.cc
index 3c7ebd2..100aec3c 100644
--- a/components/exo/drag_drop_operation_unittest.cc
+++ b/components/exo/drag_drop_operation_unittest.cc
@@ -37,7 +37,7 @@
   void OnTarget(const base::Optional<std::string>& mime_type) override {}
 
   void OnSend(const std::string& mime_type, base::ScopedFD fd) override {
-    base::WriteFileDescriptor(fd.get(), kText, sizeof(kText));
+    base::WriteFileDescriptor(fd.get(), kText);
   }
 
   void OnCancelled() override {}
diff --git a/components/exo/seat_unittest.cc b/components/exo/seat_unittest.cc
index 150c6fd..667f732 100644
--- a/components/exo/seat_unittest.cc
+++ b/components/exo/seat_unittest.cc
@@ -59,13 +59,10 @@
   void OnTarget(const base::Optional<std::string>& mime_type) override {}
   void OnSend(const std::string& mime_type, base::ScopedFD fd) override {
     if (!data_.has_value()) {
-      std::string test_data = "TestData";
-      ASSERT_TRUE(base::WriteFileDescriptor(fd.get(), test_data.data(),
-                                            test_data.size()));
+      const char kTestData[] = "TestData";
+      ASSERT_TRUE(base::WriteFileDescriptor(fd.get(), kTestData));
     } else {
-      ASSERT_TRUE(base::WriteFileDescriptor(
-          fd.get(), reinterpret_cast<const char*>(data_->data()),
-          data_->size()));
+      ASSERT_TRUE(base::WriteFileDescriptor(fd.get(), *data_));
     }
   }
   void OnCancelled() override { cancelled_ = true; }
diff --git a/components/full_restore/app_restore_data.cc b/components/full_restore/app_restore_data.cc
index fdc3769..9ed6e2a 100644
--- a/components/full_restore/app_restore_data.cc
+++ b/components/full_restore/app_restore_data.cc
@@ -33,6 +33,8 @@
 constexpr char kWindowStateTypeKey[] = "window_state_type";
 constexpr char kMinimumSizeKey[] = "min_size";
 constexpr char kMaximumSizeKey[] = "max_size";
+constexpr char kPrimaryColorKey[] = "primary_color";
+constexpr char kStatusBarColorKey[] = "status_bar_color";
 
 // Converts |size| to base::Value, e.g. { 100, 300 }.
 base::Value ConvertSizeToValue(const gfx::Size& size) {
@@ -52,6 +54,11 @@
   return rect_list;
 }
 
+// Converts |uint32_t| to base::Value in string, e.g 123 to "123".
+base::Value ConvertUintToValue(uint32_t number) {
+  return base::Value(base::NumberToString(number));
+}
+
 // Gets bool value from base::DictionaryValue, e.g. { "key": true } returns
 // true.
 base::Optional<bool> GetBoolValueFromDict(const base::DictionaryValue& dict,
@@ -65,6 +72,18 @@
   return dict.HasKey(key_name) ? dict.FindIntKey(key_name) : base::nullopt;
 }
 
+// Gets uint32_t value from base::DictionaryValue, e.g. { "key": "123" } returns
+// 123.
+base::Optional<uint32_t> GetUIntValueFromDict(const base::DictionaryValue& dict,
+                                              const std::string& key_name) {
+  uint32_t result = 0;
+  if (!dict.HasKey(key_name) ||
+      !base::StringToUint(dict.FindStringKey(key_name)->c_str(), &result)) {
+    return base::nullopt;
+  }
+  return result;
+}
+
 // Gets display id from base::DictionaryValue, e.g. { "display_id": "22000000" }
 // returns 22000000.
 base::Optional<int64_t> GetDisplayIdFromDict(
@@ -184,6 +203,8 @@
   window_state_type = GetWindowStateTypeFromDict(*data_dict);
   maximum_size = GetSizeFromDict(*data_dict, kMaximumSizeKey);
   minimum_size = GetSizeFromDict(*data_dict, kMinimumSizeKey);
+  primary_color = GetUIntValueFromDict(*data_dict, kPrimaryColorKey);
+  status_bar_color = GetUIntValueFromDict(*data_dict, kStatusBarColorKey);
 
   if (data_dict->HasKey(kIntentKey)) {
     intent = apps_util::ConvertValueToIntent(
@@ -254,6 +275,12 @@
   if (minimum_size.has_value())
     data->minimum_size = minimum_size.value();
 
+  if (primary_color.has_value())
+    data->primary_color = primary_color.value();
+
+  if (status_bar_color.has_value())
+    data->status_bar_color = status_bar_color.value();
+
   return data;
 }
 
@@ -325,6 +352,16 @@
                             ConvertSizeToValue(minimum_size.value()));
   }
 
+  if (primary_color.has_value()) {
+    launch_info_dict.SetKey(kPrimaryColorKey,
+                            ConvertUintToValue(primary_color.value()));
+  }
+
+  if (status_bar_color.has_value()) {
+    launch_info_dict.SetKey(kStatusBarColorKey,
+                            ConvertUintToValue(status_bar_color.value()));
+  }
+
   return launch_info_dict;
 }
 
@@ -356,6 +393,12 @@
   }
 }
 
+void AppRestoreData::ModifyThemeColor(uint32_t window_primary_color,
+                                      uint32_t window_status_bar_color) {
+  primary_color = window_primary_color;
+  status_bar_color = window_status_bar_color;
+}
+
 void AppRestoreData::ClearWindowInfo() {
   activation_index.reset();
   desk_id.reset();
@@ -365,6 +408,8 @@
   window_state_type.reset();
   minimum_size.reset();
   maximum_size.reset();
+  primary_color.reset();
+  status_bar_color.reset();
 }
 
 std::unique_ptr<WindowInfo> AppRestoreData::GetWindowInfo() const {
diff --git a/components/full_restore/app_restore_data.h b/components/full_restore/app_restore_data.h
index a71a2f0..6fb8483 100644
--- a/components/full_restore/app_restore_data.h
+++ b/components/full_restore/app_restore_data.h
@@ -60,6 +60,10 @@
   // Modifies the window's information based on |window_info|.
   void ModifyWindowInfo(const WindowInfo& window_info);
 
+  // Modifies the window's theme colors.
+  void ModifyThemeColor(uint32_t window_primary_color,
+                        uint32_t window_status_bar_color);
+
   // Clears the window's information.
   void ClearWindowInfo();
 
@@ -89,6 +93,8 @@
   // Extra ARC window's information.
   base::Optional<gfx::Size> minimum_size;
   base::Optional<gfx::Size> maximum_size;
+  base::Optional<uint32_t> primary_color;
+  base::Optional<uint32_t> status_bar_color;
 };
 
 }  // namespace full_restore
diff --git a/components/full_restore/arc_save_handler.cc b/components/full_restore/arc_save_handler.cc
index a776b41..45480cd 100644
--- a/components/full_restore/arc_save_handler.cc
+++ b/components/full_restore/arc_save_handler.cc
@@ -119,6 +119,17 @@
   task_id_to_app_id_.erase(task_id);
 }
 
+void ArcSaveHandler::OnTaskThemeColorUpdated(int32_t task_id,
+                                             uint32_t primary_color,
+                                             uint32_t status_bar_color) {
+  auto it = task_id_to_app_id_.find(task_id);
+  if (it == task_id_to_app_id_.end())
+    return;
+
+  FullRestoreSaveHandler::GetInstance()->ModifyThemeColor(
+      profile_path_, it->second, task_id, primary_color, status_bar_color);
+}
+
 int32_t ArcSaveHandler::GetArcSessionId() {
   if (session_id_ >= kArcSessionIdOffsetForRestoredLaunching) {
     LOG(WARNING) << "ARC session id is too large: " << session_id_;
diff --git a/components/full_restore/arc_save_handler.h b/components/full_restore/arc_save_handler.h
index bfb928b..f340dc6 100644
--- a/components/full_restore/arc_save_handler.h
+++ b/components/full_restore/arc_save_handler.h
@@ -58,6 +58,11 @@
   // Invoked when the task is destroyed for an ARC app.
   void OnTaskDestroyed(int32_t task_id);
 
+  // Invoked when the task theme color is updated for an ARC app.
+  void OnTaskThemeColorUpdated(int32_t task_id,
+                               uint32_t primary_color,
+                               uint32_t status_bar_color);
+
   // Generates the ARC session id (0 - 1,000,000,000) for ARC apps.
   int32_t GetArcSessionId();
 
diff --git a/components/full_restore/full_restore_read_handler.cc b/components/full_restore/full_restore_read_handler.cc
index aa8d09b..67dcfb2 100644
--- a/components/full_restore/full_restore_read_handler.cc
+++ b/components/full_restore/full_restore_read_handler.cc
@@ -189,7 +189,7 @@
   return arc_read_handler_->GetArcRestoreWindowId(task_id);
 }
 
-bool FullRestoreReadHandler::ModifyWidgetParams(
+void FullRestoreReadHandler::ModifyWidgetParams(
     int32_t restore_window_id,
     views::Widget::InitParams* out_params) {
   DCHECK(out_params);
@@ -206,7 +206,7 @@
     window_info = GetWindowInfo(restore_window_id);
   }
   if (!window_info)
-    return false;
+    return;
 
   if (window_info->activation_index) {
     const int32_t index = *window_info->activation_index;
@@ -244,8 +244,6 @@
         base::BindOnce(&FullRestoreReadHandler::OnWidgetInitialized,
                        weak_factory_.GetWeakPtr(), delegate));
   }
-
-  return true;
 }
 
 int32_t FullRestoreReadHandler::GetArcSessionId() {
diff --git a/components/full_restore/full_restore_read_handler.h b/components/full_restore/full_restore_read_handler.h
index b022bf10..2a529329 100644
--- a/components/full_restore/full_restore_read_handler.h
+++ b/components/full_restore/full_restore_read_handler.h
@@ -108,8 +108,8 @@
   int32_t GetArcRestoreWindowId(int32_t task_id);
 
   // Modifies `out_params` based on the window info associated with
-  // `restore_window_id`. Returns true if `out_params` was modified.
-  bool ModifyWidgetParams(int32_t restore_window_id,
+  // `restore_window_id`.
+  void ModifyWidgetParams(int32_t restore_window_id,
                           views::Widget::InitParams* out_params);
 
   // Generates the ARC session id (1,000,000,001 - INT_MAX) for restored ARC
diff --git a/components/full_restore/full_restore_save_handler.cc b/components/full_restore/full_restore_save_handler.cc
index 62f014f7..b5690d31 100644
--- a/components/full_restore/full_restore_save_handler.cc
+++ b/components/full_restore/full_restore_save_handler.cc
@@ -203,6 +203,16 @@
     arc_save_handler_->OnTaskDestroyed(task_id);
 }
 
+void FullRestoreSaveHandler::OnTaskThemeColorUpdated(
+    int32_t task_id,
+    uint32_t primary_color,
+    uint32_t status_bar_color) {
+  if (arc_save_handler_) {
+    arc_save_handler_->OnTaskThemeColorUpdated(task_id, primary_color,
+                                               status_bar_color);
+  }
+}
+
 void FullRestoreSaveHandler::Flush(const base::FilePath& profile_path) {
   if (save_running_.find(profile_path) != save_running_.end())
     return;
@@ -262,6 +272,24 @@
   MaybeStartSaveTimer();
 }
 
+void FullRestoreSaveHandler::ModifyThemeColor(
+    const base::FilePath& profile_path,
+    const std::string& app_id,
+    int32_t window_id,
+    uint32_t primary_color,
+    uint32_t status_bar_color) {
+  auto it = profile_path_to_restore_data_.find(profile_path);
+  if (it == profile_path_to_restore_data_.end())
+    return;
+
+  profile_path_to_restore_data_[profile_path].ModifyThemeColor(
+      app_id, window_id, primary_color, status_bar_color);
+
+  pending_save_profile_paths_.insert(profile_path);
+
+  MaybeStartSaveTimer();
+}
+
 void FullRestoreSaveHandler::RemoveApp(const base::FilePath& profile_path,
                                        const std::string& app_id) {
   auto it = profile_path_to_restore_data_.find(profile_path);
diff --git a/components/full_restore/full_restore_save_handler.h b/components/full_restore/full_restore_save_handler.h
index 92a236f8..503ab44c 100644
--- a/components/full_restore/full_restore_save_handler.h
+++ b/components/full_restore/full_restore_save_handler.h
@@ -79,6 +79,11 @@
   // Invoked when the task is destroyed for an ARC app.
   void OnTaskDestroyed(int32_t task_id);
 
+  // Invoked when the task theme color is updated for an ARC app.
+  void OnTaskThemeColorUpdated(int32_t task_id,
+                               uint32_t primary_color,
+                               uint32_t status_bar_color);
+
   // Flushes the full restore file in |profile_path| with the current restore
   // data.
   void Flush(const base::FilePath& profile_path);
@@ -95,6 +100,14 @@
                         int32_t window_id,
                         const WindowInfo& window_info);
 
+  // Saves |primary_color| and |status_bar_color| to |profile_path| for |app_id|
+  // and |window_id|.
+  void ModifyThemeColor(const base::FilePath& profile_path,
+                        const std::string& app_id,
+                        int32_t window_id,
+                        uint32_t primary_color,
+                        uint32_t status_bar_color);
+
   // Removes app launching and app windows for an app with the given |app_id|
   // from |file_path_to_restore_data_| for |profile_path| .
   void RemoveApp(const base::FilePath& profile_path, const std::string& app_id);
diff --git a/components/full_restore/full_restore_utils.cc b/components/full_restore/full_restore_utils.cc
index 6b0812561..7db6ccc 100644
--- a/components/full_restore/full_restore_utils.cc
+++ b/components/full_restore/full_restore_utils.cc
@@ -81,13 +81,13 @@
       restore_window_id);
 }
 
-bool ModifyWidgetParams(int32_t restore_window_id,
+void ModifyWidgetParams(int32_t restore_window_id,
                         views::Widget::InitParams* out_params) {
   if (!ash::features::IsFullRestoreEnabled())
-    return false;
+    return;
 
-  return FullRestoreReadHandler::GetInstance()->ModifyWidgetParams(
-      restore_window_id, out_params);
+  FullRestoreReadHandler::GetInstance()->ModifyWidgetParams(restore_window_id,
+                                                            out_params);
 }
 
 void OnTaskCreated(const std::string& app_id,
@@ -104,4 +104,11 @@
   FullRestoreSaveHandler::GetInstance()->OnTaskDestroyed(task_id);
 }
 
+void OnTaskThemeColorUpdated(int32_t task_id,
+                             uint32_t primary_color,
+                             uint32_t status_bar_color) {
+  FullRestoreSaveHandler::GetInstance()->OnTaskThemeColorUpdated(
+      task_id, primary_color, status_bar_color);
+}
+
 }  // namespace full_restore
diff --git a/components/full_restore/full_restore_utils.h b/components/full_restore/full_restore_utils.h
index ff4a285..89112b7 100644
--- a/components/full_restore/full_restore_utils.h
+++ b/components/full_restore/full_restore_utils.h
@@ -112,9 +112,9 @@
 bool HasWindowInfo(int32_t restore_window_id);
 
 // Modifies `out_params` based on the window info associated with
-// `restore_window_id`. Returns true if `out_params` was modified.
+// `restore_window_id`.
 COMPONENT_EXPORT(FULL_RESTORE)
-bool ModifyWidgetParams(int32_t restore_window_id,
+void ModifyWidgetParams(int32_t restore_window_id,
                         views::Widget::InitParams* out_params);
 
 // Invoked when the task is created for an ARC app.
@@ -127,6 +127,12 @@
 COMPONENT_EXPORT(FULL_RESTORE)
 void OnTaskDestroyed(int32_t task_id);
 
+// Invoked when the task theme colors are updated for an ARC app.
+COMPONENT_EXPORT(FULL_RESTORE)
+void OnTaskThemeColorUpdated(int32_t task_id,
+                             uint32_t primary_color,
+                             uint32_t status_bar_color);
+
 }  // namespace full_restore
 
 #endif  // COMPONENTS_FULL_RESTORE_FULL_RESTORE_UTILS_H_
diff --git a/components/full_restore/restore_data.cc b/components/full_restore/restore_data.cc
index 00e4da6..e134b4b 100644
--- a/components/full_restore/restore_data.cc
+++ b/components/full_restore/restore_data.cc
@@ -106,6 +106,15 @@
     app_restore_data->ModifyWindowInfo(window_info);
 }
 
+void RestoreData::ModifyThemeColor(const std::string& app_id,
+                                   int32_t window_id,
+                                   uint32_t primary_color,
+                                   uint32_t status_bar_color) {
+  auto* app_restore_data = GetAppRestoreData(app_id, window_id);
+  if (app_restore_data)
+    app_restore_data->ModifyThemeColor(primary_color, status_bar_color);
+}
+
 void RestoreData::SetNextRestoreWindowIdForChromeApp(
     const std::string& app_id) {
   auto it = app_id_to_launch_list_.find(app_id);
diff --git a/components/full_restore/restore_data.h b/components/full_restore/restore_data.h
index 0127598..184c2cec 100644
--- a/components/full_restore/restore_data.h
+++ b/components/full_restore/restore_data.h
@@ -92,6 +92,13 @@
                         int32_t window_id,
                         const WindowInfo& window_info);
 
+  // Modifies the window's theme colors for the window with |window_id| of the
+  // app with |app_id|,
+  void ModifyThemeColor(const std::string& app_id,
+                        int32_t window_id,
+                        uint32_t primary_color,
+                        uint32_t status_bar_color);
+
   // Modifies |chrome_app_id_to_current_window_id_| to set the next restore
   // window id for the given |app_id|.
   //
diff --git a/components/full_restore/restore_data_unittest.cc b/components/full_restore/restore_data_unittest.cc
index 32a92df..4a3cde9 100644
--- a/components/full_restore/restore_data_unittest.cc
+++ b/components/full_restore/restore_data_unittest.cc
@@ -74,6 +74,12 @@
 constexpr gfx::Size kMinSize1(100, 50);
 constexpr gfx::Size kMinSize2(88, 128);
 
+constexpr uint32_t kPrimaryColor1(0xFFFFFFFF);
+constexpr uint32_t kPrimaryColor2(0xFF000000);
+
+constexpr uint32_t kStatusBarColor1(0xFF00FF00);
+constexpr uint32_t kStatusBarColor2(0xFF000000);
+
 }  // namespace
 
 // Unit tests for restore data.
@@ -162,6 +168,13 @@
     restore_data().ModifyWindowInfo(kAppId2, kWindowId3, window_info3);
   }
 
+  void ModifyThemeColors() {
+    restore_data().ModifyThemeColor(kAppId1, kWindowId1, kPrimaryColor1,
+                                    kStatusBarColor1);
+    restore_data().ModifyThemeColor(kAppId1, kWindowId2, kPrimaryColor2,
+                                    kStatusBarColor2);
+  }
+
   void VerifyAppRestoreData(const std::unique_ptr<AppRestoreData>& data,
                             apps::mojom::LaunchContainer container,
                             WindowOpenDisposition disposition,
@@ -175,7 +188,9 @@
                             const gfx::Rect& current_bounds,
                             chromeos::WindowStateType window_state_type,
                             base::Optional<gfx::Size> max_size,
-                            base::Optional<gfx::Size> min_size) {
+                            base::Optional<gfx::Size> min_size,
+                            uint32_t primary_color,
+                            uint32_t status_bar_color) {
     EXPECT_TRUE(data->container.has_value());
     EXPECT_EQ(static_cast<int>(container), data->container.value());
 
@@ -232,6 +247,20 @@
     } else {
       EXPECT_FALSE(data->minimum_size.has_value());
     }
+
+    if (primary_color) {
+      EXPECT_TRUE(data->primary_color.has_value());
+      EXPECT_EQ(primary_color, data->primary_color.value());
+    } else {
+      EXPECT_FALSE(data->primary_color.has_value());
+    }
+
+    if (status_bar_color) {
+      EXPECT_TRUE(data->status_bar_color.has_value());
+      EXPECT_EQ(status_bar_color, data->status_bar_color.value());
+    } else {
+      EXPECT_FALSE(data->status_bar_color.has_value());
+    }
   }
 
   void VerifyRestoreData(const RestoreData& restore_data) {
@@ -254,7 +283,8 @@
                                     base::FilePath(kFilePath2)},
         CreateIntent(kIntentActionSend, kMimeType, kShareText1),
         kActivationIndex1, kDeskId1, kVisibleOnAllWorkspaces1, kRestoreBounds1,
-        kCurrentBounds1, kWindowStateType1, kMaxSize1, kMinSize1);
+        kCurrentBounds1, kWindowStateType1, kMaxSize1, kMinSize1,
+        kPrimaryColor1, kStatusBarColor1);
 
     const auto app_restore_data_it2 = launch_list_it1->second.find(kWindowId2);
     EXPECT_TRUE(app_restore_data_it2 != launch_list_it1->second.end());
@@ -265,7 +295,8 @@
         std::vector<base::FilePath>{base::FilePath(kFilePath2)},
         CreateIntent(kIntentActionView, kMimeType, kShareText2),
         kActivationIndex2, kDeskId2, kVisibleOnAllWorkspaces2, kRestoreBounds2,
-        kCurrentBounds2, kWindowStateType2, base::nullopt, kMinSize2);
+        kCurrentBounds2, kWindowStateType2, base::nullopt, kMinSize2,
+        kPrimaryColor2, kStatusBarColor2);
 
     // Verify for |kAppId2|.
     const auto launch_list_it2 =
@@ -281,7 +312,7 @@
         std::vector<base::FilePath>{base::FilePath(kFilePath1)},
         CreateIntent(kIntentActionView, kMimeType, kShareText1),
         kActivationIndex3, kDeskId3, kVisibleOnAllWorkspaces3, kRestoreBounds3,
-        kCurrentBounds3, kWindowStateType3, base::nullopt, base::nullopt);
+        kCurrentBounds3, kWindowStateType3, base::nullopt, base::nullopt, 0, 0);
   }
 
   RestoreData& restore_data() { return restore_data_; }
@@ -307,12 +338,14 @@
 TEST_F(RestoreDataTest, AddAppLaunchInfos) {
   AddAppLaunchInfos();
   ModifyWindowInfos();
+  ModifyThemeColors();
   VerifyRestoreData(restore_data());
 }
 
 TEST_F(RestoreDataTest, RemoveAppRestoreData) {
   AddAppLaunchInfos();
   ModifyWindowInfos();
+  ModifyThemeColors();
   VerifyRestoreData(restore_data());
 
   EXPECT_TRUE(restore_data().HasAppRestoreData(kAppId1, kWindowId1));
@@ -371,6 +404,7 @@
 TEST_F(RestoreDataTest, RemoveWindowInfo) {
   AddAppLaunchInfos();
   ModifyWindowInfos();
+  ModifyThemeColors();
   VerifyRestoreData(restore_data());
 
   // Remove kAppId1.
@@ -390,6 +424,7 @@
 TEST_F(RestoreDataTest, RemoveApp) {
   AddAppLaunchInfos();
   ModifyWindowInfos();
+  ModifyThemeColors();
   VerifyRestoreData(restore_data());
 
   // Remove kAppId1.
@@ -413,6 +448,7 @@
 TEST_F(RestoreDataTest, Convert) {
   AddAppLaunchInfos();
   ModifyWindowInfos();
+  ModifyThemeColors();
   std::unique_ptr<base::Value> value =
       std::make_unique<base::Value>(restore_data().ConvertToValue());
   std::unique_ptr<RestoreData> restore_data =
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn
index 2e7364c..4978a1dc 100644
--- a/components/metrics/BUILD.gn
+++ b/components/metrics/BUILD.gn
@@ -407,6 +407,7 @@
     "call_stack_profile_metadata_unittest.cc",
     "call_stack_profile_metrics_provider_unittest.cc",
     "child_call_stack_profile_collector_unittest.cc",
+    "clean_exit_beacon_unittest.cc",
     "cloned_install_detector_unittest.cc",
     "component_metrics_provider_unittest.cc",
     "daily_event_unittest.cc",
@@ -449,6 +450,7 @@
     ":single_sample_metrics",
     ":test_support",
     ":ui",
+    "//base",
     "//base/test:test_support",
     "//build:chromeos_buildflags",
     "//components/component_updater:test_support",
diff --git a/components/metrics/clean_exit_beacon.cc b/components/metrics/clean_exit_beacon.cc
index 120d7e0..9ede7e6 100644
--- a/components/metrics/clean_exit_beacon.cc
+++ b/components/metrics/clean_exit_beacon.cc
@@ -5,10 +5,13 @@
 #include "components/metrics/clean_exit_beacon.h"
 
 #include "base/check_op.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/numerics/ranges.h"
 #include "build/build_config.h"
 #include "components/metrics/metrics_pref_names.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
+#include "components/variations/pref_names.h"
 
 #if defined(OS_WIN)
 #include <windows.h>
@@ -19,17 +22,52 @@
 #endif
 
 namespace metrics {
+namespace {
+
+// Increments kVariationsCrashStreak if |did_previous_session_exit_cleanly| is
+// false. Also, emits the crash streak to a histogram.
+void MaybeIncrementCrashStreak(bool did_previous_session_exit_cleanly,
+                               PrefService* local_state) {
+  // Increment the crash streak if the previous session crashed. Note that the
+  // streak is not cleared if the previous run didn’t crash. Instead, it’s
+  // incremented on each crash until Chrome is able to successfully fetch a new
+  // seed. This way, a seed update that mostly destabilizes Chrome still results
+  // in a fallback to safe mode.
+  //
+  // The crash streak is incremented here rather than in a variations-related
+  // class for two reasons. First, the crash streak depends on the value of
+  // kStabilityExitedCleanly. Second, if kVariationsCrashStreak were updated in
+  // another function, any crash between CleanExitBeacon() and that function
+  // would cause the crash streak to not be to incremented. A consequence of
+  // failing to increment the crash streak is that variations safe mode might
+  // undercount or be completely unaware of repeated crashes early on in
+  // startup.
+  int num_crashes =
+      local_state->GetInteger(variations::prefs::kVariationsCrashStreak);
+  if (!did_previous_session_exit_cleanly) {
+    ++num_crashes;
+    local_state->SetInteger(variations::prefs::kVariationsCrashStreak,
+                            num_crashes);
+  }
+  base::UmaHistogramSparse("Variations.SafeMode.Streak.Crashes",
+                           base::ClampToRange(num_crashes, 0, 100));
+}
+
+}  // namespace
 
 CleanExitBeacon::CleanExitBeacon(const std::wstring& backup_registry_key,
                                  PrefService* local_state)
     : local_state_(local_state),
-      initial_value_(local_state->GetBoolean(prefs::kStabilityExitedCleanly)),
+      did_previous_session_exit_cleanly_(
+          local_state->GetBoolean(prefs::kStabilityExitedCleanly)),
       initial_browser_last_live_timestamp_(
           local_state->GetTime(prefs::kStabilityBrowserLastLiveTimeStamp)),
       backup_registry_key_(backup_registry_key) {
   DCHECK_NE(PrefService::INITIALIZATION_STATUS_WAITING,
             local_state_->GetInitializationStatus());
 
+  MaybeIncrementCrashStreak(did_previous_session_exit_cleanly_, local_state_);
+
 #if defined(OS_WIN)
   // An enumeration of all possible permutations of the the beacon state in the
   // registry and in Local State.
@@ -50,21 +88,24 @@
       regkey.ReadValueDW(
           base::ASCIIToWide(prefs::kStabilityExitedCleanly).c_str(), &value) ==
           ERROR_SUCCESS) {
-    if (value)
-      consistency = initial_value_ ? CLEAN_CLEAN : CLEAN_DIRTY;
-    else
-      consistency = initial_value_ ? DIRTY_CLEAN : DIRTY_DIRTY;
+    if (value) {
+      consistency =
+          did_previous_session_exit_cleanly_ ? CLEAN_CLEAN : CLEAN_DIRTY;
+    } else {
+      consistency =
+          did_previous_session_exit_cleanly_ ? DIRTY_CLEAN : DIRTY_DIRTY;
+    }
   } else {
-    consistency = initial_value_ ? MISSING_CLEAN : MISSING_DIRTY;
+    consistency =
+        did_previous_session_exit_cleanly_ ? MISSING_CLEAN : MISSING_DIRTY;
   }
 
   UMA_HISTOGRAM_ENUMERATION(
       "UMA.CleanExitBeaconConsistency", consistency, NUM_CONSISTENCY_ENUMS);
-#endif
+#endif  // defined(OS_WIN)
 }
 
-CleanExitBeacon::~CleanExitBeacon() {
-}
+CleanExitBeacon::~CleanExitBeacon() = default;
 
 void CleanExitBeacon::WriteBeaconValue(bool value) {
   UpdateLastLiveTimestamp();
@@ -77,7 +118,7 @@
     regkey.WriteValue(base::ASCIIToWide(prefs::kStabilityExitedCleanly).c_str(),
                       value ? 1u : 0u);
   }
-#endif
+#endif  // defined(OS_WIN)
 }
 
 void CleanExitBeacon::UpdateLastLiveTimestamp() {
@@ -91,6 +132,12 @@
 
   registry->RegisterTimePref(prefs::kStabilityBrowserLastLiveTimeStamp,
                              base::Time(), PrefRegistry::LOSSY_PREF);
+
+  // This variations-safe-mode-related pref is registered here rather than in
+  // SafeSeedManager::RegisterPrefs() because the CleanExitBeacon is
+  // responsible for incrementing this value. (See the comments in
+  // MaybeIncrementCrashStreak() for more details.)
+  registry->RegisterIntegerPref(variations::prefs::kVariationsCrashStreak, 0);
 }
 
 // static
diff --git a/components/metrics/clean_exit_beacon.h b/components/metrics/clean_exit_beacon.h
index 2ac7913..0f1f10e 100644
--- a/components/metrics/clean_exit_beacon.h
+++ b/components/metrics/clean_exit_beacon.h
@@ -34,7 +34,7 @@
   ~CleanExitBeacon();
 
   // Returns the original value of the beacon.
-  bool exited_cleanly() const { return initial_value_; }
+  bool exited_cleanly() const { return did_previous_session_exit_cleanly_; }
 
   // Returns the original value of the last live timestamp.
   base::Time browser_last_live_timestamp() const {
@@ -55,7 +55,7 @@
 
  private:
   PrefService* const local_state_;
-  const bool initial_value_;
+  const bool did_previous_session_exit_cleanly_;
 
   // This is the value of the last live timestamp from local state at the
   // time of construction. It notes a timestamp from the previous browser
diff --git a/components/metrics/clean_exit_beacon_unittest.cc b/components/metrics/clean_exit_beacon_unittest.cc
new file mode 100644
index 0000000..05547e1
--- /dev/null
+++ b/components/metrics/clean_exit_beacon_unittest.cc
@@ -0,0 +1,90 @@
+// 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 "components/metrics/clean_exit_beacon.h"
+
+#include <string>
+
+#include "base/test/metrics/histogram_tester.h"
+#include "base/time/time.h"
+#include "components/metrics/metrics_pref_names.h"
+#include "components/prefs/testing_pref_service.h"
+#include "components/variations/pref_names.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace metrics {
+namespace {
+
+const wchar_t kDummyWindowsRegistryKey[] = L"";
+
+}  // namespace
+
+TEST(CleanExitBeaconTest, CrashStreakMetricWithDefaultPrefs) {
+  TestingPrefServiceSimple pref_service;
+  CleanExitBeacon::RegisterPrefs(pref_service.registry());
+  base::HistogramTester histogram_tester;
+
+  CleanExitBeacon clean_exit_beacon(kDummyWindowsRegistryKey, &pref_service);
+  histogram_tester.ExpectUniqueSample("Variations.SafeMode.Streak.Crashes", 0,
+                                      1);
+}
+
+TEST(CleanExitBeaconTest, CrashStreakMetricWithNoCrashes) {
+  TestingPrefServiceSimple pref_service;
+  CleanExitBeacon::RegisterPrefs(pref_service.registry());
+  // The default value for kStabilityExitedCleanly is true, but defaults can
+  // change, so we explicitly set it to true here. Similarly, we explicitly set
+  // kVariationsCrashStreak to 0.
+  pref_service.SetBoolean(prefs::kStabilityExitedCleanly, true);
+  pref_service.SetInteger(variations::prefs::kVariationsCrashStreak, 0);
+  base::HistogramTester histogram_tester;
+
+  CleanExitBeacon clean_exit_beacon(kDummyWindowsRegistryKey, &pref_service);
+  histogram_tester.ExpectUniqueSample("Variations.SafeMode.Streak.Crashes", 0,
+                                      1);
+}
+
+TEST(CleanExitBeaconTest, CrashStreakMetricWithSomeCrashes) {
+  TestingPrefServiceSimple pref_service;
+  CleanExitBeacon::RegisterPrefs(pref_service.registry());
+  // The default value for kStabilityExitedCleanly is true, but defaults can
+  // change, so we explicitly set it to true here.
+  pref_service.SetBoolean(prefs::kStabilityExitedCleanly, true);
+  pref_service.SetInteger(variations::prefs::kVariationsCrashStreak, 1);
+  base::HistogramTester histogram_tester;
+
+  CleanExitBeacon clean_exit_beacon(kDummyWindowsRegistryKey, &pref_service);
+  histogram_tester.ExpectUniqueSample("Variations.SafeMode.Streak.Crashes", 1,
+                                      1);
+}
+
+TEST(CleanExitBeaconTest, CrashIncrementsCrashStreak) {
+  TestingPrefServiceSimple pref_service;
+  CleanExitBeacon::RegisterPrefs(pref_service.registry());
+  pref_service.SetBoolean(prefs::kStabilityExitedCleanly, false);
+  pref_service.SetInteger(variations::prefs::kVariationsCrashStreak, 1);
+  base::HistogramTester histogram_tester;
+
+  CleanExitBeacon clean_exit_beacon(kDummyWindowsRegistryKey, &pref_service);
+  EXPECT_EQ(pref_service.GetInteger(variations::prefs::kVariationsCrashStreak),
+            2);
+  histogram_tester.ExpectUniqueSample("Variations.SafeMode.Streak.Crashes", 2,
+                                      1);
+}
+
+TEST(CleanExitBeaconTest,
+     CrashIncrementsCrashStreakWithDefaultCrashStreakPref) {
+  TestingPrefServiceSimple pref_service;
+  CleanExitBeacon::RegisterPrefs(pref_service.registry());
+  pref_service.SetBoolean(prefs::kStabilityExitedCleanly, false);
+  base::HistogramTester histogram_tester;
+
+  CleanExitBeacon clean_exit_beacon(kDummyWindowsRegistryKey, &pref_service);
+  EXPECT_EQ(pref_service.GetInteger(variations::prefs::kVariationsCrashStreak),
+            1);
+  histogram_tester.ExpectUniqueSample("Variations.SafeMode.Streak.Crashes", 1,
+                                      1);
+}
+
+}  // namespace metrics
diff --git a/components/metrics/serialization/serialization_utils.cc b/components/metrics/serialization/serialization_utils.cc
index 223d0cb..4ab151b 100644
--- a/components/metrics/serialization/serialization_utils.cc
+++ b/components/metrics/serialization/serialization_utils.cc
@@ -10,6 +10,7 @@
 
 #include <utility>
 
+#include "base/containers/span.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
@@ -205,15 +206,14 @@
   // The file containing the metrics samples will only be read by programs on
   // the same device so we do not check endianness.
   uint32_t encoded_size = base::checked_cast<uint32_t>(size);
-  if (!base::WriteFileDescriptor(file_descriptor.get(),
-                                 reinterpret_cast<char*>(&encoded_size),
-                                 sizeof(uint32_t))) {
+  if (!base::WriteFileDescriptor(
+          file_descriptor.get(),
+          base::as_bytes(base::make_span(&encoded_size, 1)))) {
     DPLOG(ERROR) << "error writing message length: " << filename;
     return false;
   }
 
-  if (!base::WriteFileDescriptor(
-          file_descriptor.get(), msg.c_str(), msg.size())) {
+  if (!base::WriteFileDescriptor(file_descriptor.get(), msg)) {
     DPLOG(ERROR) << "error writing message: " << filename;
     return false;
   }
diff --git a/components/page_info/page_info_ui_delegate.h b/components/page_info/page_info_ui_delegate.h
index 7bd78f6..6dd91870 100644
--- a/components/page_info/page_info_ui_delegate.h
+++ b/components/page_info/page_info_ui_delegate.h
@@ -8,19 +8,15 @@
 #include "build/build_config.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "components/permissions/permission_result.h"
-#include "url/gurl.h"
 
 class PageInfoUiDelegate {
  public:
   virtual ~PageInfoUiDelegate() = default;
 #if !defined(OS_ANDROID)
   virtual bool IsBlockAutoPlayEnabled() = 0;
-  virtual bool ShouldShowSiteSettings() = 0;
 #endif
   virtual permissions::PermissionResult GetPermissionStatus(
       ContentSettingsType type) = 0;
-  virtual bool ShouldShowAllow(ContentSettingsType type) = 0;
-  virtual bool ShouldShowAsk(ContentSettingsType type) = 0;
 };
 
 #endif  // COMPONENTS_PAGE_INFO_PAGE_INFO_UI_DELEGATE_H_
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc
index b5cb450..7ec2d0b5 100644
--- a/components/password_manager/core/browser/password_manager_util.cc
+++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -87,11 +87,6 @@
   return password_manager::SyncState::kAccountPasswordsActiveNormalEncryption;
 }
 
-bool IsSyncingWithNormalEncryption(const syncer::SyncService* sync_service) {
-  return GetPasswordSyncState(sync_service) ==
-         password_manager::SyncState::kSyncingNormalEncryption;
-}
-
 void TrimUsernameOnlyCredentials(
     std::vector<std::unique_ptr<PasswordForm>>* android_credentials) {
   // Remove username-only credentials which are not federated.
diff --git a/components/password_manager/core/browser/password_manager_util.h b/components/password_manager/core/browser/password_manager_util.h
index f3273708..05546a23 100644
--- a/components/password_manager/core/browser/password_manager_util.h
+++ b/components/password_manager/core/browser/password_manager_util.h
@@ -44,10 +44,6 @@
 password_manager::SyncState GetPasswordSyncState(
     const syncer::SyncService* sync_service);
 
-// Reports whether passwords are synced with normal encryption, i.e. without a
-// custom passphrase.
-bool IsSyncingWithNormalEncryption(const syncer::SyncService* sync_service);
-
 // Removes Android username-only credentials from |android_credentials|.
 // Transforms federated credentials into non zero-click ones.
 void TrimUsernameOnlyCredentials(
diff --git a/components/payments/content/installable_payment_app_crawler.cc b/components/payments/content/installable_payment_app_crawler.cc
index d84e79de..9b391fc2 100644
--- a/components/payments/content/installable_payment_app_crawler.cc
+++ b/components/payments/content/installable_payment_app_crawler.cc
@@ -166,8 +166,7 @@
     return;
 
   content::PermissionController* permission_controller =
-      content::BrowserContext::GetPermissionController(
-          rfh->GetBrowserContext());
+      rfh->GetBrowserContext()->GetPermissionController();
   DCHECK(permission_controller);
 
   for (const auto& web_app_manifest_url : default_applications) {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 3627b88..641099f 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -17357,7 +17357,7 @@
       'owners': ['vecore@google.com', 'hansberry@chromium.org', 'better-together-dev@google.com'],
       'type': 'main',
       'schema': { 'type': 'boolean' },
-      'future_on': ['chrome_os'],
+      'supported_on': ['chrome_os:91-'],
       'features': {
         'dynamic_refresh': True,
         'per_profile': True,
diff --git a/components/policy/tools/syntax_check_policy_template_json.py b/components/policy/tools/syntax_check_policy_template_json.py
index 887ae6f..437587f6 100755
--- a/components/policy/tools/syntax_check_policy_template_json.py
+++ b/components/policy/tools/syntax_check_policy_template_json.py
@@ -1896,7 +1896,7 @@
           'bypass this validation by adding "BYPASS_POLICY_COMPATIBILITY_CHECK='
           '<justification>" to your changelist description. If you believe '
           'that this validation is a bug, please file a crbug against '
-          '"Enterprise>CloudPolicy" and add a link to the bug as '
+          '"Enterprise" and add a link to the bug as '
           'justification. Otherwise, please provide an explanation for the '
           'change. For more information please refer to: '
           'https://bit.ly/33qr3ZV.')
diff --git a/components/policy_strings_grdp/DIR_METADATA b/components/policy_strings_grdp/DIR_METADATA
index ccb8f65..04f1804 100644
--- a/components/policy_strings_grdp/DIR_METADATA
+++ b/components/policy_strings_grdp/DIR_METADATA
@@ -1,5 +1,5 @@
 monorail {
-  component: "Enterprise>CloudPolicy"
+  component: "Enterprise"
 }
 
-team_email: "chromium-reviews@chromium.org"
+team_email: "chromium-enterprise@chromium.org"
diff --git a/components/services/app_service/public/cpp/app_update.cc b/components/services/app_service/public/cpp/app_update.cc
index 377f3bc..a7f324a 100644
--- a/components/services/app_service/public/cpp/app_update.cc
+++ b/components/services/app_service/public/cpp/app_update.cc
@@ -131,9 +131,6 @@
   if (delta->resize_locked != apps::mojom::OptionalBool::kUnknown) {
     state->resize_locked = delta->resize_locked;
   }
-  if (delta->preferred_app != apps::mojom::OptionalBool::kUnknown) {
-    state->preferred_app = delta->preferred_app;
-  }
 
   // When adding new fields to the App Mojo type, this function should also be
   // updated.
@@ -545,22 +542,6 @@
          (!state_ || (delta_->resize_locked != state_->resize_locked));
 }
 
-apps::mojom::OptionalBool AppUpdate::PreferredApp() const {
-  if (delta_ &&
-      (delta_->preferred_app != apps::mojom::OptionalBool::kUnknown)) {
-    return delta_->preferred_app;
-  }
-  if (state_)
-    return state_->preferred_app;
-  return apps::mojom::OptionalBool::kUnknown;
-}
-
-bool AppUpdate::PreferredAppChanged() const {
-  return delta_ &&
-         (delta_->preferred_app != apps::mojom::OptionalBool::kUnknown) &&
-         (!state_ || (delta_->preferred_app != state_->preferred_app));
-}
-
 const ::AccountId& AppUpdate::AccountId() const {
   return account_id_;
 }
diff --git a/components/services/app_service/public/cpp/app_update.h b/components/services/app_service/public/cpp/app_update.h
index cca4bde..1699333b 100644
--- a/components/services/app_service/public/cpp/app_update.h
+++ b/components/services/app_service/public/cpp/app_update.h
@@ -136,9 +136,6 @@
   apps::mojom::OptionalBool ResizeLocked() const;
   bool ResizeLockedChanged() const;
 
-  apps::mojom::OptionalBool PreferredApp() const;
-  bool PreferredAppChanged() const;
-
   const ::AccountId& AccountId() const;
 
  private:
diff --git a/components/services/app_service/public/cpp/preferred_apps_list.cc b/components/services/app_service/public/cpp/preferred_apps_list.cc
index a11dfec..1aec810 100644
--- a/components/services/app_service/public/cpp/preferred_apps_list.cc
+++ b/components/services/app_service/public/cpp/preferred_apps_list.cc
@@ -188,6 +188,15 @@
 
 void PreferredAppsList::Init(PreferredApps& preferred_apps) {
   Clone(preferred_apps, &preferred_apps_);
+  auto iter = preferred_apps_.begin();
+  while (iter != preferred_apps_.end()) {
+    if (IsSupportedLink((*iter)->intent_filter)) {
+      for (auto& obs : observers_) {
+        obs.OnPreferredAppChanged((*iter)->app_id, true);
+      }
+    }
+    iter++;
+  }
   initialized_ = true;
 }
 
diff --git a/components/services/app_service/public/mojom/types.mojom b/components/services/app_service/public/mojom/types.mojom
index dbf521f..75a1af44 100644
--- a/components/services/app_service/public/mojom/types.mojom
+++ b/components/services/app_service/public/mojom/types.mojom
@@ -72,9 +72,6 @@
   // operations will be restricted.
   OptionalBool resize_locked;
 
-  // If true, this app is used as a preferred app for its given intent filters.
-  OptionalBool preferred_app;
-
   // When adding new fields, also update the Merge method and other helpers in
   // components/services/app_service/public/cpp/app_update.*
 };
diff --git a/components/sync/protocol/proto_enum_conversions.cc b/components/sync/protocol/proto_enum_conversions.cc
index 1896fd3..aad9485d 100644
--- a/components/sync/protocol/proto_enum_conversions.cc
+++ b/components/sync/protocol/proto_enum_conversions.cc
@@ -516,11 +516,12 @@
 }
 
 const char* ProtoEnumToString(sync_pb::WebAppIconInfo::Purpose purpose) {
-  ASSERT_ENUM_BOUNDS(sync_pb::WebAppIconInfo, Purpose, UNSPECIFIED, MASKABLE);
+  ASSERT_ENUM_BOUNDS(sync_pb::WebAppIconInfo, Purpose, UNSPECIFIED, MONOCHROME);
   switch (purpose) {
     ENUM_CASE(sync_pb::WebAppIconInfo, UNSPECIFIED);
     ENUM_CASE(sync_pb::WebAppIconInfo, ANY);
     ENUM_CASE(sync_pb::WebAppIconInfo, MASKABLE);
+    ENUM_CASE(sync_pb::WebAppIconInfo, MONOCHROME);
   }
   NOTREACHED();
   return "";
diff --git a/components/sync/protocol/web_app_specifics.proto b/components/sync/protocol/web_app_specifics.proto
index 52b075a..198bd6c 100644
--- a/components/sync/protocol/web_app_specifics.proto
+++ b/components/sync/protocol/web_app_specifics.proto
@@ -23,7 +23,8 @@
     ANY = 1;
     // Designed for masking.
     MASKABLE = 2;
-    // MONOCHROME; is never serialized.
+    // Suitable for monochrome purposes.
+    MONOCHROME = 3;
   }
 
   // The size of the square app icon, in raw pixels.
diff --git a/components/variations/service/safe_seed_manager.cc b/components/variations/service/safe_seed_manager.cc
index e82dd986..b44a0d5 100644
--- a/components/variations/service/safe_seed_manager.cc
+++ b/components/variations/service/safe_seed_manager.cc
@@ -9,6 +9,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/ranges.h"
+#include "components/prefs/pref_registry.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/variations/client_filterable_state.h"
@@ -64,24 +65,10 @@
 // to find a better balance here.
 constexpr int kFetchFailureStreakThreshold = 25;
 
-SafeSeedManager::SafeSeedManager(bool did_previous_session_exit_cleanly,
-                                 PrefService* local_state)
+SafeSeedManager::SafeSeedManager(PrefService* local_state)
     : local_state_(local_state) {
-  // Increment the crash streak if the previous session crashed.
-  // Note that the streak is not cleared if the previous run didn’t crash.
-  // Instead, it’s incremented on each crash until Chrome is able to
-  // successfully fetch a new seed. This way, a seed update that mostly
-  // destabilizes Chrome will still result in a fallback to safe mode.
-  int num_crashes = local_state->GetInteger(prefs::kVariationsCrashStreak);
-  if (!did_previous_session_exit_cleanly) {
-    ++num_crashes;
-    local_state->SetInteger(prefs::kVariationsCrashStreak, num_crashes);
-  }
-
   int num_failed_fetches =
-      local_state->GetInteger(prefs::kVariationsFailedToFetchSeedStreak);
-  base::UmaHistogramSparse("Variations.SafeMode.Streak.Crashes",
-                           base::ClampToRange(num_crashes, 0, 100));
+      local_state_->GetInteger(prefs::kVariationsFailedToFetchSeedStreak);
   base::UmaHistogramSparse("Variations.SafeMode.Streak.FetchFailures",
                            base::ClampToRange(num_failed_fetches, 0, 100));
 }
@@ -90,8 +77,14 @@
 
 // static
 void SafeSeedManager::RegisterPrefs(PrefRegistrySimple* registry) {
-  // Prefs tracking failures along the way to fetching a seed.
-  registry->RegisterIntegerPref(prefs::kVariationsCrashStreak, 0);
+  // Verify that the crash streak pref has already been registered.
+  DCHECK(
+      registry->defaults()->GetValue(prefs::kVariationsCrashStreak, nullptr));
+
+  // Registers one of two prefs used for tracking variations-seed-related
+  // failures. The other pref, kVariationsCrashStreak, is registered in
+  // CleanExitBeacon::RegisterPrefs(). See components/metrics/
+  // clean_exit_beacon.cc for more details.
   registry->RegisterIntegerPref(prefs::kVariationsFailedToFetchSeedStreak, 0);
 }
 
diff --git a/components/variations/service/safe_seed_manager.h b/components/variations/service/safe_seed_manager.h
index 5855f7a0..610e403 100644
--- a/components/variations/service/safe_seed_manager.h
+++ b/components/variations/service/safe_seed_manager.h
@@ -22,13 +22,12 @@
 // The primary class that encapsulates state for managing the safe seed.
 class SafeSeedManager {
  public:
-  // Creates a SafeSeedManager instance, and updates safe mode prefs for
-  // bookkeeping.
-  SafeSeedManager(bool did_previous_session_exit_cleanly,
-                  PrefService* local_state);
+  // Creates a SafeSeedManager instance and updates a safe mode pref,
+  // kVariationsFailedToFetchSeedStreak, for bookkeeping.
+  explicit SafeSeedManager(PrefService* local_state);
   virtual ~SafeSeedManager();
 
-  // Register safe mode prefs in Local State.
+  // Registers safe mode prefs in Local State.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
   // Returns true iff the client should use the safe seed for variations state.
@@ -83,8 +82,8 @@
   // The active seed state must never be set more than once.
   bool has_set_active_seed_state_ = false;
 
-  // The pref service used to store persist the variations seed. Weak reference;
-  // must outlive |this| instance.
+  // The pref service used to persist the variations seed. Weak reference; must
+  // outlive |this| instance.
   PrefService* local_state_;
 
   DISALLOW_COPY_AND_ASSIGN(SafeSeedManager);
diff --git a/components/variations/service/safe_seed_manager_unittest.cc b/components/variations/service/safe_seed_manager_unittest.cc
index 40d3b11..31abfaab 100644
--- a/components/variations/service/safe_seed_manager_unittest.cc
+++ b/components/variations/service/safe_seed_manager_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
+#include "components/metrics/clean_exit_beacon.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/variations/client_filterable_state.h"
 #include "components/variations/pref_names.h"
@@ -109,7 +110,10 @@
 
 class SafeSeedManagerTest : public testing::Test {
  public:
-  SafeSeedManagerTest() { SafeSeedManager::RegisterPrefs(prefs_.registry()); }
+  SafeSeedManagerTest() {
+    metrics::CleanExitBeacon::RegisterPrefs(prefs_.registry());
+    SafeSeedManager::RegisterPrefs(prefs_.registry());
+  }
   ~SafeSeedManagerTest() override = default;
 
  protected:
@@ -117,7 +121,7 @@
 };
 
 TEST_F(SafeSeedManagerTest, RecordSuccessfulFetch_FirstCallSavesSafeSeed) {
-  SafeSeedManager safe_seed_manager(true, &prefs_);
+  SafeSeedManager safe_seed_manager(&prefs_);
   SetDefaultActiveState(&safe_seed_manager);
 
   FakeSeedStore seed_store(&prefs_);
@@ -127,7 +131,7 @@
 }
 
 TEST_F(SafeSeedManagerTest, RecordSuccessfulFetch_RepeatedCallsRetainSafeSeed) {
-  SafeSeedManager safe_seed_manager(true, &prefs_);
+  SafeSeedManager safe_seed_manager(&prefs_);
   SetDefaultActiveState(&safe_seed_manager);
 
   FakeSeedStore seed_store(&prefs_);
@@ -140,7 +144,7 @@
 
 TEST_F(SafeSeedManagerTest,
        RecordSuccessfulFetch_NoActiveState_DoesntSaveSafeSeed) {
-  SafeSeedManager safe_seed_manager(true, &prefs_);
+  SafeSeedManager safe_seed_manager(&prefs_);
   // Omit setting any active state.
 
   FakeSeedStore seed_store(&prefs_);
@@ -155,59 +159,31 @@
   EXPECT_EQ(base::Time(), seed_store.fetch_time());
 }
 
-TEST_F(SafeSeedManagerTest, StreakMetrics_NoPrefs) {
+TEST_F(SafeSeedManagerTest, FetchFailureMetrics_DefaultPrefs) {
   base::HistogramTester histogram_tester;
-  SafeSeedManager safe_seed_manager(true, &prefs_);
-  histogram_tester.ExpectUniqueSample("Variations.SafeMode.Streak.Crashes", 0,
-                                      1);
+  SafeSeedManager safe_seed_manager(&prefs_);
   histogram_tester.ExpectUniqueSample(
       "Variations.SafeMode.Streak.FetchFailures", 0, 1);
 }
 
-TEST_F(SafeSeedManagerTest, StreakMetrics_NoCrashes_NoFetchFailures) {
-  prefs_.SetInteger(prefs::kVariationsCrashStreak, 0);
+TEST_F(SafeSeedManagerTest, FetchFailureMetrics_NoFailures) {
   prefs_.SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 0);
 
   base::HistogramTester histogram_tester;
-  SafeSeedManager safe_seed_manager(true, &prefs_);
-  histogram_tester.ExpectUniqueSample("Variations.SafeMode.Streak.Crashes", 0,
-                                      1);
+  SafeSeedManager safe_seed_manager(&prefs_);
   histogram_tester.ExpectUniqueSample(
       "Variations.SafeMode.Streak.FetchFailures", 0, 1);
 }
 
-TEST_F(SafeSeedManagerTest, StreakMetrics_SomeCrashes_SomeFetchFailures) {
-  prefs_.SetInteger(prefs::kVariationsCrashStreak, 1);
+TEST_F(SafeSeedManagerTest, FetchFailureMetrics_SomeFailures) {
   prefs_.SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 2);
 
   base::HistogramTester histogram_tester;
-  SafeSeedManager safe_seed_manager(true, &prefs_);
-  histogram_tester.ExpectUniqueSample("Variations.SafeMode.Streak.Crashes", 1,
-                                      1);
+  SafeSeedManager safe_seed_manager(&prefs_);
   histogram_tester.ExpectUniqueSample(
       "Variations.SafeMode.Streak.FetchFailures", 2, 1);
 }
 
-TEST_F(SafeSeedManagerTest, StreakMetrics_CrashIncrementsCrashStreak) {
-  prefs_.SetInteger(prefs::kVariationsCrashStreak, 1);
-
-  base::HistogramTester histogram_tester;
-  SafeSeedManager safe_seed_manager(false, &prefs_);
-
-  EXPECT_EQ(2, prefs_.GetInteger(prefs::kVariationsCrashStreak));
-  histogram_tester.ExpectUniqueSample("Variations.SafeMode.Streak.Crashes", 2,
-                                      1);
-}
-
-TEST_F(SafeSeedManagerTest, StreakMetrics_CrashIncrementsCrashStreak_NoPrefs) {
-  base::HistogramTester histogram_tester;
-  SafeSeedManager safe_seed_manager(false, &prefs_);
-
-  EXPECT_EQ(1, prefs_.GetInteger(prefs::kVariationsCrashStreak));
-  histogram_tester.ExpectUniqueSample("Variations.SafeMode.Streak.Crashes", 1,
-                                      1);
-}
-
 TEST_F(SafeSeedManagerTest, ShouldRunInSafeMode_OverriddenByCommandlineFlag) {
   // So many failures.
   prefs_.SetInteger(prefs::kVariationsCrashStreak, 100);
@@ -215,7 +191,7 @@
   base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
       ::switches::kForceFieldTrials, "SomeFieldTrial");
 
-  SafeSeedManager safe_seed_manager(true, &prefs_);
+  SafeSeedManager safe_seed_manager(&prefs_);
   EXPECT_FALSE(safe_seed_manager.ShouldRunInSafeMode());
 }
 
@@ -223,14 +199,14 @@
   prefs_.SetInteger(prefs::kVariationsCrashStreak, 0);
   prefs_.SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 0);
 
-  SafeSeedManager safe_seed_manager(true, &prefs_);
+  SafeSeedManager safe_seed_manager(&prefs_);
   EXPECT_FALSE(safe_seed_manager.ShouldRunInSafeMode());
 }
 
 TEST_F(SafeSeedManagerTest, ShouldRunInSafeMode_NoPrefs) {
   // Don't explicitly set either of the prefs. The implicit/default values
   // should be zero.
-  SafeSeedManager safe_seed_manager(true, &prefs_);
+  SafeSeedManager safe_seed_manager(&prefs_);
   EXPECT_FALSE(safe_seed_manager.ShouldRunInSafeMode());
 }
 
@@ -238,7 +214,7 @@
   prefs_.SetInteger(prefs::kVariationsCrashStreak, 2);
   prefs_.SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 2);
 
-  SafeSeedManager safe_seed_manager(true, &prefs_);
+  SafeSeedManager safe_seed_manager(&prefs_);
   EXPECT_FALSE(safe_seed_manager.ShouldRunInSafeMode());
 }
 
@@ -246,7 +222,7 @@
   prefs_.SetInteger(prefs::kVariationsCrashStreak, 3);
   prefs_.SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 0);
 
-  SafeSeedManager safe_seed_manager(true, &prefs_);
+  SafeSeedManager safe_seed_manager(&prefs_);
   EXPECT_TRUE(safe_seed_manager.ShouldRunInSafeMode());
 }
 
@@ -254,7 +230,7 @@
   prefs_.SetInteger(prefs::kVariationsCrashStreak, 0);
   prefs_.SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 50);
 
-  SafeSeedManager safe_seed_manager(true, &prefs_);
+  SafeSeedManager safe_seed_manager(&prefs_);
   EXPECT_TRUE(safe_seed_manager.ShouldRunInSafeMode());
 }
 
@@ -262,7 +238,7 @@
   prefs_.SetInteger(prefs::kVariationsCrashStreak, 3);
   prefs_.SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 50);
 
-  SafeSeedManager safe_seed_manager(true, &prefs_);
+  SafeSeedManager safe_seed_manager(&prefs_);
   EXPECT_TRUE(safe_seed_manager.ShouldRunInSafeMode());
 }
 
diff --git a/components/variations/service/variations_field_trial_creator_unittest.cc b/components/variations/service/variations_field_trial_creator_unittest.cc
index 7b0ac056..6980d55e 100644
--- a/components/variations/service/variations_field_trial_creator_unittest.cc
+++ b/components/variations/service/variations_field_trial_creator_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/version.h"
 #include "build/build_config.h"
+#include "components/metrics/clean_exit_beacon.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/variations/platform_field_trials.h"
 #include "components/variations/pref_names.h"
@@ -128,7 +129,7 @@
 class MockSafeSeedManager : public SafeSeedManager {
  public:
   explicit MockSafeSeedManager(PrefService* local_state)
-      : SafeSeedManager(true, local_state) {}
+      : SafeSeedManager(local_state) {}
   ~MockSafeSeedManager() override = default;
 
   MOCK_CONST_METHOD0(ShouldRunInSafeMode, bool());
@@ -269,6 +270,7 @@
 class FieldTrialCreatorTest : public ::testing::Test {
  protected:
   FieldTrialCreatorTest() {
+    metrics::CleanExitBeacon::RegisterPrefs(prefs_.registry());
     VariationsService::RegisterPrefs(prefs_.registry());
     global_feature_list_ = base::FeatureList::ClearInstanceForTesting();
   }
diff --git a/components/variations/service/variations_service.cc b/components/variations/service/variations_service.cc
index 4217905..98baea86 100644
--- a/components/variations/service/variations_service.cc
+++ b/components/variations/service/variations_service.cc
@@ -359,8 +359,7 @@
       disable_deltas_for_next_request_(false),
       resource_request_allowed_notifier_(std::move(notifier)),
       request_count_(0),
-      safe_seed_manager_(state_manager->clean_exit_beacon()->exited_cleanly(),
-                         local_state),
+      safe_seed_manager_(local_state),
       field_trial_creator_(local_state,
                            client_.get(),
                            std::make_unique<VariationsSeedStore>(
diff --git a/components/variations/service/variations_service_unittest.cc b/components/variations/service/variations_service_unittest.cc
index d9b01e8..8c73177 100644
--- a/components/variations/service/variations_service_unittest.cc
+++ b/components/variations/service/variations_service_unittest.cc
@@ -306,8 +306,8 @@
       : network_tracker_(network::TestNetworkConnectionTracker::GetInstance()),
         enabled_state_provider_(
             new metrics::TestEnabledStateProvider(false, false)) {
-    VariationsService::RegisterPrefs(prefs_.registry());
     metrics::CleanExitBeacon::RegisterPrefs(prefs_.registry());
+    VariationsService::RegisterPrefs(prefs_.registry());
     metrics::MetricsStateManager::RegisterPrefs(prefs_.registry());
   }
 
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
index 02244c7..a1d13df 100644
--- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
+++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -11,6 +11,7 @@
 
 #include "base/bind.h"
 #include "base/check_op.h"
+#include "base/containers/queue.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc
index cc0bef10..9b0c14e 100644
--- a/content/browser/back_forward_cache_browsertest.cc
+++ b/content/browser/back_forward_cache_browsertest.cc
@@ -6439,6 +6439,11 @@
 // page.
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestWithBlockedWebsites,
                        NavigateFromAllowedPageToDisallowedPage) {
+  // Skip checking the AllSites metrics since BackForwardCacheMetrics stop
+  // recording except BackForwardCache.AllSites.* metrics when the target URL is
+  // disallowed by allowed_websites or blocked_websites.
+  DisableCheckingMetricsForAllSites();
+
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url_a(embedded_test_server()->GetURL(
       "a.allowed", "/back_forward_cache/allowed_path.html"));
@@ -6458,7 +6463,7 @@
   RenderFrameDeletedObserver delete_observer_rfh_b(rfh_b);
 
   // 3) Check if rfh_a is stored in back-forward cache, since it doesn't match
-  // to the |blocked_websites|, and |allowed_websites| are empty, so it should
+  // to the blocked_websites, and allowed_websites are empty, so it should
   // be stored.
   EXPECT_FALSE(delete_observer_rfh_a.deleted());
   EXPECT_TRUE(rfh_a->IsInBackForwardCache());
@@ -6467,17 +6472,31 @@
   web_contents()->GetController().GoBack();
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   EXPECT_EQ(rfh_a, current_frame_host());
+  ExpectRestored(FROM_HERE);
 
   // 5) Check if rfh_b is not stored in back-forward cache, since it matches to
-  // the |blocked_websites|.
+  // the blocked_websites.
   delete_observer_rfh_b.WaitUntilDeleted();
   EXPECT_TRUE(delete_observer_rfh_b.deleted());
+
+  // 6) Go forward to B. B should not restored from the back-forward cache.
+  web_contents()->GetController().GoForward();
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+  // Nothing is recorded since B is disallowed.
+  ExpectOutcomeDidNotChange(FROM_HERE);
+  ExpectNotRestoredDidNotChange(FROM_HERE);
 }
 
 // Check the allowed page is bfcached when it's navigated from disallowed
 // page.
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestWithBlockedWebsites,
                        NavigateFromDisallowedPageToAllowedPage) {
+  // Skip checking the AllSites metrics since BackForwardCacheMetrics stop
+  // recording except BackForwardCache.AllSites.* metrics when the target URL is
+  // disallowed by allowed_websites or blocked_websites.
+  DisableCheckingMetricsForAllSites();
+
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url_a(embedded_test_server()->GetURL(
       "a.blocked", "/back_forward_cache/disallowed_path.html"));
@@ -6497,7 +6516,7 @@
   RenderFrameDeletedObserver delete_observer_rfh_b(rfh_b);
 
   // 3) Check if rfh_a is not stored in back-forward cache, since it matches to
-  // the |blocked_websites|.
+  // the blocked_websites.
   delete_observer_rfh_a.WaitUntilDeleted();
   EXPECT_TRUE(delete_observer_rfh_a.deleted());
 
@@ -6505,11 +6524,186 @@
   web_contents()->GetController().GoBack();
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
 
+  // Nothing is recorded since A is disallowed.
+  ExpectOutcomeDidNotChange(FROM_HERE);
+  ExpectNotRestoredDidNotChange(FROM_HERE);
+
   // 5) Check if rfh_b is stored in back-forward cache, since it doesn't match
-  // to the |blocked_websites|, and |allowed_websites| are empty, so it should
+  // to the blocked_websites, and allowed_websites are empty, so it should
   // be stored.
   EXPECT_FALSE(delete_observer_rfh_b.deleted());
   EXPECT_TRUE(rfh_b->IsInBackForwardCache());
+
+  // 6) Go forward to url_b which is bfcached.
+  web_contents()->GetController().GoForward();
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+  ExpectRestored(FROM_HERE);
+}
+
+// Test BackForwardCache::IsAllowed() with several allowed_websites URL
+// patterns.
+class BackForwardCacheBrowserTestForAllowedWebsitesUrlPatterns
+    : public BackForwardCacheBrowserTest {
+ protected:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    // Sets the allowed websites for testing, additionally adding the params
+    // used by BackForwardCacheBrowserTest.
+    std::string allowed_websites =
+        "https://a.com/,"
+        "https://b.com/path,"
+        "https://c.com/path/";
+    EnableFeatureAndSetParams(features::kBackForwardCache, "allowed_websites",
+                              allowed_websites);
+
+    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
+  }
+};
+
+// Check if the URLs are allowed when allowed_websites are specified.
+IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestForAllowedWebsitesUrlPatterns,
+                       AllowedWebsitesUrlPatterns) {
+  BackForwardCacheImpl& bfcache =
+      web_contents()->GetController().GetBackForwardCache();
+
+  // Doesn't match with any allowed_websites.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://a.org/")));
+
+  // Exact match with https://a.com/.
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://a.com/")));
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://a.com")));
+
+  // Match with https://a.com/ since we don't take into account the difference
+  // on port number.
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://a.com:123/")));
+
+  // Match with https://a.com/ since we don't take into account the difference
+  // on query.
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://a.com:123/?x=1")));
+
+  // Match with https://a.com/ since we don't take into account the difference
+  // on scheme.
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("http://a.com/")));
+
+  // Match with https://a.com/ since we are checking the prefix on path.
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://a.com/path")));
+
+  // Doesn't match with https://a.com/ since the host doesn't match with a.com.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://prefix.a.com/")));
+
+  // Doesn't match with https://b.com/path since the path prefix doesn't match.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://b.com/")));
+
+  // Exact match with https://b.com/path.
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://b.com/path")));
+
+  // Match with https://b.com/path since we are checking the prefix on path.
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://b.com/path/")));
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://b.com/path_abc")));
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://b.com/path_abc?x=1")));
+
+  // Doesn't match with https://c.com/path/ since the path prefix doesn't match.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://c.com/path")));
+}
+
+// Test BackForwardCache::IsAllowed() with several blocked_websites URL
+// patterns.
+class BackForwardCacheBrowserTestForBlockedWebsitesUrlPatterns
+    : public BackForwardCacheBrowserTest {
+ protected:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    // Sets the blocked websites for testing, additionally adding the params
+    // used by BackForwardCacheBrowserTest.
+    std::string blocked_websites =
+        "https://a.com/,"
+        "https://b.com/path,"
+        "https://c.com/path/";
+    EnableFeatureAndSetParams(features::kBackForwardCache, "blocked_websites",
+                              blocked_websites);
+
+    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
+  }
+};
+
+// Check if the URLs are allowed when blocked_websites are specified.
+IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestForBlockedWebsitesUrlPatterns,
+                       BlockedWebsitesUrlPatterns) {
+  BackForwardCacheImpl& bfcache =
+      web_contents()->GetController().GetBackForwardCache();
+
+  // Doesn't match with any blocked_websites.
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://a.org/")));
+
+  // Exact match with https://a.com/.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://a.com/")));
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://a.com")));
+
+  // Match with https://a.com/ since we don't take into account the difference
+  // on port number.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://a.com:123/")));
+
+  // Match with https://a.com/ since we don't take into account the difference
+  // on query.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://a.com:123/?x=1")));
+
+  // Match with https://a.com/ since we don't take into account the difference
+  // on scheme.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("http://a.com/")));
+
+  // Match with https://a.com/ since we are checking the prefix on path.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://a.com/path")));
+
+  // Doesn't match with https://a.com/ since the host doesn't match with a.com.
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://prefix.a.com/")));
+
+  // Doesn't match with https://b.com/path since the path prefix doesn't match.
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://b.com/")));
+
+  // Exact match with https://b.com/path.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://b.com/path")));
+
+  // Match with https://b.com/path since we are checking the prefix on path.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://b.com/path/")));
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://b.com/path_abc")));
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://b.com/path_abc?x=1")));
+
+  // Doesn't match with https://c.com/path/ since the path prefix doesn't match.
+  EXPECT_TRUE(bfcache.IsAllowed(GURL("https://c.com/path")));
+}
+
+// Test BackForwardCache::IsAllowed() with several allowed_websites and
+// blocked_websites URL patterns.
+class BackForwardCacheBrowserTestForWebsitesUrlPatterns
+    : public BackForwardCacheBrowserTest {
+ protected:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    // Sets the allowed websites for testing, additionally adding the params
+    // used by BackForwardCacheBrowserTest.
+    std::string allowed_websites = "https://a.com/";
+    EnableFeatureAndSetParams(features::kBackForwardCache, "allowed_websites",
+                              allowed_websites);
+
+    // Sets the blocked websites for testing, additionally adding the params
+    // used by BackForwardCacheBrowserTest.
+    std::string blocked_websites = "https://a.com/";
+    EnableFeatureAndSetParams(features::kBackForwardCache, "blocked_websites",
+                              blocked_websites);
+
+    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
+  }
+};
+
+// Check if the URLs are allowed when allowed_websites and blocked_websites are
+// specified.
+IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestForWebsitesUrlPatterns,
+                       WebsitesUrlPatterns) {
+  BackForwardCacheImpl& bfcache =
+      web_contents()->GetController().GetBackForwardCache();
+
+  // https://a.com/ is not allowed since blocked_websites will be prioritized
+  // when the same website is specified in allowed_websites and
+  // blocked_websites.
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://a.com/")));
+  EXPECT_FALSE(bfcache.IsAllowed(GURL("https://a.com")));
 }
 
 // Check that if WebPreferences was changed while a page was bfcached, it will
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc
index b25d6ea..3e829751 100644
--- a/content/browser/background_sync/background_sync_manager.cc
+++ b/content/browser/background_sync/background_sync_manager.cc
@@ -129,7 +129,7 @@
     return {PermissionStatus::DENIED, PermissionStatus::DENIED};
 
   PermissionController* permission_controller =
-      BrowserContext::GetPermissionController(browser_context);
+      browser_context->GetPermissionController();
   DCHECK(permission_controller);
 
   // The requesting origin always matches the embedding origin.
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc
index 9817f13..f5f2428 100644
--- a/content/browser/browser_context.cc
+++ b/content/browser/browser_context.cc
@@ -122,11 +122,9 @@
   return impl()->GetBrowsingDataRemover();
 }
 
-// static
-PermissionController* BrowserContext::GetPermissionController(
-    BrowserContext* self) {
+PermissionController* BrowserContext::GetPermissionController() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  return self->impl()->GetPermissionController();
+  return impl()->GetPermissionController();
 }
 
 StoragePartition* BrowserContext::GetStoragePartition(
@@ -304,13 +302,11 @@
   impl()->SetDownloadManagerForTesting(std::move(download_manager));  // IN-TEST
 }
 
-// static
 void BrowserContext::SetPermissionControllerForTesting(
-    BrowserContext* self,
     std::unique_ptr<PermissionController> permission_controller) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(permission_controller);
-  self->impl()->SetPermissionControllerForTesting(  // IN-TEST
+  impl()->SetPermissionControllerForTesting(  // IN-TEST
       std::move(permission_controller));
 }
 
diff --git a/content/browser/cross_origin_opener_policy_browsertest.cc b/content/browser/cross_origin_opener_policy_browsertest.cc
index 30774a1..9266656 100644
--- a/content/browser/cross_origin_opener_policy_browsertest.cc
+++ b/content/browser/cross_origin_opener_policy_browsertest.cc
@@ -162,7 +162,6 @@
         // Disabled:
         {
             features::kSharedArrayBuffer,
-            features::kWebAssemblyThreads,
         });
   }
 
@@ -3060,7 +3059,6 @@
         {
             // Disabled
             features::kSharedArrayBuffer,
-            features::kWebAssemblyThreads,
         });
   }
 
@@ -3332,7 +3330,6 @@
         {
             // Disabled
             features::kSharedArrayBuffer,
-            features::kWebAssemblyThreads,
         });
   }
 
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc
index d61f558..4cbfa40 100644
--- a/content/browser/devtools/devtools_instrumentation.cc
+++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -39,7 +39,7 @@
 #include "net/cookies/cookie_inclusion_status.h"
 #include "net/http/http_request_headers.h"
 #include "net/proxy_resolution/proxy_config.h"
-#include "net/quic/quic_transport_error.h"
+#include "net/quic/web_transport_error.h"
 #include "net/ssl/ssl_info.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/mojom/network_context.mojom.h"
@@ -965,7 +965,7 @@
 void OnWebTransportHandshakeFailed(
     RenderFrameHostImpl* frame,
     const GURL& url,
-    const base::Optional<net::QuicTransportError>& error) {
+    const base::Optional<net::WebTransportError>& error) {
   FrameTreeNode* ftn = frame->frame_tree_node();
   if (!ftn)
     return;
@@ -973,7 +973,7 @@
       "Failed to establish a connection to %s", url.spec().c_str());
   if (error) {
     text += ": ";
-    text += net::QuicTransportErrorToString(*error);
+    text += net::WebTransportErrorToString(*error);
   }
   text += ".";
   auto entry = protocol::Log::LogEntry::Create()
diff --git a/content/browser/devtools/devtools_instrumentation.h b/content/browser/devtools/devtools_instrumentation.h
index 32ffbe0..cc024ed 100644
--- a/content/browser/devtools/devtools_instrumentation.h
+++ b/content/browser/devtools/devtools_instrumentation.h
@@ -35,7 +35,7 @@
 namespace net {
 class SSLInfo;
 class X509Certificate;
-struct QuicTransportError;
+struct WebTransportError;
 }  // namespace net
 
 namespace download {
@@ -209,7 +209,7 @@
 void OnWebTransportHandshakeFailed(
     RenderFrameHostImpl* frame_host,
     const GURL& url,
-    const base::Optional<net::QuicTransportError>& error);
+    const base::Optional<net::WebTransportError>& error);
 
 // Adds a debug error message from a worklet to the devtools console.
 void LogWorkletError(RenderFrameHostImpl* frame_host, const std::string& error);
diff --git a/content/browser/file_system/file_system_manager_impl.cc b/content/browser/file_system/file_system_manager_impl.cc
index 9ffc63d..b0f79913 100644
--- a/content/browser/file_system/file_system_manager_impl.cc
+++ b/content/browser/file_system/file_system_manager_impl.cc
@@ -273,10 +273,12 @@
     return;
   }
 
-  operation_runner()->Move(src_url, dest_url,
-                           storage::FileSystemOperation::OPTION_NONE,
-                           base::BindOnce(&FileSystemManagerImpl::DidFinish,
-                                          GetWeakPtr(), std::move(callback)));
+  operation_runner()->Move(
+      src_url, dest_url, storage::FileSystemOperation::OPTION_NONE,
+      FileSystemOperation::ERROR_BEHAVIOR_ABORT,
+      storage::FileSystemOperation::CopyOrMoveProgressCallback(),
+      base::BindOnce(&FileSystemManagerImpl::DidFinish, GetWeakPtr(),
+                     std::move(callback)));
 }
 
 void FileSystemManagerImpl::Copy(const GURL& src_path,
@@ -301,7 +303,7 @@
   operation_runner()->Copy(
       src_url, dest_url, storage::FileSystemOperation::OPTION_NONE,
       FileSystemOperation::ERROR_BEHAVIOR_ABORT,
-      storage::FileSystemOperationRunner::CopyProgressCallback(),
+      storage::FileSystemOperation::CopyOrMoveProgressCallback(),
       base::BindOnce(&FileSystemManagerImpl::DidFinish, GetWeakPtr(),
                      std::move(callback)));
 }
diff --git a/content/browser/file_system_access/file_system_access_file_handle_impl.cc b/content/browser/file_system_access/file_system_access_file_handle_impl.cc
index ee43f7c..4661f7f 100644
--- a/content/browser/file_system_access/file_system_access_file_handle_impl.cc
+++ b/content/browser/file_system_access/file_system_access_file_handle_impl.cc
@@ -357,7 +357,7 @@
       url(), swap_url,
       storage::FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED,
       storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
-      storage::FileSystemOperation::CopyProgressCallback());
+      storage::FileSystemOperation::CopyOrMoveProgressCallback());
 }
 
 void FileSystemAccessFileHandleImpl::DidCopySwapFile(
diff --git a/content/browser/geolocation/geolocation_service_impl_unittest.cc b/content/browser/geolocation/geolocation_service_impl_unittest.cc
index d61e10a..8eac25e 100644
--- a/content/browser/geolocation/geolocation_service_impl_unittest.cc
+++ b/content/browser/geolocation/geolocation_service_impl_unittest.cc
@@ -108,9 +108,10 @@
     navigation_simulator->Commit();
     embedded_rfh = navigation_simulator->GetFinalRenderFrameHost();
 
-    BrowserContext::SetPermissionControllerForTesting(
-        embedded_rfh->GetProcess()->GetBrowserContext(),
-        std::make_unique<PermissionControllerImpl>(browser_context_.get()));
+    embedded_rfh->GetProcess()
+        ->GetBrowserContext()
+        ->SetPermissionControllerForTesting(
+            std::make_unique<PermissionControllerImpl>(browser_context_.get()));
     service_ =
         std::make_unique<GeolocationServiceImpl>(context_.get(), embedded_rfh);
     service_->Bind(service_remote_.BindNewPipeAndPassReceiver());
diff --git a/content/browser/idle/idle_manager_impl.cc b/content/browser/idle/idle_manager_impl.cc
index 83b66e4d..4d2c7bf 100644
--- a/content/browser/idle/idle_manager_impl.cc
+++ b/content/browser/idle/idle_manager_impl.cc
@@ -134,7 +134,7 @@
 
 bool IdleManagerImpl::HasPermission(const url::Origin& origin) {
   PermissionController* permission_controller =
-      BrowserContext::GetPermissionController(browser_context_);
+      browser_context_->GetPermissionController();
   DCHECK(permission_controller);
   PermissionStatus status = permission_controller->GetPermissionStatus(
       PermissionType::IDLE_DETECTION, origin.GetURL(), origin.GetURL());
diff --git a/content/browser/media/media_devices_permission_checker.cc b/content/browser/media/media_devices_permission_checker.cc
index ff5b6c6..32069cf 100644
--- a/content/browser/media/media_devices_permission_checker.cc
+++ b/content/browser/media/media_devices_permission_checker.cc
@@ -170,8 +170,8 @@
   if (!web_contents)
     return false;
 
-  auto* permission_controller = BrowserContext::GetPermissionController(
-      web_contents->GetBrowserContext());
+  auto* permission_controller =
+      web_contents->GetBrowserContext()->GetPermissionController();
   DCHECK(permission_controller);
 
   const GURL& origin = web_contents->GetLastCommittedURL();
diff --git a/content/browser/notifications/blink_notification_service_impl.cc b/content/browser/notifications/blink_notification_service_impl.cc
index cd1f69d..3dab156 100644
--- a/content/browser/notifications/blink_notification_service_impl.cc
+++ b/content/browser/notifications/blink_notification_service_impl.cc
@@ -186,9 +186,8 @@
   // TOOD(crbug.com/987654): It is odd that a service instance can be created
   // for cross-origin subframes, yet the instance is completely oblivious of
   // whether it is serving a top-level browsing context or an embedded one.
-  return BrowserContext::GetPermissionController(browser_context_)
-      ->GetPermissionStatus(PermissionType::NOTIFICATIONS, origin_.GetURL(),
-                            origin_.GetURL());
+  return browser_context_->GetPermissionController()->GetPermissionStatus(
+      PermissionType::NOTIFICATIONS, origin_.GetURL(), origin_.GetURL());
 }
 
 bool BlinkNotificationServiceImpl::ValidateNotificationDataAndResources(
diff --git a/content/browser/notifications/platform_notification_context_impl.cc b/content/browser/notifications/platform_notification_context_impl.cc
index 8db550c..4fd6bb17 100644
--- a/content/browser/notifications/platform_notification_context_impl.cc
+++ b/content/browser/notifications/platform_notification_context_impl.cc
@@ -358,7 +358,7 @@
   }
 
   content::PermissionController* controller =
-      BrowserContext::GetPermissionController(browser_context_);
+      browser_context_->GetPermissionController();
   if (!controller) {
     std::move(callback).Run(/* success= */ false, /* deleted_count= */ 0);
     return;
diff --git a/content/browser/payments/installed_payment_apps_finder_impl.cc b/content/browser/payments/installed_payment_apps_finder_impl.cc
index 2595729..1c9bb55 100644
--- a/content/browser/payments/installed_payment_apps_finder_impl.cc
+++ b/content/browser/payments/installed_payment_apps_finder_impl.cc
@@ -91,7 +91,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   PermissionController* permission_controller =
-      BrowserContext::GetPermissionController(browser_context_);
+      browser_context_->GetPermissionController();
   DCHECK(permission_controller);
 
   PaymentApps permitted_apps;
diff --git a/content/browser/permissions/permission_controller_impl.cc b/content/browser/permissions/permission_controller_impl.cc
index 10726f7..aaa4e7f 100644
--- a/content/browser/permissions/permission_controller_impl.cc
+++ b/content/browser/permissions/permission_controller_impl.cc
@@ -123,7 +123,7 @@
 PermissionControllerImpl* PermissionControllerImpl::FromBrowserContext(
     BrowserContext* browser_context) {
   return static_cast<PermissionControllerImpl*>(
-      BrowserContext::GetPermissionController(browser_context));
+      browser_context->GetPermissionController());
 }
 
 struct PermissionControllerImpl::Subscription {
diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc
index 892fb13..1438d92 100644
--- a/content/browser/permissions/permission_service_impl.cc
+++ b/content/browser/permissions/permission_service_impl.cc
@@ -205,14 +205,14 @@
 
   GURL requesting_origin(origin_.GetURL());
   if (context_->render_frame_host()) {
-    return BrowserContext::GetPermissionController(browser_context)
+    return browser_context->GetPermissionController()
         ->GetPermissionStatusForFrame(type, context_->render_frame_host(),
                                       requesting_origin);
   }
 
   DCHECK(context_->GetEmbeddingOrigin().is_empty());
-  return BrowserContext::GetPermissionController(browser_context)
-      ->GetPermissionStatus(type, requesting_origin, requesting_origin);
+  return browser_context->GetPermissionController()->GetPermissionStatus(
+      type, requesting_origin, requesting_origin);
 }
 
 void PermissionServiceImpl::ResetPermissionStatus(PermissionType type) {
diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc
index 4ad502e..fed7eec 100644
--- a/content/browser/prerender/prerender_browsertest.cc
+++ b/content/browser/prerender/prerender_browsertest.cc
@@ -61,6 +61,23 @@
 namespace content {
 namespace {
 
+enum class BackForwardCacheType {
+  kDisabled,
+  kEnabled,
+  kEnabledWithSameSite,
+};
+
+std::string ToString(const testing::TestParamInfo<BackForwardCacheType>& info) {
+  switch (info.param) {
+    case BackForwardCacheType::kDisabled:
+      return "Disabled";
+    case BackForwardCacheType::kEnabled:
+      return "Enabled";
+    case BackForwardCacheType::kEnabledWithSameSite:
+      return "EnabledWithSameSite";
+  }
+}
+
 RenderFrameHost* FindRenderFrameHost(RenderFrameHost& root, const GURL& url) {
   std::vector<RenderFrameHost*> rfhs = root.GetFramesInSubtree();
   for (auto* rfh : rfhs) {
@@ -775,26 +792,6 @@
   // prerendering abandons the prerendered page regardless of activation.
 }
 
-// Tests that back-forward history is preserved after activation.
-IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, HistoryAfterActivation) {
-  const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html");
-  const GURL kPrerenderingUrl = GetUrl("/empty.html");
-
-  // Navigate to an initial page.
-  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
-
-  // Make and activate a prerendered page.
-  AddPrerender(kPrerenderingUrl);
-  NavigatePrimaryPage(kPrerenderingUrl);
-  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
-
-  // Navigate back to the initial page.
-  content::TestNavigationObserver observer(web_contents());
-  shell()->GoBackOrForward(-1);
-  observer.Wait();
-  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
-}
-
 // Tests that all RenderFrameHostImpls in the prerendering page know the
 // prerendering state.
 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderIframe) {
@@ -1805,5 +1802,115 @@
   EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
 }
 
+class PrerenderWithBackForwardCacheBrowserTest
+    : public PrerenderBrowserTest,
+      public testing::WithParamInterface<BackForwardCacheType> {
+ public:
+  PrerenderWithBackForwardCacheBrowserTest() {
+    // Set up the common params for the BFCache.
+    base::FieldTrialParams feature_params;
+    feature_params["TimeToLiveInBackForwardCacheInSeconds"] = "3600";
+
+    // Allow the BFCache for all devices regardless of their memory.
+    std::vector<base::Feature> disabled_features{
+        features::kBackForwardCacheMemoryControls};
+
+    switch (GetParam()) {
+      case BackForwardCacheType::kDisabled:
+        feature_list_.InitAndDisableFeature(features::kBackForwardCache);
+        break;
+      case BackForwardCacheType::kEnabled:
+        feature_list_.InitWithFeaturesAndParameters(
+            {{features::kBackForwardCache, feature_params}}, disabled_features);
+        break;
+      case BackForwardCacheType::kEnabledWithSameSite:
+        feature_params["enable_same_site"] = "true";
+        feature_list_.InitWithFeaturesAndParameters(
+            {{features::kBackForwardCache, feature_params}}, disabled_features);
+        break;
+    }
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    PrerenderWithBackForwardCacheBrowserTest,
+    testing::Values(BackForwardCacheType::kDisabled,
+                    BackForwardCacheType::kEnabled,
+                    BackForwardCacheType::kEnabledWithSameSite),
+    ToString);
+
+// Tests that history navigation works after activation. This runs with variaous
+// BFCache configurations that may modify behavior of history navigation.
+// This is a regression test for https://crbug.com/1201914.
+IN_PROC_BROWSER_TEST_P(PrerenderWithBackForwardCacheBrowserTest,
+                       HistoryNavigationAfterActivation) {
+  const GURL kInitialUrl = GetUrl("/prerender/add_prerender.html");
+  const GURL kPrerenderingUrl = GetUrl("/empty.html");
+
+  // Navigate to an initial page.
+  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
+  RenderFrameHostImpl* initial_frame_host = current_frame_host();
+  blink::LocalFrameToken initial_frame_token =
+      initial_frame_host->GetFrameToken();
+
+  // When the BFCache is disabled, activation will destroy the initial frame
+  // host. This observer will be used for confirming it.
+  RenderFrameDeletedObserver delete_observer(initial_frame_host);
+
+  // Make and activate a prerendered page.
+  AddPrerender(kPrerenderingUrl);
+  NavigatePrimaryPage(kPrerenderingUrl);
+  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl);
+
+  // Check if the initial page is in the BFCache.
+  switch (GetParam()) {
+    case BackForwardCacheType::kDisabled:
+      EXPECT_NE(current_frame_host(), initial_frame_host);
+      // The initial frame host should be deleted after activation because it is
+      // not cached in the BFCache.
+      delete_observer.WaitUntilDeleted();
+      break;
+    case BackForwardCacheType::kEnabled:
+      // Same-origin prerender activation should allow the initial page to be
+      // cached in the BFCache even if the BFCache for same-site (same-origin)
+      // is not enabled. This is because prerender activation always swaps
+      // BrowsingInstance and it makes the previous page cacheacble unlike
+      // regular same-origin navigation.
+      ASSERT_FALSE(IsSameSiteBackForwardCacheEnabled());
+      EXPECT_TRUE(initial_frame_host->IsInBackForwardCache());
+      break;
+    case BackForwardCacheType::kEnabledWithSameSite:
+      // Same-origin prerender activation should allow the initial page to be
+      // cached in the BFCache.
+      ASSERT_TRUE(IsSameSiteBackForwardCacheEnabled());
+      EXPECT_TRUE(initial_frame_host->IsInBackForwardCache());
+      break;
+  }
+
+  // Navigate back to the initial page.
+  content::TestNavigationObserver observer(web_contents());
+  shell()->GoBackOrForward(-1);
+  observer.Wait();
+  EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
+
+  // Check if the back navigation is served from the BFCache.
+  switch (GetParam()) {
+    case BackForwardCacheType::kDisabled:
+      // The frame host should be created again.
+      EXPECT_NE(current_frame_host()->GetFrameToken(), initial_frame_token);
+      break;
+    case BackForwardCacheType::kEnabled:
+    case BackForwardCacheType::kEnabledWithSameSite:
+      // The frame host should be restored.
+      EXPECT_EQ(current_frame_host()->GetFrameToken(), initial_frame_token);
+      EXPECT_FALSE(initial_frame_host->IsInBackForwardCache());
+      break;
+  }
+}
+
 }  // namespace
 }  // namespace content
diff --git a/content/browser/renderer_host/back_forward_cache_metrics.cc b/content/browser/renderer_host/back_forward_cache_metrics.cc
index 209f1ca..9c18b7c8 100644
--- a/content/browser/renderer_host/back_forward_cache_metrics.cc
+++ b/content/browser/renderer_host/back_forward_cache_metrics.cc
@@ -439,7 +439,7 @@
 }
 
 void BackForwardCacheMetrics::SetBrowsingInstanceSwapResult(
-    ShouldSwapBrowsingInstance reason) {
+    base::Optional<ShouldSwapBrowsingInstance> reason) {
   browsing_instance_swap_result_ = reason;
 }
 
diff --git a/content/browser/renderer_host/back_forward_cache_metrics.h b/content/browser/renderer_host/back_forward_cache_metrics.h
index 04b1140..3068258 100644
--- a/content/browser/renderer_host/back_forward_cache_metrics.h
+++ b/content/browser/renderer_host/back_forward_cache_metrics.h
@@ -161,8 +161,10 @@
   static void RecordEvictedAfterDocumentRestored(
       EvictedAfterDocumentRestoredReason reason);
 
-  // Sets the reason why the browsing instance is not swapped.
-  void SetBrowsingInstanceSwapResult(ShouldSwapBrowsingInstance reason);
+  // Sets the reason why the browsing instance is not swapped. Passing
+  // base::nullopt resets the reason.
+  void SetBrowsingInstanceSwapResult(
+      base::Optional<ShouldSwapBrowsingInstance> reason);
 
   // Notifies that the main frame has started a navigation to an entry
   // associated with |this|.
diff --git a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
index 9982337..d07178f 100644
--- a/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
+++ b/content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.cc
@@ -97,8 +97,11 @@
               storage::FileSystemOperationRunner::CopyOrMoveOption option,
               storage::FileSystemOperationRunner::StatusCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  file_system_context->operation_runner()->Move(src_path, dest_path, option,
-                                                std::move(callback));
+  file_system_context->operation_runner()->Move(
+      src_path, dest_path, option,
+      storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
+      storage::FileSystemOperation::CopyOrMoveProgressCallback(),
+      std::move(callback));
 }
 
 void CallGetMetadata(
@@ -322,6 +325,8 @@
   } else {
     GetFileSystemContext()->operation_runner()->Move(
         GetFileSystemURL(), new_url, option,
+        storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
+        storage::FileSystemOperation::CopyOrMoveProgressCallback(),
         base::BindOnce(&PepperInternalFileRefBackend::DidFinish,
                        weak_factory_.GetWeakPtr(), reply_context,
                        PpapiPluginMsg_FileRef_RenameReply()));
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index 13fd4a9..840fefc 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -706,6 +706,14 @@
   DCHECK(blink::features::IsPrerender2Enabled());
   if (speculative_render_frame_host_)
     DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost());
+
+  // Reset the swap result of BrowsingInstance as prerender activation always
+  // swaps BrowsingInstance.
+  BackForwardCacheMetrics* back_forward_cache_metrics =
+      render_frame_host_->GetBackForwardCacheMetrics();
+  if (back_forward_cache_metrics)
+    back_forward_cache_metrics->SetBrowsingInstanceSwapResult(base::nullopt);
+
   RestoreFromBackForwardCache(std::move(entry));
 }
 
diff --git a/content/browser/sandbox_mac_unittest.mm b/content/browser/sandbox_mac_unittest.mm
index baf0b3ce..3fac2f3 100644
--- a/content/browser/sandbox_mac_unittest.mm
+++ b/content/browser/sandbox_mac_unittest.mm
@@ -19,6 +19,7 @@
 #include "base/posix/eintr_wrapper.h"
 #include "base/process/kill.h"
 #include "base/strings/strcat.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -250,9 +251,10 @@
       result->font_data->Map(font_data_size);
   ASSERT_TRUE(mapping);
 
-  base::WriteFileDescriptor(fileno(temp_file.get()),
-                            static_cast<const char*>(mapping.get()),
-                            font_data_size);
+  base::WriteFileDescriptor(
+      fileno(temp_file.get()),
+      base::StringPiece(static_cast<const char*>(mapping.get()),
+                        font_data_size));
 
   extra_data_ = temp_file_path.value();
   ExecuteWithParams("FontLoadingProcess",
diff --git a/content/browser/service_worker/service_worker_internals_ui.cc b/content/browser/service_worker/service_worker_internals_ui.cc
index 4e52598..f8dd309 100644
--- a/content/browser/service_worker/service_worker_internals_ui.cc
+++ b/content/browser/service_worker/service_worker_internals_ui.cc
@@ -432,7 +432,12 @@
   weak_ptr_factory_.InvalidateWeakPtrs();
 }
 
-ServiceWorkerInternalsHandler::~ServiceWorkerInternalsHandler() = default;
+ServiceWorkerInternalsHandler::~ServiceWorkerInternalsHandler() {
+  // ServiceWorkerInternalsHandler can be destroyed without
+  // OnJavascriptDisallowed() ever being called (https://crbug.com/1199198).
+  // Call it to ensure that `this` is removed as an observer.
+  OnJavascriptDisallowed();
+}
 
 void ServiceWorkerInternalsHandler::OnRunningStateChanged() {
   FireWebUIListener("running-state-changed");
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 88f575bd..f2193d2 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -1845,7 +1845,7 @@
     OnCanSendReportingReportsCallback callback) {
   DCHECK(initialized_);
   PermissionController* permission_controller =
-      BrowserContext::GetPermissionController(browser_context_);
+      browser_context_->GetPermissionController();
   DCHECK(permission_controller);
 
   std::vector<url::Origin> origins_out;
@@ -1866,7 +1866,7 @@
     OnCanSendDomainReliabilityUploadCallback callback) {
   DCHECK(initialized_);
   PermissionController* permission_controller =
-      BrowserContext::GetPermissionController(browser_context_);
+      browser_context_->GetPermissionController();
   std::move(callback).Run(
       permission_controller->GetPermissionStatus(
           content::PermissionType::BACKGROUND_SYNC, origin, origin) ==
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 9130449..cce0e569 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1410,16 +1410,11 @@
     return;
 
   accessibility_mode_ = mode;
-
-  for (FrameTreeNode* node : frame_tree_.Nodes()) {
-    node->current_frame_host()->UpdateAccessibilityMode();
-    // Also update accessibility mode on the speculative RenderFrameHost for
-    // this FrameTreeNode, if one exists.
-    RenderFrameHostImpl* speculative_frame_host =
-        node->render_manager()->speculative_frame_host();
-    if (speculative_frame_host)
-      speculative_frame_host->UpdateAccessibilityMode();
-  }
+  // Update state for all frames in this tree and inner trees. Should also
+  // include speculative frame hosts.
+  GetMainFrame()->ForEachRenderFrameHostIncludingSpeculative(
+      base::BindRepeating(
+          [](RenderFrameHostImpl* rfhi) { rfhi->UpdateAccessibilityMode(); }));
 }
 
 void WebContentsImpl::AddAccessibilityMode(ui::AXMode mode) {
@@ -1694,10 +1689,13 @@
   desired_mode |= ui::kAXModeWebContentsOnly;
   AddAccessibilityMode(desired_mode);
 
+  // Accessibility mode updates include speculative RFH's as well as any inner
+  // trees. Iterate across these as we do for SetAccessibilityMode (which is
+  // called indirectly above via AddAccessibilityMode).
   if (need_reset) {
-    for (RenderFrameHost* rfh : GetAllFrames()) {
-      static_cast<RenderFrameHostImpl*>(rfh)->AccessibilityReset();
-    }
+    GetMainFrame()->ForEachRenderFrameHostIncludingSpeculative(
+        base::BindRepeating(
+            [](RenderFrameHostImpl* rfhi) { rfhi->AccessibilityReset(); }));
   }
 }
 
diff --git a/content/browser/webtransport/web_transport_connector_impl.cc b/content/browser/webtransport/web_transport_connector_impl.cc
index 71b94077..371e1ea 100644
--- a/content/browser/webtransport/web_transport_connector_impl.cc
+++ b/content/browser/webtransport/web_transport_connector_impl.cc
@@ -33,7 +33,7 @@
     remote_->OnConnectionEstablished(std::move(transport), std::move(client));
   }
   void OnHandshakeFailed(
-      const base::Optional<net::QuicTransportError>& error) override {
+      const base::Optional<net::WebTransportError>& error) override {
     // Here we pass null because it is dangerous to pass the error details
     // to the initiator renderer.
     remote_->OnHandshakeFailed(base::nullopt);
diff --git a/content/browser/webui/web_ui_security_browsertest.cc b/content/browser/webui/web_ui_security_browsertest.cc
index f57847d4..b6111b40 100644
--- a/content/browser/webui/web_ui_security_browsertest.cc
+++ b/content/browser/webui/web_ui_security_browsertest.cc
@@ -724,10 +724,11 @@
     EXPECT_EQ("Failed to fetch",
               PerformFetch(shell(), chrome_url, FetchMode::CORS));
     console_observer.Wait();
-    EXPECT_EQ(console_observer.GetMessageAt(0),
-              base::StringPrintf("Fetch API cannot load %s. URL scheme must be "
-                                 "\"http\" or \"https\" for CORS request.",
-                                 chrome_url.spec().c_str()));
+    EXPECT_EQ(
+        console_observer.GetMessageAt(0),
+        base::StringPrintf(
+            "Fetch API cannot load %s. URL scheme \"chrome\" is not supported.",
+            chrome_url.spec().c_str()));
   }
 
   {
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index ae8679b5..80c5af16 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -293,6 +293,7 @@
      features::kSecurePaymentConfirmationDebug},
     {wf::EnableSendBeaconThrowForBlobWithNonSimpleType,
      features::kSendBeaconThrowForBlobWithNonSimpleType},
+    {wf::EnableSharedArrayBuffer, features::kSharedArrayBuffer},
     {wf::EnableSharedArrayBufferOnDesktop,
      features::kSharedArrayBufferOnDesktop},
     {wf::EnableSharedAutofill, autofill::features::kAutofillAcrossIframes},
@@ -542,10 +543,6 @@
     WebRuntimeFeatures::EnableDecodeLossyWebPImagesToYUV(true);
   }
 
-  WebRuntimeFeatures::EnableSharedArrayBuffer(
-      base::FeatureList::IsEnabled(features::kSharedArrayBuffer) ||
-      base::FeatureList::IsEnabled(features::kWebAssemblyThreads));
-
   // These checks are custom wrappers around base::FeatureList::IsEnabled
   // They're moved here to distinguish them from actual base checks
   WebRuntimeFeatures::EnableOverlayScrollbars(ui::IsOverlayScrollbarEnabled());
diff --git a/content/public/browser/browser_context.h b/content/public/browser/browser_context.h
index 5412fbe8..0dc2cb0 100644
--- a/content/public/browser/browser_context.h
+++ b/content/public/browser/browser_context.h
@@ -124,7 +124,7 @@
 
   // Returns the PermissionController associated with this context. There's
   // always a PermissionController instance for each BrowserContext.
-  static PermissionController* GetPermissionController(BrowserContext* self);
+  PermissionController* GetPermissionController();
 
   // Returns a StoragePartition for the given SiteInstance. By default this will
   // create a new StoragePartition if it doesn't exist, unless |can_create| is
@@ -223,8 +223,7 @@
   void SetDownloadManagerForTesting(
       std::unique_ptr<DownloadManager> download_manager);
 
-  static void SetPermissionControllerForTesting(
-      BrowserContext* self,
+  void SetPermissionControllerForTesting(
       std::unique_ptr<PermissionController> permission_controller);
 
   // The list of CORS exemptions.  This list needs to be 1) replicated when
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index b46adc6..8fd5555 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -777,9 +777,9 @@
 const base::Feature kTrustedDOMTypes{"TrustedDOMTypes",
                                      base::FEATURE_ENABLED_BY_DEFAULT};
 
-// This feature is for a reverse Origin Trial, enabling SharedArrayBuffer and
-// WebAssemblyThreads for sites as they migrate towards requiring cross-origin
-// isolation for these features.
+// This feature is for a reverse Origin Trial, enabling SharedArrayBuffer for
+// sites as they migrate towards requiring cross-origin isolation for these
+// features.
 // TODO(bbudge): Remove when the deprecation is complete.
 // https://developer.chrome.com/origintrials/#/view_trial/303992974847508481
 // https://crbug.com/1144104
@@ -844,15 +844,6 @@
 const base::Feature kWebAssemblyTiering{"WebAssemblyTiering",
                                         base::FEATURE_ENABLED_BY_DEFAULT};
 
-// Enable WebAssembly threads.
-// https://github.com/WebAssembly/threads
-// This feature is also enabled independently of this flag for cross-origin
-// isolated renderers.
-const base::Feature kWebAssemblyThreads {
-  "WebAssemblyThreads",
-      base::FEATURE_DISABLED_BY_DEFAULT
-};
-
 // Enable WebAssembly trap handler.
 #if (defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN) || \
      defined(OS_MAC)) &&                                             \
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 935f6cec..346cb8a 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -215,7 +215,6 @@
 #endif  // defined(OS_LINUX) && defined(ARCH_CPU_X86_64)
 CONTENT_EXPORT extern const base::Feature kWebAssemblyLazyCompilation;
 CONTENT_EXPORT extern const base::Feature kWebAssemblySimd;
-CONTENT_EXPORT extern const base::Feature kWebAssemblyThreads;
 CONTENT_EXPORT extern const base::Feature kWebAssemblyTiering;
 CONTENT_EXPORT extern const base::Feature kWebAssemblyTrapHandler;
 CONTENT_EXPORT extern const base::Feature kWebAuth;
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc
index 89e1980..08e33b7e 100644
--- a/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -193,6 +193,9 @@
 void BlinkAXTreeSource::Thaw() {
   CHECK(frozen_);
   WebAXObject::Thaw(document_);
+  document_ = WebDocument();
+  focus_ = WebAXObject();
+  root_ = WebAXObject();
   frozen_ = false;
 }
 
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc
index 2823724..46f8fa8 100644
--- a/content/renderer/render_process_impl.cc
+++ b/content/renderer/render_process_impl.cc
@@ -167,8 +167,6 @@
   constexpr char kAtomicsFlag[] = "--harmony-atomics";
   v8::V8::SetFlagsFromString(kAtomicsFlag, sizeof(kAtomicsFlag));
 
-  bool enable_wasm_threads =
-      base::FeatureList::IsEnabled(features::kWebAssemblyThreads);
   bool enable_shared_array_buffer_unconditionally =
       base::FeatureList::IsEnabled(features::kSharedArrayBuffer);
 
@@ -188,11 +186,6 @@
   }
 #endif
 
-  // WebAssembly Threads require the feature flag.
-  if (enable_wasm_threads) {
-    blink::WebV8Features::EnableWasmThreads();
-  }
-
   // The following line enables V8 support for SharedArrayBuffer. Note that the
   // SharedArrayBuffer constructor will be added to every global object only if
   // the v8 flag `sharedarraybuffer-per-context` is disabled (cf. next block of
diff --git a/extensions/browser/api/usb/usb_device_manager.h b/extensions/browser/api/usb/usb_device_manager.h
index 2a2ae3c..13eacd11 100644
--- a/extensions/browser/api/usb/usb_device_manager.h
+++ b/extensions/browser/api/usb/usb_device_manager.h
@@ -9,6 +9,7 @@
 #include <string>
 #include <vector>
 
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "build/chromeos_buildflags.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
index 4225637..3f04137 100644
--- a/extensions/renderer/dispatcher.cc
+++ b/extensions/renderer/dispatcher.cc
@@ -953,7 +953,6 @@
   // add support for extension opt-in into cross-origin isolation.
   if (extension->is_extension()) {
     blink::WebV8Features::EnableSharedArrayBuffer();
-    blink::WebV8Features::EnableWasmThreads();
   }
 
   active_extension_ids_.insert(extension_id);
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn
index 0ed1e56..ace3232 100644
--- a/gpu/BUILD.gn
+++ b/gpu/BUILD.gn
@@ -218,11 +218,16 @@
     "//gpu/skia_bindings:skia_bindings",
     "//testing/gmock",
     "//testing/gtest",
-    "//third_party/angle:translator",
     "//ui/gfx:test_support",
     "//ui/gl:gl_unittest_utils",
     "//ui/gl:test_support",
   ]
+
+  if (use_static_angle) {
+    deps += [ "//third_party/angle:translator" ]
+  } else {
+    deps += [ "//third_party/angle:translator_gl_d3d_only" ]
+  }
 }
 
 if (!is_android && !is_fuchsia && !is_chromeos_ash) {
diff --git a/ios/chrome/browser/policy/DIR_METADATA b/ios/chrome/browser/policy/DIR_METADATA
index 17fbea7..b21bb252 100644
--- a/ios/chrome/browser/policy/DIR_METADATA
+++ b/ios/chrome/browser/policy/DIR_METADATA
@@ -7,5 +7,5 @@
 #   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
 
 monorail {
-  component: "Enterprise>CloudPolicy"
-}
\ No newline at end of file
+  component: "Enterprise"
+}
diff --git a/media/blink/blink_platform_with_task_environment.h b/media/blink/blink_platform_with_task_environment.h
index a279b2b..4ebfff9 100644
--- a/media/blink/blink_platform_with_task_environment.h
+++ b/media/blink/blink_platform_with_task_environment.h
@@ -7,6 +7,7 @@
 
 #include "base/macros.h"
 #include "base/test/task_environment.h"
+#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
 #include "third_party/blink/public/web/blink.h"
 
diff --git a/media/blink/video_frame_compositor_unittest.cc b/media/blink/video_frame_compositor_unittest.cc
index cd8ef47..e1491b2 100644
--- a/media/blink/video_frame_compositor_unittest.cc
+++ b/media/blink/video_frame_compositor_unittest.cc
@@ -6,8 +6,10 @@
 #include "base/bind.h"
 #include "base/macros.h"
 #include "base/run_loop.h"
+#include "base/synchronization/waitable_event.h"
 #include "base/test/gmock_callback_support.h"
 #include "base/test/simple_test_tick_clock.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
 #include "media/base/video_frame.h"
diff --git a/media/capture/video/chromeos/camera_app_device_impl.h b/media/capture/video/chromeos/camera_app_device_impl.h
index 9bb497dd..b33b0ffb 100644
--- a/media/capture/video/chromeos/camera_app_device_impl.h
+++ b/media/capture/video/chromeos/camera_app_device_impl.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/containers/flat_set.h"
+#include "base/containers/queue.h"
 #include "base/memory/weak_ptr.h"
 #include "base/single_thread_task_runner.h"
 #include "base/synchronization/lock.h"
diff --git a/media/capture/video/chromeos/camera_hal_delegate.cc b/media/capture/video/chromeos/camera_hal_delegate.cc
index fcc92b23..9b83d4c 100644
--- a/media/capture/video/chromeos/camera_hal_delegate.cc
+++ b/media/capture/video/chromeos/camera_hal_delegate.cc
@@ -264,7 +264,7 @@
         continue;
       }
 
-      CAMERA_LOG(EVENT) << "Supported format: " << width << "x" << height
+      CAMERA_LOG(DEBUG) << "Supported format: " << width << "x" << height
                         << " fps=" << fps
                         << " format=" << cr_format.video_format;
       supported_formats->emplace_back(gfx::Size(width, height), fps,
diff --git a/media/capture/video/file_video_capture_device.h b/media/capture/video/file_video_capture_device.h
index 2d4a4757..a08187a 100644
--- a/media/capture/video/file_video_capture_device.h
+++ b/media/capture/video/file_video_capture_device.h
@@ -10,6 +10,7 @@
 #include <memory>
 #include <string>
 
+#include "base/containers/queue.h"
 #include "base/files/file.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/macros.h"
diff --git a/media/capture/video/win/video_capture_device_mf_win.h b/media/capture/video/win/video_capture_device_mf_win.h
index beefdb9b..0b663380 100644
--- a/media/capture/video/win/video_capture_device_mf_win.h
+++ b/media/capture/video/win/video_capture_device_mf_win.h
@@ -19,6 +19,7 @@
 #include <vector>
 
 #include "base/callback_forward.h"
+#include "base/containers/queue.h"
 #include "base/macros.h"
 #include "base/optional.h"
 #include "base/sequence_checker.h"
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc
index 0bc65a5..4555d2e 100644
--- a/mojo/public/cpp/bindings/lib/multiplex_router.cc
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -21,6 +21,7 @@
 #include "mojo/public/cpp/bindings/interface_endpoint_controller.h"
 #include "mojo/public/cpp/bindings/lib/may_auto_lock.h"
 #include "mojo/public/cpp/bindings/lib/message_quota_checker.h"
+#include "mojo/public/cpp/bindings/message_header_validator.h"
 #include "mojo/public/cpp/bindings/sequence_local_sync_event_watcher.h"
 
 namespace mojo {
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.h b/mojo/public/cpp/bindings/lib/multiplex_router.h
index 06a6ba3..7fe3b72d 100644
--- a/mojo/public/cpp/bindings/lib/multiplex_router.h
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.h
@@ -9,28 +9,22 @@
 
 #include <map>
 #include <memory>
-#include <string>
 
-#include "base/check_op.h"
-#include "base/compiler_specific.h"
+#include "base/check.h"
 #include "base/component_export.h"
-#include "base/containers/queue.h"
+#include "base/containers/circular_deque.h"
 #include "base/containers/small_map.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/optional.h"
 #include "base/sequence_checker.h"
-#include "base/sequenced_task_runner.h"
 #include "base/synchronization/lock.h"
 #include "base/types/pass_key.h"
 #include "mojo/public/cpp/bindings/associated_group_controller.h"
-#include "mojo/public/cpp/bindings/async_flusher.h"
 #include "mojo/public/cpp/bindings/connection_group.h"
 #include "mojo/public/cpp/bindings/connector.h"
 #include "mojo/public/cpp/bindings/interface_id.h"
 #include "mojo/public/cpp/bindings/message_dispatcher.h"
-#include "mojo/public/cpp/bindings/message_header_validator.h"
 #include "mojo/public/cpp/bindings/pending_flush.h"
 #include "mojo/public/cpp/bindings/pipe_control_message_handler.h"
 #include "mojo/public/cpp/bindings/pipe_control_message_handler_delegate.h"
@@ -43,6 +37,10 @@
 
 namespace mojo {
 
+class AsyncFlusher;
+class MessageHeaderValidator;
+class PendingFlush;
+
 namespace internal {
 
 // MultiplexRouter supports routing messages for multiple interfaces over a
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 8626a1a..72788fd 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -830,10 +830,10 @@
     "quic/quic_stream_factory.h",
     "quic/quic_transport_client.cc",
     "quic/quic_transport_client.h",
-    "quic/quic_transport_error.cc",
-    "quic/quic_transport_error.h",
     "quic/web_transport_client.cc",
     "quic/web_transport_client.h",
+    "quic/web_transport_error.cc",
+    "quic/web_transport_error.h",
     "quiche/common/platform/impl/quiche_bug_tracker_impl.h",
     "quiche/common/platform/impl/quiche_flag_utils_impl.h",
     "quiche/common/platform/impl/quiche_flags_impl.cc",
diff --git a/net/quic/dedicated_web_transport_http3_client.cc b/net/quic/dedicated_web_transport_http3_client.cc
index dc95eb3c..43259ff 100644
--- a/net/quic/dedicated_web_transport_http3_client.cc
+++ b/net/quic/dedicated_web_transport_http3_client.cc
@@ -217,7 +217,7 @@
   DoLoop(OK);
 }
 
-const QuicTransportError& DedicatedWebTransportHttp3Client::error() const {
+const WebTransportError& DedicatedWebTransportHttp3Client::error() const {
   return error_;
 }
 
diff --git a/net/quic/dedicated_web_transport_http3_client.h b/net/quic/dedicated_web_transport_http3_client.h
index b09fbe3..d40989ce 100644
--- a/net/quic/dedicated_web_transport_http3_client.h
+++ b/net/quic/dedicated_web_transport_http3_client.h
@@ -14,8 +14,8 @@
 #include "net/quic/quic_chromium_packet_writer.h"
 #include "net/quic/quic_context.h"
 #include "net/quic/quic_event_logger.h"
-#include "net/quic/quic_transport_error.h"
 #include "net/quic/web_transport_client.h"
+#include "net/quic/web_transport_error.h"
 #include "net/socket/client_socket_factory.h"
 #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
 #include "net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h"
@@ -58,7 +58,7 @@
   ~DedicatedWebTransportHttp3Client() override;
 
   WebTransportState state() const { return state_; }
-  const QuicTransportError& error() const override;
+  const WebTransportError& error() const override;
 
   // Connect() is an asynchronous operation.  Once the operation is finished,
   // OnConnected() or OnConnectionFailed() is called on the Visitor.
@@ -152,7 +152,7 @@
 
   WebTransportState state_ = NEW;
   ConnectState next_connect_state_ = CONNECT_STATE_NONE;
-  QuicTransportError error_;
+  WebTransportError error_;
   bool retried_with_new_version_ = false;
   bool session_ready_ = false;
 
diff --git a/net/quic/quic_transport_client.cc b/net/quic/quic_transport_client.cc
index 45525cf..a80a9c4 100644
--- a/net/quic/quic_transport_client.cc
+++ b/net/quic/quic_transport_client.cc
@@ -100,7 +100,7 @@
   DoLoop(OK);
 }
 
-const QuicTransportError& QuicTransportClient::error() const {
+const WebTransportError& QuicTransportClient::error() const {
   return error_;
 }
 
diff --git a/net/quic/quic_transport_client.h b/net/quic/quic_transport_client.h
index 7244a80..7bd9ecd 100644
--- a/net/quic/quic_transport_client.h
+++ b/net/quic/quic_transport_client.h
@@ -14,8 +14,8 @@
 #include "net/quic/quic_chromium_packet_writer.h"
 #include "net/quic/quic_context.h"
 #include "net/quic/quic_event_logger.h"
-#include "net/quic/quic_transport_error.h"
 #include "net/quic/web_transport_client.h"
+#include "net/quic/web_transport_error.h"
 #include "net/socket/client_socket_factory.h"
 #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
 #include "net/third_party/quiche/src/quic/core/quic_config.h"
@@ -58,7 +58,7 @@
   ~QuicTransportClient() override;
 
   WebTransportState state() const { return state_; }
-  const QuicTransportError& error() const override;
+  const WebTransportError& error() const override;
 
   // Connect() is an asynchronous operation.  Once the operation is finished,
   // OnConnected() or OnConnectionFailed() is called on the Visitor.
@@ -172,7 +172,7 @@
 
   WebTransportState state_ = NEW;
   ConnectState next_connect_state_ = CONNECT_STATE_NONE;
-  QuicTransportError error_;
+  WebTransportError error_;
   bool retried_with_new_version_ = false;
 
   ProxyInfo proxy_info_;
diff --git a/net/quic/quic_transport_error.h b/net/quic/quic_transport_error.h
deleted file mode 100644
index 263fc12..0000000
--- a/net/quic/quic_transport_error.h
+++ /dev/null
@@ -1,54 +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 NET_QUIC_QUIC_TRANSPORT_ERROR_H_
-#define NET_QUIC_QUIC_TRANSPORT_ERROR_H_
-
-#include <ostream>
-#include <string>
-
-#include "base/strings/string_piece.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_export.h"
-#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
-
-namespace net {
-
-// TODO(crbug.com/1193409): rename this class to WebTransportError.
-struct NET_EXPORT QuicTransportError {
-  QuicTransportError() = default;
-  QuicTransportError(int net_error,
-                     quic::QuicErrorCode quic_error,
-                     base::StringPiece details,
-                     bool safe_to_report_details)
-      : net_error(net_error),
-        quic_error(quic_error),
-        details(details),
-        safe_to_report_details(safe_to_report_details) {}
-
-  // |net_error| is always set to a meaningful value.
-  int net_error = OK;
-
-  // |quic_error| is set to a QUIC error, or to quic::QUIC_NO_ERROR if the error
-  // originates non-QUIC parts of the stack.
-  quic::QuicErrorCode quic_error = quic::QUIC_NO_ERROR;
-
-  // Human-readable error summary.
-  std::string details;
-
-  // QuicTransport requires that the connection errors have to be
-  // undistinguishable until the peer is confirmed to be a QuicTransport
-  // endpoint.  See https://wicg.github.io/web-transport/#protocol-security
-  bool safe_to_report_details = false;
-};
-
-NET_EXPORT
-std::string QuicTransportErrorToString(const QuicTransportError& error);
-
-NET_EXPORT
-std::ostream& operator<<(std::ostream& os, const QuicTransportError& error);
-
-}  // namespace net
-
-#endif  // NET_QUIC_QUIC_TRANSPORT_ERROR_H_
diff --git a/net/quic/web_transport_client.cc b/net/quic/web_transport_client.cc
index 3afe751..8cb394b8 100644
--- a/net/quic/web_transport_client.cc
+++ b/net/quic/web_transport_client.cc
@@ -23,10 +23,10 @@
   void Connect() override { visitor_->OnConnectionFailed(); }
 
   quic::WebTransportSession* session() override { return nullptr; }
-  const QuicTransportError& error() const override { return error_; }
+  const WebTransportError& error() const override { return error_; }
 
  private:
-  QuicTransportError error_;
+  WebTransportError error_;
   WebTransportClientVisitor* visitor_;
 };
 }  // namespace
diff --git a/net/quic/web_transport_client.h b/net/quic/web_transport_client.h
index e627d97a..916f180 100644
--- a/net/quic/web_transport_client.h
+++ b/net/quic/web_transport_client.h
@@ -10,7 +10,7 @@
 #include "base/optional.h"
 #include "base/strings/string_piece.h"
 #include "net/base/network_isolation_key.h"
-#include "net/quic/quic_transport_error.h"
+#include "net/quic/web_transport_error.h"
 #include "net/third_party/quiche/src/quic/core/quic_types.h"
 #include "net/third_party/quiche/src/quic/core/web_transport_interface.h"
 #include "net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h"
@@ -101,7 +101,7 @@
 
   // session() can be nullptr in states other than CONNECTED.
   virtual quic::WebTransportSession* session() = 0;
-  virtual const QuicTransportError& error() const = 0;
+  virtual const WebTransportError& error() const = 0;
 };
 
 // Creates a WebTransport client for |url| accessed from |origin| with the
diff --git a/net/quic/quic_transport_error.cc b/net/quic/web_transport_error.cc
similarity index 66%
rename from net/quic/quic_transport_error.cc
rename to net/quic/web_transport_error.cc
index 94030a4..4f15654 100644
--- a/net/quic/quic_transport_error.cc
+++ b/net/quic/web_transport_error.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "net/quic/quic_transport_error.h"
+#include "net/quic/web_transport_error.h"
 
 #include "base/strings/strcat.h"
 
 namespace net {
 
-std::string QuicTransportErrorToString(const QuicTransportError& error) {
+std::string WebTransportErrorToString(const WebTransportError& error) {
   std::string message =
       ExtendedErrorToString(error.net_error, error.quic_error);
   if (error.details == message)
@@ -16,8 +16,8 @@
   return base::StrCat({message, " (", error.details, ")"});
 }
 
-std::ostream& operator<<(std::ostream& os, const QuicTransportError& error) {
-  os << QuicTransportErrorToString(error);
+std::ostream& operator<<(std::ostream& os, const WebTransportError& error) {
+  os << WebTransportErrorToString(error);
   return os;
 }
 
diff --git a/net/quic/web_transport_error.h b/net/quic/web_transport_error.h
new file mode 100644
index 0000000..3d97c585
--- /dev/null
+++ b/net/quic/web_transport_error.h
@@ -0,0 +1,53 @@
+// 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 NET_QUIC_WEB_TRANSPORT_ERROR_H_
+#define NET_QUIC_WEB_TRANSPORT_ERROR_H_
+
+#include <ostream>
+#include <string>
+
+#include "base/strings/string_piece.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_export.h"
+#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
+
+namespace net {
+
+struct NET_EXPORT WebTransportError {
+  WebTransportError() = default;
+  WebTransportError(int net_error,
+                    quic::QuicErrorCode quic_error,
+                    base::StringPiece details,
+                    bool safe_to_report_details)
+      : net_error(net_error),
+        quic_error(quic_error),
+        details(details),
+        safe_to_report_details(safe_to_report_details) {}
+
+  // |net_error| is always set to a meaningful value.
+  int net_error = OK;
+
+  // |quic_error| is set to a QUIC error, or to quic::QUIC_NO_ERROR if the error
+  // originates non-QUIC parts of the stack.
+  quic::QuicErrorCode quic_error = quic::QUIC_NO_ERROR;
+
+  // Human-readable error summary.
+  std::string details;
+
+  // WebTransport requires that the connection errors have to be
+  // undistinguishable until the peer is confirmed to be a WebTransport
+  // endpoint.  See https://w3c.github.io/webtransport/#protocol-security
+  bool safe_to_report_details = false;
+};
+
+NET_EXPORT
+std::string WebTransportErrorToString(const WebTransportError& error);
+
+NET_EXPORT
+std::ostream& operator<<(std::ostream& os, const WebTransportError& error);
+
+}  // namespace net
+
+#endif  // NET_QUIC_WEB_TRANSPORT_ERROR_H_
diff --git a/printing/backend/cups_helper.cc b/printing/backend/cups_helper.cc
index d81365a..c2c8746 100644
--- a/printing/backend/cups_helper.cc
+++ b/printing/backend/cups_helper.cc
@@ -592,17 +592,12 @@
   base::FilePath ppd_file_path;
   base::ScopedFD ppd_fd =
       base::CreateAndOpenFdForTemporaryFileInDir(temp_dir, &ppd_file_path);
-  if (!ppd_fd.is_valid())
-    return false;
-
-  if (!base::WriteFileDescriptor(ppd_fd.get(), printer_capabilities.data(),
-                                 printer_capabilities.size())) {
+  if (!ppd_fd.is_valid() ||
+      !base::WriteFileDescriptor(ppd_fd.get(), printer_capabilities) ||
+      lseek(ppd_fd.get(), 0, SEEK_SET) == -1) {
     return false;
   }
 
-  if (lseek(ppd_fd.get(), 0, SEEK_SET) == -1)
-    return false;
-
   ppd_file_t* ppd = ppdOpenFd(ppd_fd.get());
   if (!ppd) {
     int line = 0;
diff --git a/printing/metafile_skia.cc b/printing/metafile_skia.cc
index 3c71297..61e43da1 100644
--- a/printing/metafile_skia.cc
+++ b/printing/metafile_skia.cc
@@ -12,6 +12,7 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/containers/contains.h"
+#include "base/containers/span.h"
 #include "base/files/file.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/time/time.h"
@@ -335,10 +336,9 @@
     if (read_size == 0u)
       break;
     DCHECK_GE(buffer.size(), read_size);
-    if (!base::WriteFileDescriptor(
-            fd, reinterpret_cast<const char*>(buffer.data()), read_size)) {
+    buffer.resize(read_size);
+    if (!base::WriteFileDescriptor(fd, buffer))
       return false;
-    }
   } while (!asset->isAtEnd());
 
   return true;
diff --git a/services/data_decoder/image_decoder_impl_unittest.cc b/services/data_decoder/image_decoder_impl_unittest.cc
index 48f631e..e7845059 100644
--- a/services/data_decoder/image_decoder_impl_unittest.cc
+++ b/services/data_decoder/image_decoder_impl_unittest.cc
@@ -14,6 +14,7 @@
 #include "mojo/public/cpp/bindings/binder_map.h"
 #include "services/data_decoder/image_decoder_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/web/blink.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/codec/jpeg_codec.h"
diff --git a/services/network/public/cpp/web_transport_error_mojom_traits.cc b/services/network/public/cpp/web_transport_error_mojom_traits.cc
index 3850e2a..a3f1aba 100644
--- a/services/network/public/cpp/web_transport_error_mojom_traits.cc
+++ b/services/network/public/cpp/web_transport_error_mojom_traits.cc
@@ -8,8 +8,8 @@
 
 bool StructTraits<
     network::mojom::WebTransportErrorDataView,
-    net::QuicTransportError>::Read(network::mojom::WebTransportErrorDataView in,
-                                   net::QuicTransportError* out) {
+    net::WebTransportError>::Read(network::mojom::WebTransportErrorDataView in,
+                                  net::WebTransportError* out) {
   if (in.net_error() > 0) {
     return false;
   }
@@ -21,7 +21,7 @@
     return false;
   }
 
-  *out = net::QuicTransportError(
+  *out = net::WebTransportError(
       in.net_error(), static_cast<quic::QuicErrorCode>(in.quic_error()),
       std::move(details), in.safe_to_report_details());
   return true;
diff --git a/services/network/public/cpp/web_transport_error_mojom_traits.h b/services/network/public/cpp/web_transport_error_mojom_traits.h
index 6be42fa..3931ebd 100644
--- a/services/network/public/cpp/web_transport_error_mojom_traits.h
+++ b/services/network/public/cpp/web_transport_error_mojom_traits.h
@@ -6,7 +6,7 @@
 #define SERVICES_NETWORK_PUBLIC_CPP_WEB_TRANSPORT_ERROR_MOJOM_TRAITS_H_
 
 #include "mojo/public/cpp/bindings/struct_traits.h"
-#include "net/quic/quic_transport_error.h"
+#include "net/quic/web_transport_error.h"
 #include "services/network/public/mojom/web_transport.mojom-shared.h"
 
 namespace mojo {
@@ -14,21 +14,21 @@
 template <>
 struct COMPONENT_EXPORT(NETWORK_CPP_BASE)
     StructTraits<network::mojom::WebTransportErrorDataView,
-                 net::QuicTransportError> {
-  static int32_t net_error(const net::QuicTransportError& e) {
+                 net::WebTransportError> {
+  static int32_t net_error(const net::WebTransportError& e) {
     return e.net_error;
   }
-  static int32_t quic_error(const net::QuicTransportError& e) {
+  static int32_t quic_error(const net::WebTransportError& e) {
     return static_cast<int32_t>(e.quic_error);
   }
-  static const std::string& details(const net::QuicTransportError& e) {
+  static const std::string& details(const net::WebTransportError& e) {
     return e.details;
   }
-  static bool safe_to_report_details(const net::QuicTransportError& e) {
+  static bool safe_to_report_details(const net::WebTransportError& e) {
     return e.safe_to_report_details;
   }
   static bool Read(network::mojom::WebTransportErrorDataView in,
-                   net::QuicTransportError* out);
+                   net::WebTransportError* out);
 };
 
 }  // namespace mojo
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn
index 6cc2d8a..9245898 100644
--- a/services/network/public/mojom/BUILD.gn
+++ b/services/network/public/mojom/BUILD.gn
@@ -97,7 +97,7 @@
       types = [
         {
           mojom = "network.mojom.WebTransportError"
-          cpp = "::net::QuicTransportError"
+          cpp = "::net::WebTransportError"
         },
       ]
       traits_headers =
diff --git a/services/network/web_transport_unittest.cc b/services/network/web_transport_unittest.cc
index ee200be65..30ddf9b 100644
--- a/services/network/web_transport_unittest.cc
+++ b/services/network/web_transport_unittest.cc
@@ -123,7 +123,7 @@
   }
 
   void OnHandshakeFailed(
-      const base::Optional<net::QuicTransportError>& error) override {
+      const base::Optional<net::WebTransportError>& error) override {
     has_seen_handshake_failure_ = true;
     receiver_.reset();
     std::move(callback_).Run();
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_linux.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_linux.cc
index 6d35c65..5994bb5 100644
--- a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_linux.cc
+++ b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_linux.cc
@@ -69,8 +69,7 @@
   base::ScopedFD clear_refs_fd(open(clear_refs_file.value().c_str(), O_WRONLY));
   is_peak_rss_resettable =
       clear_refs_fd.get() >= 0 &&
-      base::WriteFileDescriptor(clear_refs_fd.get(), kClearPeakRssCommand,
-                                sizeof(kClearPeakRssCommand) - 1);
+      base::WriteFileDescriptor(clear_refs_fd.get(), kClearPeakRssCommand);
   return is_peak_rss_resettable;
 }
 
@@ -299,7 +298,7 @@
 
   auto process_metrics = CreateProcessMetrics(pid);
 
-  const static size_t page_size = base::GetPageSize();
+  static const size_t page_size = base::GetPageSize();
   uint64_t rss_anon_bytes = (resident_pages - shared_pages) * page_size;
   uint64_t vm_swap_bytes = process_metrics->GetVmSwapBytes();
 
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_unittest.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_unittest.cc
index 4ec1f08..58c35d4a 100644
--- a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_unittest.cc
+++ b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_unittest.cc
@@ -124,8 +124,7 @@
   *file = CreateAndOpenTemporaryStream(&temp_path);
   ASSERT_TRUE(*file);
 
-  ASSERT_TRUE(base::WriteFileDescriptor(fileno(file->get()), contents,
-                                        strlen(contents)));
+  ASSERT_TRUE(base::WriteFileDescriptor(fileno(file->get()), contents));
 }
 
 }  // namespace
diff --git a/storage/browser/file_system/copy_or_move_operation_delegate.cc b/storage/browser/file_system/copy_or_move_operation_delegate.cc
index f39419b..06522a9 100644
--- a/storage/browser/file_system/copy_or_move_operation_delegate.cc
+++ b/storage/browser/file_system/copy_or_move_operation_delegate.cc
@@ -731,7 +731,7 @@
     OperationType operation_type,
     CopyOrMoveOption option,
     ErrorBehavior error_behavior,
-    const CopyProgressCallback& progress_callback,
+    const CopyOrMoveProgressCallback& progress_callback,
     StatusCallback callback)
     : RecursiveOperationDelegate(file_system_context),
       src_root_(src_root),
@@ -781,12 +781,13 @@
 
 void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url,
                                               StatusCallback callback) {
+  FileSystemURL dest_url = CreateDestURL(src_url);
+
   if (!progress_callback_.is_null()) {
-    progress_callback_.Run(FileSystemOperation::BEGIN_COPY_ENTRY, src_url,
-                           FileSystemURL(), 0);
+    progress_callback_.Run(FileSystemOperation::CopyOrMoveProgressType::kBegin,
+                           src_url, dest_url, 0);
   }
 
-  FileSystemURL dest_url = CreateDestURL(src_url);
   std::unique_ptr<CopyOrMoveImpl> impl;
   if (same_file_system_ &&
       (file_system_context()
@@ -796,7 +797,7 @@
     impl = std::make_unique<CopyOrMoveOnSameFileSystemImpl>(
         operation_runner(), operation_type_, src_url, dest_url, option_,
         base::BindRepeating(&CopyOrMoveOperationDelegate::OnCopyFileProgress,
-                            weak_factory_.GetWeakPtr(), src_url));
+                            weak_factory_.GetWeakPtr(), src_url, dest_url));
   } else {
     // Cross filesystem case.
     base::File::Error error = base::File::FILE_ERROR_FAILED;
@@ -805,8 +806,9 @@
             dest_root_.type(), &error);
     if (error != base::File::FILE_OK) {
       if (!progress_callback_.is_null())
-        progress_callback_.Run(FileSystemOperation::ERROR_COPY_ENTRY, src_url,
-                               dest_url, 0);
+        progress_callback_.Run(
+            FileSystemOperation::CopyOrMoveProgressType::kError, src_url,
+            dest_url, 0);
 
       std::move(callback).Run(error);
       return;
@@ -824,7 +826,7 @@
             dest_url, option_, std::move(reader), std::move(writer),
             base::BindRepeating(
                 &CopyOrMoveOperationDelegate::OnCopyFileProgress,
-                weak_factory_.GetWeakPtr(), src_url));
+                weak_factory_.GetWeakPtr(), src_url, dest_url));
       }
     }
 
@@ -833,7 +835,7 @@
           operation_runner(), operation_type_, src_url, dest_url, option_,
           validator_factory,
           base::BindRepeating(&CopyOrMoveOperationDelegate::OnCopyFileProgress,
-                              weak_factory_.GetWeakPtr(), src_url));
+                              weak_factory_.GetWeakPtr(), src_url, dest_url));
     }
   }
 
@@ -861,13 +863,14 @@
     return;
   }
 
+  FileSystemURL dest_url = CreateDestURL(src_url);
+
   if (!progress_callback_.is_null()) {
-    progress_callback_.Run(FileSystemOperation::BEGIN_COPY_ENTRY, src_url,
-                           FileSystemURL(), 0);
+    progress_callback_.Run(FileSystemOperation::CopyOrMoveProgressType::kBegin,
+                           src_url, dest_url, 0);
   }
 
-  ProcessDirectoryInternal(src_url, CreateDestURL(src_url),
-                           std::move(callback));
+  ProcessDirectoryInternal(src_url, dest_url, std::move(callback));
 }
 
 void CopyOrMoveOperationDelegate::PostProcessDirectory(
@@ -902,12 +905,13 @@
 
   if (!progress_callback_.is_null() && error != base::File::FILE_OK &&
       error != base::File::FILE_ERROR_NOT_A_FILE)
-    progress_callback_.Run(FileSystemOperation::ERROR_COPY_ENTRY, src_url,
-                           dest_url, 0);
+    progress_callback_.Run(FileSystemOperation::CopyOrMoveProgressType::kError,
+                           src_url, dest_url, 0);
 
   if (!progress_callback_.is_null() && error == base::File::FILE_OK) {
-    progress_callback_.Run(FileSystemOperation::END_COPY_ENTRY, src_url,
-                           dest_url, 0);
+    progress_callback_.Run(
+        FileSystemOperation::CopyOrMoveProgressType::kEndCopy, src_url,
+        dest_url, 0);
   }
 
   std::move(callback).Run(error);
@@ -950,8 +954,9 @@
     StatusCallback callback,
     base::File::Error error) {
   if (!progress_callback_.is_null() && error == base::File::FILE_OK) {
-    progress_callback_.Run(FileSystemOperation::END_COPY_ENTRY, src_url,
-                           dest_url, 0);
+    progress_callback_.Run(
+        FileSystemOperation::CopyOrMoveProgressType::kEndCopy, src_url,
+        dest_url, 0);
   }
 
   std::move(callback).Run(error);
@@ -1008,10 +1013,12 @@
 
 void CopyOrMoveOperationDelegate::OnCopyFileProgress(
     const FileSystemURL& src_url,
+    const FileSystemURL& dest_url,
     int64_t size) {
   if (!progress_callback_.is_null()) {
-    progress_callback_.Run(FileSystemOperation::PROGRESS, src_url,
-                           FileSystemURL(), size);
+    progress_callback_.Run(
+        FileSystemOperation::CopyOrMoveProgressType::kProgress, src_url,
+        dest_url, size);
   }
 }
 
diff --git a/storage/browser/file_system/copy_or_move_operation_delegate.h b/storage/browser/file_system/copy_or_move_operation_delegate.h
index 3b709d2e..e84d192 100644
--- a/storage/browser/file_system/copy_or_move_operation_delegate.h
+++ b/storage/browser/file_system/copy_or_move_operation_delegate.h
@@ -31,7 +31,8 @@
 class CopyOrMoveOperationDelegate : public RecursiveOperationDelegate {
  public:
   class CopyOrMoveImpl;
-  using CopyProgressCallback = FileSystemOperation::CopyProgressCallback;
+  using CopyOrMoveProgressCallback =
+      FileSystemOperation::CopyOrMoveProgressCallback;
   using CopyOrMoveOption = FileSystemOperation::CopyOrMoveOption;
   using ErrorBehavior = FileSystemOperation::ErrorBehavior;
 
@@ -84,14 +85,15 @@
     DISALLOW_COPY_AND_ASSIGN(StreamCopyHelper);
   };
 
-  CopyOrMoveOperationDelegate(FileSystemContext* file_system_context,
-                              const FileSystemURL& src_root,
-                              const FileSystemURL& dest_root,
-                              OperationType operation_type,
-                              CopyOrMoveOption option,
-                              ErrorBehavior error_behavior,
-                              const CopyProgressCallback& progress_callback,
-                              StatusCallback callback);
+  CopyOrMoveOperationDelegate(
+      FileSystemContext* file_system_context,
+      const FileSystemURL& src_root,
+      const FileSystemURL& dest_root,
+      OperationType operation_type,
+      CopyOrMoveOption option,
+      ErrorBehavior error_behavior,
+      const CopyOrMoveProgressCallback& progress_callback,
+      StatusCallback callback);
   ~CopyOrMoveOperationDelegate() override;
 
   // RecursiveOperationDelegate overrides:
@@ -129,7 +131,9 @@
                                           base::File::Error error);
   void DidRemoveSourceForMove(StatusCallback callback, base::File::Error error);
 
-  void OnCopyFileProgress(const FileSystemURL& src_url, int64_t size);
+  void OnCopyFileProgress(const FileSystemURL& src_url,
+                          const FileSystemURL& dest_url,
+                          int64_t size);
   FileSystemURL CreateDestURL(const FileSystemURL& src_url) const;
 
 #if DCHECK_IS_ON()
@@ -142,7 +146,7 @@
   OperationType operation_type_;
   CopyOrMoveOption option_;
   ErrorBehavior error_behavior_;
-  CopyProgressCallback progress_callback_;
+  CopyOrMoveProgressCallback progress_callback_;
   StatusCallback callback_;
 
   std::map<CopyOrMoveImpl*, std::unique_ptr<CopyOrMoveImpl>> running_copy_set_;
diff --git a/storage/browser/file_system/copy_or_move_operation_delegate_unittest.cc b/storage/browser/file_system/copy_or_move_operation_delegate_unittest.cc
index edaf1d25..bf8821b0 100644
--- a/storage/browser/file_system/copy_or_move_operation_delegate_unittest.cc
+++ b/storage/browser/file_system/copy_or_move_operation_delegate_unittest.cc
@@ -109,16 +109,16 @@
   };
 };
 
-// Records CopyProgressCallback invocations.
+// Records CopyOrMoveProgressCallback invocations.
 struct ProgressRecord {
-  FileSystemOperation::CopyProgressType type;
+  FileSystemOperation::CopyOrMoveProgressType type;
   FileSystemURL source_url;
   FileSystemURL dest_url;
   int64_t size;
 };
 
 void RecordProgressCallback(std::vector<ProgressRecord>* records,
-                            FileSystemOperation::CopyProgressType type,
+                            FileSystemOperation::CopyOrMoveProgressType type,
                             const FileSystemURL& source_url,
                             const FileSystemURL& dest_url,
                             int64_t size) {
@@ -259,7 +259,8 @@
   base::File::Error CopyWithProgress(
       const FileSystemURL& src,
       const FileSystemURL& dest,
-      const AsyncFileTestHelper::CopyProgressCallback& progress_callback) {
+      const AsyncFileTestHelper::CopyOrMoveProgressCallback&
+          progress_callback) {
     return AsyncFileTestHelper::CopyWithProgress(file_system_context_.get(),
                                                  src, dest, progress_callback);
   }
@@ -515,7 +516,7 @@
   // Copy it.
   ASSERT_EQ(base::File::FILE_OK,
             helper.CopyWithProgress(
-                src, dest, AsyncFileTestHelper::CopyProgressCallback()));
+                src, dest, AsyncFileTestHelper::CopyOrMoveProgressCallback()));
 
   // Verify.
   ASSERT_TRUE(helper.DirectoryExists(src));
@@ -661,9 +662,11 @@
     ASSERT_NE(end_index, records.size());
     ASSERT_NE(begin_index, end_index);
 
-    EXPECT_EQ(FileSystemOperation::BEGIN_COPY_ENTRY, records[begin_index].type);
-    EXPECT_FALSE(records[begin_index].dest_url.is_valid());
-    EXPECT_EQ(FileSystemOperation::END_COPY_ENTRY, records[end_index].type);
+    EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kBegin,
+              records[begin_index].type);
+    EXPECT_EQ(dest_url, records[begin_index].dest_url);
+    EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kEndCopy,
+              records[end_index].type);
     EXPECT_EQ(dest_url, records[end_index].dest_url);
 
     if (test_case.is_directory) {
@@ -674,8 +677,9 @@
       int64_t current_size = 0;
       for (size_t j = begin_index + 1; j < end_index; ++j) {
         if (records[j].source_url == src_url) {
-          EXPECT_EQ(FileSystemOperation::PROGRESS, records[j].type);
-          EXPECT_FALSE(records[j].dest_url.is_valid());
+          EXPECT_EQ(FileSystemOperation::CopyOrMoveProgressType::kProgress,
+                    records[j].type);
+          EXPECT_EQ(dest_url, records[j].dest_url);
           EXPECT_GE(records[j].size, current_size);
           current_size = records[j].size;
         }
diff --git a/storage/browser/file_system/file_system_operation.h b/storage/browser/file_system/file_system_operation.h
index b827d9a..18e98cf2 100644
--- a/storage/browser/file_system/file_system_operation.h
+++ b/storage/browser/file_system/file_system_operation.h
@@ -123,83 +123,111 @@
   // fails some of the operations.
   enum ErrorBehavior { ERROR_BEHAVIOR_ABORT, ERROR_BEHAVIOR_SKIP };
 
-  // Used for progress update callback for Copy().
+  // Used for progress update callback for Copy() and Move().
   //
-  // BEGIN_COPY_ENTRY is fired for each copy creation beginning (for both
-  // file and directory).
-  // The |source_url| is the URL of the source entry. |size| should not be
+  // Note that Move() has both a same-filesystem (1) and a cross-filesystem (2)
+  // implementation.
+  // 1) Requires metadata updates. Depending on the underlying implementation:
+  // - we either only update the metadata of (or in other words, rename) the
+  // moving directory
+  // - or the directories are recursively copied + deleted, while the files are
+  // moved by having their metadata updated.
+  // 2) Degrades into copy + delete: each entry is copied and deleted
+  // recursively.
+  //
+  // kBegin is fired at the start of each copy or move operation (for
+  // both file and directory). The |source_url| and the |destination_url| are
+  // the URLs of the source and the destination entries. |size| should not be
   // used.
   //
-  // END_COPY_ENTRY is fired for each copy creation finishing (for both
-  // file and directory).
-  // The |source_url| is the URL of the source entry. The |destination_url| is
-  // the URL of the destination entry. |size| should not be used.
+  // kProgress is fired periodically during file transfer (not fired for
+  // same-filesystem move and directory copy/move).
+  // The |source_url| and the |destination_url| are the URLs of the source and
+  // the destination entries. |size| is the number of cumulative copied bytes
+  // for the currently copied file. Both at beginning and ending of file
+  // transfer, PROGRESS event should be called. At beginning, |size| should be
+  // 0. At ending, |size| should be the size of the file.
   //
-  // PROGRESS is fired periodically during file copying (not fired for
-  // directory copy).
-  // The |source_url| is the URL of the source file. |size| is the number
-  // of cumulative copied bytes for the currently copied file.
-  // Both at beginning and ending of file copying, PROGRESS event should be
-  // called. At beginning, |size| should be 0. At ending, |size| should be
-  // the size of the file.
+  // kEndCopy is fired for each destination entry that has been successfully
+  // copied (for both file and directory). The |source_url| and the
+  // |destination_url| are the URLs of the source and the destination entries.
+  // |size| should not be used.
   //
-  // Here is an example callback sequence of recursive copy. Suppose
-  // there are a/b/c.txt (100 bytes) and a/b/d.txt (200 bytes), and trying to
-  // copy a to x recursively, then the progress update sequence will be:
+  // kEndMove is fired for each entry that has been successfully moved (for both
+  // file and directory), in the case of a same-filesystem move. The
+  // |source_url| and the |destination_url| are the URLs of the source and the
+  // destination entries. |size| should not be used.
   //
-  // BEGIN_COPY_ENTRY a  (starting create "a" directory in x/).
-  // END_COPY_ENTRY a x/a (creating "a" directory in x/ is finished).
+  // kEndRemoveSource, applies in the Move() case only, and is fired for each
+  // source entry that has been successfully removed from its source location
+  // (for both file and directory). The |source_url| is the URL of the source
+  // entry. |destination_url| and |size| should not be used.
   //
-  // BEGIN_COPY_ENTRY a/b (starting create "b" directory in x/a).
-  // END_COPY_ENTRY a/b x/a/b (creating "b" directory in x/a/ is finished).
+  // When moving files, the expected events are as follows.
+  // Copy: kBegin -> kProgress -> ... -> kProgress -> kEndCopy.
+  // Move (same-filesystem): kBegin -> kEndMove.
+  // Move (cross-filesystem): kBegin -> kProgress -> ... -> kProgress ->
+  // kEndCopy -> kEndRemoveSource.
   //
-  // BEGIN_COPY_ENTRY a/b/c.txt (starting to copy "c.txt" in x/a/b/).
-  // PROGRESS a/b/c.txt 0 (The first PROGRESS's |size| should be 0).
-  // PROGRESS a/b/c.txt 10
+  // Here is an example callback sequence of for a copy or a cross-filesystem
+  // move. Suppose there are a/b/c.txt (100 bytes) and a/b/d.txt (200 bytes),
+  // and trying to transfer a to x recursively, then the progress update
+  // sequence will be:
+  //
+  // kBegin a x/a (starting create "a" directory in x/).
+  // kEndCopy a x/a (creating "a" directory in x/ is finished).
+  //
+  // kBegin a/b x/a/b (starting create "b" directory in x/a).
+  // kEndCopy a/b x/a/b (creating "b" directory in x/a/ is
+  //                     finished).
+  //
+  // kBegin a/b/c.txt x/a/b/c.txt (starting to transfer "c.txt" in
+  //                               x/a/b/).
+  // kProgress a/b/c.txt x/a/b/c.txt 0 (The first kProgress's |size|
+  //                                    should be 0).
+  // kProgress a/b/c.txt x/a/b/c.txt 10
   //    :
-  // PROGRESS a/b/c.txt 90
-  // PROGRESS a/b/c.txt 100 (The last PROGRESS's |size| should be the size of
-  //                         the file).
-  // END_COPY_ENTRY a/b/c.txt x/a/b/c.txt (copying "c.txt" is finished).
+  // kProgress a/b/c.txt x/a/b/c.txt 90
+  // kProgress a/b/c.txt x/a/b/c.txt 100 (The last kProgress's |size| should be
+  //                                      the size of the file).
+  // kEndCopy a/b/c.txt x/a/b/c.txt (transferring "c.txt" is
+  //                                 finished).
+  // kEndRemoveSource a/b/c.txt ("copy + delete" move case).
   //
-  // BEGIN_COPY_ENTRY a/b/d.txt (starting to copy "d.txt" in x/a/b).
-  // PROGRESS a/b/d.txt 0 (The first PROGRESS's |size| should be 0).
-  // PROGRESS a/b/d.txt 10
+  // kBegin a/b/d.txt x/a/b/d.txt (starting to transfer "d.txt" in x/a/b).
+  // kProgress a/b/d.txt x/a/b/d.txt 0 (The first kProgress's |size| should be
+  //                                    0).
+  // kProgress a/b/d.txt x/a/b/d.txt 10
   //    :
-  // PROGRESS a/b/d.txt 190
-  // PROGRESS a/b/d.txt 200 (The last PROGRESS's |size| should be the size of
-  //                         the file).
-  // END_COPY_ENTRY a/b/d.txt x/a/b/d.txt (copy "d.txt" is finished).
+  // kProgress a/b/d.txt x/a/b/d.txt 190
+  // kProgress a/b/d.txt x/a/b/d.txt 200 (The last kProgress's |size| should be
+  //                                      the size of the file).
+  // kEndCopy a/b/d.txt x/a/b/d.txt (transferring "d.txt" is
+  // finished).
+  // kEndRemoveSource a/b/d.txt ("copy + delete" move case).
+  //
+  // kEndRemoveSource a/b ("copy + delete" move case).
+  //
+  // kEndRemoveSource a ("copy + delete" move case).
   //
   // Note that event sequence of a/b/c.txt and a/b/d.txt can be interlaced,
-  // because they can be done in parallel. Also PROGRESS events are optional,
+  // because they can be done in parallel. Also kProgress events are optional,
   // so they may not be appeared.
   // All the progress callback invocation should be done before StatusCallback
   // given to the Copy is called. Especially if an error is found before first
   // progres callback invocation, the progress callback may NOT invoked for the
   // copy.
   //
-  // Note for future extension. Currently this callback is only supported on
-  // Copy(). We can extend this to Move(), because Move() is sometimes
-  // implemented as "copy then delete."
-  // In more precise, Move() usually can be implemented either 1) by updating
-  // the metadata of resource (e.g. root of moving directory tree), or 2) by
-  // copying directory tree and them removing the source tree.
-  // For 1)'s case, we can simply add BEGIN_MOVE_ENTRY and END_MOVE_ENTRY
-  // for root directory.
-  // For 2)'s case, we can add BEGIN_DELETE_ENTRY and END_DELETE_ENTRY for each
-  // entry.
-  // For both cases, we probably won't need to use PROGRESS event because
-  // these operations should be done quickly (at least much faster than copying
-  // usually).
-  enum CopyProgressType {
-    BEGIN_COPY_ENTRY,
-    END_COPY_ENTRY,
-    PROGRESS,
-    ERROR_COPY_ENTRY
+  enum class CopyOrMoveProgressType {
+    kBegin = 0,
+    kProgress,
+    kEndCopy,
+    kEndMove,
+    kEndRemoveSource,
+    kError,
   };
-  using CopyProgressCallback =
-      base::RepeatingCallback<void(CopyProgressType type,
+  using CopyOrMoveProgressCallback =
+      base::RepeatingCallback<void(CopyOrMoveProgressType type,
                                    const FileSystemURL& source_url,
                                    const FileSystemURL& destination_url,
                                    int64_t size)>;
@@ -268,8 +296,8 @@
   // |error_behavior| specifies whether this continues operation after it
   // failed an operation or not.
   // |progress_callback| is periodically called to report the progress
-  // update. See also the comment of CopyProgressCallback. This callback is
-  // optional.
+  // update. See also the comment of CopyOrMoveProgressCallback. This callback
+  // is optional.
   //
   // For recursive case this internally creates new FileSystemOperations and
   // calls:
@@ -283,13 +311,18 @@
                     const FileSystemURL& dest_path,
                     CopyOrMoveOption option,
                     ErrorBehavior error_behavior,
-                    const CopyProgressCallback& progress_callback,
+                    const CopyOrMoveProgressCallback& progress_callback,
                     StatusCallback callback) = 0;
 
   // Moves a file or directory from |src_path| to |dest_path|. A new file
   // or directory is created at |dest_path| as needed.
   // |option| specifies the minor behavior of Copy(). See CopyOrMoveOption's
   // comment for details.
+  // |error_behavior| specifies whether this continues operation after it
+  // failed an operation or not.
+  // |progress_callback| is periodically called to report the progress
+  // update. See also the comment of CopyProgressCallback. This callback is
+  // optional.
   //
   // For recursive case this internally creates new FileSystemOperations and
   // calls:
@@ -304,6 +337,8 @@
   virtual void Move(const FileSystemURL& src_path,
                     const FileSystemURL& dest_path,
                     CopyOrMoveOption option,
+                    ErrorBehavior error_behavior,
+                    const CopyOrMoveProgressCallback& progress_callback,
                     StatusCallback callback) = 0;
 
   // Checks if a directory is present at |path|.
diff --git a/storage/browser/file_system/file_system_operation_impl.cc b/storage/browser/file_system/file_system_operation_impl.cc
index 32e47fb..fa53a2e 100644
--- a/storage/browser/file_system/file_system_operation_impl.cc
+++ b/storage/browser/file_system/file_system_operation_impl.cc
@@ -99,7 +99,7 @@
     const FileSystemURL& dest_url,
     CopyOrMoveOption option,
     ErrorBehavior error_behavior,
-    const CopyProgressCallback& progress_callback,
+    const CopyOrMoveProgressCallback& progress_callback,
     StatusCallback callback) {
   DCHECK(SetPendingOperationType(kOperationCopy));
   DCHECK(!recursive_operation_delegate_);
@@ -113,16 +113,19 @@
   recursive_operation_delegate_->RunRecursively();
 }
 
-void FileSystemOperationImpl::Move(const FileSystemURL& src_url,
-                                   const FileSystemURL& dest_url,
-                                   CopyOrMoveOption option,
-                                   StatusCallback callback) {
+void FileSystemOperationImpl::Move(
+    const FileSystemURL& src_url,
+    const FileSystemURL& dest_url,
+    CopyOrMoveOption option,
+    ErrorBehavior error_behavior,
+    const CopyOrMoveProgressCallback& progress_callback,
+    StatusCallback callback) {
   DCHECK(SetPendingOperationType(kOperationMove));
   DCHECK(!recursive_operation_delegate_);
   recursive_operation_delegate_ = std::make_unique<CopyOrMoveOperationDelegate>(
       file_system_context(), src_url, dest_url,
-      CopyOrMoveOperationDelegate::OPERATION_MOVE, option, ERROR_BEHAVIOR_ABORT,
-      FileSystemOperation::CopyProgressCallback(),
+      CopyOrMoveOperationDelegate::OPERATION_MOVE, option, error_behavior,
+      progress_callback,
       base::BindOnce(&FileSystemOperationImpl::DidFinishOperation,
                      weak_factory_.GetWeakPtr(), std::move(callback)));
   recursive_operation_delegate_->RunRecursively();
diff --git a/storage/browser/file_system/file_system_operation_impl.h b/storage/browser/file_system/file_system_operation_impl.h
index c096e2a..ee6f52aa 100644
--- a/storage/browser/file_system/file_system_operation_impl.h
+++ b/storage/browser/file_system/file_system_operation_impl.h
@@ -45,11 +45,13 @@
             const FileSystemURL& dest_url,
             CopyOrMoveOption option,
             ErrorBehavior error_behavior,
-            const CopyProgressCallback& progress_callback,
+            const CopyOrMoveProgressCallback& progress_callback,
             StatusCallback callback) override;
   void Move(const FileSystemURL& src_url,
             const FileSystemURL& dest_url,
             CopyOrMoveOption option,
+            ErrorBehavior error_behavior,
+            const CopyOrMoveProgressCallback& progress_callback,
             StatusCallback callback) override;
   void DirectoryExists(const FileSystemURL& url,
                        StatusCallback callback) override;
diff --git a/storage/browser/file_system/file_system_operation_impl_unittest.cc b/storage/browser/file_system/file_system_operation_impl_unittest.cc
index 8ba68dfa..13f885f 100644
--- a/storage/browser/file_system/file_system_operation_impl_unittest.cc
+++ b/storage/browser/file_system/file_system_operation_impl_unittest.cc
@@ -283,7 +283,8 @@
     base::RunLoop run_loop;
     update_observer_.Enable();
     operation_runner()->Move(
-        src, dest, option,
+        src, dest, option, storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
+        storage::FileSystemOperation::CopyOrMoveProgressCallback(),
         RecordStatusCallback(run_loop.QuitClosure(), &status));
     run_loop.Run();
     update_observer_.Disable();
@@ -298,7 +299,7 @@
     update_observer_.Enable();
     operation_runner()->Copy(
         src, dest, option, FileSystemOperation::ERROR_BEHAVIOR_ABORT,
-        FileSystemOperationRunner::CopyProgressCallback(),
+        FileSystemOperation::CopyOrMoveProgressCallback(),
         RecordStatusCallback(run_loop.QuitClosure(), &status));
     run_loop.Run();
     update_observer_.Disable();
diff --git a/storage/browser/file_system/file_system_operation_runner.cc b/storage/browser/file_system/file_system_operation_runner.cc
index 7c186bd..ab92adb 100644
--- a/storage/browser/file_system/file_system_operation_runner.cc
+++ b/storage/browser/file_system/file_system_operation_runner.cc
@@ -94,7 +94,7 @@
     const FileSystemURL& dest_url,
     CopyOrMoveOption option,
     ErrorBehavior error_behavior,
-    const CopyProgressCallback& progress_callback,
+    const CopyOrMoveProgressCallback& progress_callback,
     StatusCallback callback) {
   base::File::Error error = base::File::FILE_OK;
   std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
@@ -111,7 +111,7 @@
   operation_raw->Copy(
       src_url, dest_url, option, error_behavior,
       progress_callback.is_null()
-          ? CopyProgressCallback()
+          ? CopyOrMoveProgressCallback()
           : base::BindRepeating(&FileSystemOperationRunner::OnCopyProgress,
                                 weak_ptr_, id, progress_callback),
       base::BindOnce(&FileSystemOperationRunner::DidFinish, weak_ptr_, id,
@@ -119,10 +119,13 @@
   return id;
 }
 
-OperationID FileSystemOperationRunner::Move(const FileSystemURL& src_url,
-                                            const FileSystemURL& dest_url,
-                                            CopyOrMoveOption option,
-                                            StatusCallback callback) {
+OperationID FileSystemOperationRunner::Move(
+    const FileSystemURL& src_url,
+    const FileSystemURL& dest_url,
+    CopyOrMoveOption option,
+    ErrorBehavior error_behavior,
+    const CopyOrMoveProgressCallback& progress_callback,
+    StatusCallback callback) {
   base::File::Error error = base::File::FILE_OK;
   std::unique_ptr<FileSystemOperation> operation = base::WrapUnique(
       file_system_context_->CreateFileSystemOperation(dest_url, &error));
@@ -135,9 +138,14 @@
   }
   PrepareForWrite(id, dest_url);
   PrepareForWrite(id, src_url);
-  operation_raw->Move(src_url, dest_url, option,
-                      base::BindOnce(&FileSystemOperationRunner::DidFinish,
-                                     weak_ptr_, id, std::move(callback)));
+  operation_raw->Move(
+      src_url, dest_url, option, error_behavior,
+      progress_callback.is_null()
+          ? CopyOrMoveProgressCallback()
+          : base::BindRepeating(&FileSystemOperationRunner::OnCopyProgress,
+                                weak_ptr_, id, progress_callback),
+      base::BindOnce(&FileSystemOperationRunner::DidFinish, weak_ptr_, id,
+                     std::move(callback)));
   return id;
 }
 
@@ -691,8 +699,8 @@
 
 void FileSystemOperationRunner::OnCopyProgress(
     const OperationID id,
-    const CopyProgressCallback& callback,
-    FileSystemOperation::CopyProgressType type,
+    const CopyOrMoveProgressCallback& callback,
+    FileSystemOperation::CopyOrMoveProgressType type,
     const FileSystemURL& source_url,
     const FileSystemURL& dest_url,
     int64_t size) {
diff --git a/storage/browser/file_system/file_system_operation_runner.h b/storage/browser/file_system/file_system_operation_runner.h
index 661cbe0..74cd2c1 100644
--- a/storage/browser/file_system/file_system_operation_runner.h
+++ b/storage/browser/file_system/file_system_operation_runner.h
@@ -43,7 +43,8 @@
   using WriteCallback = FileSystemOperation::WriteCallback;
   using OpenFileCallback = FileSystemOperation::OpenFileCallback;
   using ErrorBehavior = FileSystemOperation::ErrorBehavior;
-  using CopyProgressCallback = FileSystemOperation::CopyProgressCallback;
+  using CopyOrMoveProgressCallback =
+      FileSystemOperation::CopyOrMoveProgressCallback;
   using CopyFileProgressCallback =
       FileSystemOperation::CopyFileProgressCallback;
   using CopyOrMoveOption = FileSystemOperation::CopyOrMoveOption;
@@ -84,7 +85,7 @@
                    const FileSystemURL& dest_url,
                    CopyOrMoveOption option,
                    ErrorBehavior error_behavior,
-                   const CopyProgressCallback& progress_callback,
+                   const CopyOrMoveProgressCallback& progress_callback,
                    StatusCallback callback);
 
   // Moves a file or directory from |src_url| to |dest_url|. A new file
@@ -93,6 +94,8 @@
   OperationID Move(const FileSystemURL& src_url,
                    const FileSystemURL& dest_url,
                    CopyOrMoveOption option,
+                   ErrorBehavior error_behavior,
+                   const CopyOrMoveProgressCallback& progress_callback,
                    StatusCallback callback);
 
   // Checks if a directory is present at |url|.
@@ -283,8 +286,8 @@
                          scoped_refptr<ShareableFileReference> file_ref);
 
   void OnCopyProgress(const OperationID id,
-                      const CopyProgressCallback& callback,
-                      FileSystemOperation::CopyProgressType type,
+                      const CopyOrMoveProgressCallback& callback,
+                      FileSystemOperation::CopyOrMoveProgressType type,
                       const FileSystemURL& source_url,
                       const FileSystemURL& dest_url,
                       int64_t size);
diff --git a/storage/browser/test/async_file_test_helper.cc b/storage/browser/test/async_file_test_helper.cc
index c7b2a6c9..85d5e763 100644
--- a/storage/browser/test/async_file_test_helper.cc
+++ b/storage/browser/test/async_file_test_helper.cc
@@ -100,14 +100,14 @@
 base::File::Error AsyncFileTestHelper::Copy(FileSystemContext* context,
                                             const FileSystemURL& src,
                                             const FileSystemURL& dest) {
-  return CopyWithProgress(context, src, dest, CopyProgressCallback());
+  return CopyWithProgress(context, src, dest, CopyOrMoveProgressCallback());
 }
 
 base::File::Error AsyncFileTestHelper::CopyWithProgress(
     FileSystemContext* context,
     const FileSystemURL& src,
     const FileSystemURL& dest,
-    const CopyProgressCallback& progress_callback) {
+    const CopyOrMoveProgressCallback& progress_callback) {
   base::File::Error result = base::File::FILE_ERROR_FAILED;
   base::RunLoop run_loop;
   context->operation_runner()->Copy(src, dest, FileSystemOperation::OPTION_NONE,
@@ -137,8 +137,11 @@
                                             const FileSystemURL& dest) {
   base::File::Error result = base::File::FILE_ERROR_FAILED;
   base::RunLoop run_loop;
-  context->operation_runner()->Move(src, dest, FileSystemOperation::OPTION_NONE,
-                                    AssignAndQuitCallback(&run_loop, &result));
+  context->operation_runner()->Move(
+      src, dest, FileSystemOperation::OPTION_NONE,
+      storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
+      storage::FileSystemOperation::CopyOrMoveProgressCallback(),
+      AssignAndQuitCallback(&run_loop, &result));
   run_loop.Run();
   return result;
 }
diff --git a/storage/browser/test/async_file_test_helper.h b/storage/browser/test/async_file_test_helper.h
index 341a1a74..1b693ef4 100644
--- a/storage/browser/test/async_file_test_helper.h
+++ b/storage/browser/test/async_file_test_helper.h
@@ -28,7 +28,8 @@
 class AsyncFileTestHelper {
  public:
   using FileEntryList = FileSystemOperation::FileEntryList;
-  using CopyProgressCallback = FileSystemOperation::CopyProgressCallback;
+  using CopyOrMoveProgressCallback =
+      FileSystemOperation::CopyOrMoveProgressCallback;
 
   static const int64_t kDontCheckSize;
 
@@ -42,7 +43,7 @@
       FileSystemContext* context,
       const FileSystemURL& src,
       const FileSystemURL& dest,
-      const CopyProgressCallback& progress_callback);
+      const CopyOrMoveProgressCallback& progress_callback);
 
   // Performs CopyFileLocal from |src| to |dest| and returns the status code.
   static base::File::Error CopyFileLocal(FileSystemContext* context,
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index 3fde26f2..560685a 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -4689,7 +4689,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M90",
-              "revision": "version:90.0.4430.217"
+              "revision": "version:90.0.4430.218"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -4768,7 +4768,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.61"
+              "revision": "version:91.0.4472.62"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -4926,7 +4926,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M90",
-              "revision": "version:90.0.4430.217"
+              "revision": "version:90.0.4430.218"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -5005,7 +5005,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.61"
+              "revision": "version:91.0.4472.62"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 5dad51d..dd05fd1 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -53852,7 +53852,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M90",
-              "revision": "version:90.0.4430.217"
+              "revision": "version:90.0.4430.218"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -53932,7 +53932,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.61"
+              "revision": "version:91.0.4472.62"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54092,7 +54092,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M90",
-              "revision": "version:90.0.4430.217"
+              "revision": "version:90.0.4430.218"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54172,7 +54172,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.61"
+              "revision": "version:91.0.4472.62"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54397,7 +54397,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M90",
-              "revision": "version:90.0.4430.217"
+              "revision": "version:90.0.4430.218"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54476,7 +54476,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.61"
+              "revision": "version:91.0.4472.62"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54634,7 +54634,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M90",
-              "revision": "version:90.0.4430.217"
+              "revision": "version:90.0.4430.218"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54713,7 +54713,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.61"
+              "revision": "version:91.0.4472.62"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54938,7 +54938,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M90",
-              "revision": "version:90.0.4430.217"
+              "revision": "version:90.0.4430.218"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -55017,7 +55017,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.61"
+              "revision": "version:91.0.4472.62"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -55175,7 +55175,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M90",
-              "revision": "version:90.0.4430.217"
+              "revision": "version:90.0.4430.218"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -55254,7 +55254,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.61"
+              "revision": "version:91.0.4472.62"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter b/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter
index d65af86ed..f1d4897 100644
--- a/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter
+++ b/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter
@@ -1,5 +1,9 @@
 # These tests cannot work on Wayland because the platform does not allow clients
 # to position top level windows, activate them, and set focus.
+-All/HostedOrWebAppTest.CtrlClickLink/HostedApp
+-All/HostedOrWebAppTest.CtrlClickLink/WebApp
+-All/HostedOrWebAppTest.OpenLinkInNewTab/HostedApp
+-All/HostedOrWebAppTest.OpenLinkInNewTab/WebApp
 -All/PopupBrowserTest.MoveClampedToCurrentDisplay/0
 -All/PopupBrowserTest.MoveClampedToCurrentDisplay/1
 -AutomationManagerAuraBrowserTest.EventFromAction
@@ -40,14 +44,5 @@
 # are created.
 # TODO(https://crbug.com/1176174): figure out what exactly is wrong and fix
 # the problems.
--All/HostedOrWebAppTest.CtrlClickLink/HostedApp
--All/HostedOrWebAppTest.CtrlClickLink/WebApp
--All/HostedOrWebAppTest.OpenLinkInNewTab/HostedApp
--All/HostedOrWebAppTest.OpenLinkInNewTab/WebApp
 -AudioFocusWebContentsObserverBrowserTest.PlatformAppHasDifferentAudioFocus
--CustomTabBarViewBrowserTest.RightClickMenuShowsCopyUrl
--RemoteCopyBrowserTest.ImageUrl
--RemoteCopyBrowserTest.Text
--RemoteCopyBrowserTest.TextThenImageUrl
--WebAppBrowserTest.CopyURL
 -BrowserNavigatorTest.SwitchToTabLatestWindow
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index efdc7ac..132ab0b 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -352,7 +352,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M91',
-          'revision': 'version:91.0.4472.61',
+          'revision': 'version:91.0.4472.62',
         }
       ],
     },
@@ -376,7 +376,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M90',
-          'revision': 'version:90.0.4430.217',
+          'revision': 'version:90.0.4430.218',
         }
       ],
     },
@@ -424,7 +424,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M91',
-          'revision': 'version:91.0.4472.61',
+          'revision': 'version:91.0.4472.62',
         }
       ],
     },
@@ -448,7 +448,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M90',
-          'revision': 'version:90.0.4430.217',
+          'revision': 'version:90.0.4430.218',
         }
       ],
     },
@@ -496,7 +496,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M91',
-          'revision': 'version:91.0.4472.61',
+          'revision': 'version:91.0.4472.62',
         }
       ],
     },
@@ -520,7 +520,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M90',
-          'revision': 'version:90.0.4430.217',
+          'revision': 'version:90.0.4430.218',
         }
       ],
     },
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 6534f2b..c1de07d 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -711,6 +711,7 @@
       Network.CorsErrorStatus corsErrorStatus
       boolean isWarning
       AffectedRequest request
+      optional SourceCodeLocation location
       optional string initiatorOrigin
       optional Network.IPAddressSpace resourceIPAddressSpace
       optional Network.ClientSecurityState clientSecurityState
@@ -4771,6 +4772,7 @@
       HeaderDisallowedByPreflightResponse
       RedirectContainsCredentials
       InsecurePrivateNetwork
+      NoCorsRedirectModeNotFollow
 
   type CorsErrorStatus extends object
     properties
diff --git a/third_party/blink/public/platform/web_media_player.h b/third_party/blink/public/platform/web_media_player.h
index 41bab3c..654150fe 100644
--- a/third_party/blink/public/platform/web_media_player.h
+++ b/third_party/blink/public/platform/web_media_player.h
@@ -44,6 +44,7 @@
 #include "third_party/blink/public/platform/webaudiosourceprovider_impl.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
+#include "url/gurl.h"
 
 namespace cc {
 class PaintCanvas;
diff --git a/third_party/blink/public/platform/webaudiosourceprovider_impl.h b/third_party/blink/public/platform/webaudiosourceprovider_impl.h
index dfb47a2..76911d6 100644
--- a/third_party/blink/public/platform/webaudiosourceprovider_impl.h
+++ b/third_party/blink/public/platform/webaudiosourceprovider_impl.h
@@ -16,7 +16,6 @@
 #include "base/memory/weak_ptr.h"
 #include "base/synchronization/lock.h"
 #include "media/base/audio_renderer_sink.h"
-#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_audio_source_provider.h"
 #include "third_party/blink/public/platform/web_vector.h"
 
diff --git a/third_party/blink/public/web/blink.h b/third_party/blink/public/web/blink.h
index 0786d214..a2e8029e 100644
--- a/third_party/blink/public/web/blink.h
+++ b/third_party/blink/public/web/blink.h
@@ -31,7 +31,6 @@
 #ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_BLINK_H_
 #define THIRD_PARTY_BLINK_PUBLIC_WEB_BLINK_H_
 
-#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "v8/include/v8.h"
 
@@ -41,6 +40,12 @@
 
 namespace blink {
 
+namespace scheduler {
+class WebThreadScheduler;
+}  // namespace scheduler
+
+class Platform;
+
 // Initialize the entire Blink (wtf, platform, core, modules and web).
 // If you just need wtf and platform, use Platform::Initialize instead.
 //
diff --git a/third_party/blink/public/web/web_v8_features.h b/third_party/blink/public/web/web_v8_features.h
index 8aa9f6e..e8863284 100644
--- a/third_party/blink/public/web/web_v8_features.h
+++ b/third_party/blink/public/web/web_v8_features.h
@@ -26,9 +26,6 @@
   // Enables SharedArrayBuffer for this process.
   BLINK_EXPORT static void EnableSharedArrayBuffer();
 
-  // Enables web assembly threads for this process.
-  BLINK_EXPORT static void EnableWasmThreads();
-
  private:
   WebV8Features() = delete;
 };
diff --git a/third_party/blink/renderer/bindings/core/v8/custom/v8_html_all_collection_custom.cc b/third_party/blink/renderer/bindings/core/v8/custom/v8_html_all_collection_custom.cc
index 14dc366..7b2cd59c 100644
--- a/third_party/blink/renderer/bindings/core/v8/custom/v8_html_all_collection_custom.cc
+++ b/third_party/blink/renderer/bindings/core/v8/custom/v8_html_all_collection_custom.cc
@@ -31,6 +31,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_html_all_collection.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/html_collection_or_element.h"
+#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_element_htmlcollection.h"
 #include "third_party/blink/renderer/platform/bindings/v8_set_return_value.h"
 
 namespace blink {
@@ -61,9 +63,20 @@
   }
 
   TOSTRING_VOID(V8StringResource<>, name, info[0]);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptState* script_state = ScriptState::From(info.This()->CreationContext());
+  v8::Local<v8::Value> v8_value;
+  if (!ToV8Traits<IDLNullable<V8UnionElementOrHTMLCollection>>::ToV8(
+           script_state, impl->NamedGetter(name))
+           .ToLocal(&v8_value)) {
+    return;
+  }
+  bindings::V8SetReturnValue(info, v8_value);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HTMLCollectionOrElement result;
   impl->NamedGetter(name, result);
   V8SetReturnValue(info, result);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 void V8HTMLAllCollection::LegacyCallCustom(
diff --git a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
index 8d43742..947718c 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc
@@ -327,6 +327,17 @@
   form_disabled_callback_->InvokeAndReportException(&element, is_disabled);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void ScriptCustomElementDefinition::RunFormStateRestoreCallback(
+    Element& element,
+    const V8ControlValue* value,
+    const String& mode) {
+  if (!form_state_restore_callback_)
+    return;
+  form_state_restore_callback_->InvokeAndReportException(
+      &element, value, V8FormStateRestoreMode::Create(mode).value());
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void ScriptCustomElementDefinition::RunFormStateRestoreCallback(
     Element& element,
     const FileOrUSVStringOrFormData& value,
@@ -336,5 +347,6 @@
   form_state_restore_callback_->InvokeAndReportException(
       &element, value, V8FormStateRestoreMode::Create(mode).value());
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h
index 839c213..ecdf8b76 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h
@@ -67,9 +67,15 @@
                                  HTMLFormElement* nullable_form) override;
   void RunFormResetCallback(Element& element) override;
   void RunFormDisabledCallback(Element& element, bool is_disabled) override;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void RunFormStateRestoreCallback(Element& element,
+                                   const V8ControlValue* value,
+                                   const String& mode) override;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void RunFormStateRestoreCallback(Element& element,
                                    const FileOrUSVStringOrFormData& value,
                                    const String& mode) override;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
  private:
   // Implementations of |CustomElementDefinition|
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
index e4f0561..af74f72 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
@@ -18,6 +18,7 @@
 #include "third_party/blink/renderer/core/fileapi/blob.h"
 #include "third_party/blink/renderer/core/fileapi/file.h"
 #include "third_party/blink/renderer/core/fileapi/file_list.h"
+#include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/geometry/dom_matrix.h"
 #include "third_party/blink/renderer/core/geometry/dom_matrix_read_only.h"
 #include "third_party/blink/renderer/core/geometry/dom_point.h"
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
index f8e1a44..33c97784 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc
@@ -33,6 +33,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_offscreen_canvas.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_string_resource.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_float32array_uint16array_uint8clampedarray.h"
 #include "third_party/blink/renderer/core/fileapi/blob.h"
 #include "third_party/blink/renderer/core/fileapi/file.h"
 #include "third_party/blink/renderer/core/fileapi/file_list.h"
@@ -784,7 +785,11 @@
       2, 1, base::nullopt, nullptr, ASSERT_NO_EXCEPTION);
   SkPixmap pm = image_data->GetSkPixmap();
   pm.writable_addr32(0, 0)[0] = 200u;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  image_data->data()->GetAsUint8ClampedArray()->BufferBase()->Detach();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   image_data->data().GetAsUint8ClampedArray()->BufferBase()->Detach();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   v8::Local<v8::Value> wrapper =
       ToV8(image_data, scope.GetContext()->Global(), scope.GetIsolate());
diff --git a/third_party/blink/renderer/bindings/core/v8/to_v8_traits.h b/third_party/blink/renderer/bindings/core/v8/to_v8_traits.h
index b298ca7..ab12adfc 100644
--- a/third_party/blink/renderer/bindings/core/v8/to_v8_traits.h
+++ b/third_party/blink/renderer/bindings/core/v8/to_v8_traits.h
@@ -1002,7 +1002,10 @@
     std::enable_if_t<std::is_base_of<bindings::UnionBase, T>::value>> {
   static v8::MaybeLocal<v8::Value> WARN_UNUSED_RESULT
   ToV8(ScriptState* script_state, const T* value) {
-    DCHECK(value);
+    // TODO(crbug.com/1185018): nullptr shouldn't be passed.  This should be
+    // DCHECK(value);
+    if (!value)
+      return v8::Null(script_state->GetIsolate());
     return value->ToV8Value(script_state);
   }
 };
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
index c79fd01a..72248101 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -36,6 +36,7 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/bindings/core/v8/binding_security.h"
 #include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h"
+#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
 #include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h"
 #include "third_party/blink/renderer/bindings/core/v8/rejected_promises.h"
 #include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
@@ -55,6 +56,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_metrics.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_trusted_script.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_trustedscript.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.h"
 #include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
 #include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
@@ -389,10 +391,16 @@
     return {true, v8::MaybeLocal<v8::String>()};
   }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionStringOrTrustedScript* string_or_trusted_script =
+      NativeValueTraits<V8UnionStringOrTrustedScript>::NativeValue(
+          context->GetIsolate(), source, exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrTrustedScript string_or_trusted_script;
   V8StringOrTrustedScript::ToImpl(
       context->GetIsolate(), source, string_or_trusted_script,
       UnionTypeConversionMode::kNotNullable, exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (exception_state.HadException()) {
     exception_state.ClearException();
     // The input was a string or TrustedScript but the conversion failed.
@@ -400,11 +408,18 @@
     return {false, v8::MaybeLocal<v8::String>()};
   }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  if (is_code_like && string_or_trusted_script->IsString()) {
+    string_or_trusted_script->Set(MakeGarbageCollected<TrustedScript>(
+        string_or_trusted_script->GetAsString()));
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (is_code_like && string_or_trusted_script.IsString()) {
     string_or_trusted_script = StringOrTrustedScript::FromTrustedScript(
         MakeGarbageCollected<TrustedScript>(
             string_or_trusted_script.GetAsString()));
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   String stringified_source = TrustedTypesCheckForScript(
       string_or_trusted_script, ToExecutionContext(context), exception_state);
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 411d48c..5c78dd7 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1200,6 +1200,7 @@
 source_set("unit_tests") {
   testonly = true
   sources = [
+    "accessibility/ax_context_test.cc",
     "app_history/app_history_test.cc",
     "clipboard/clipboard_utilities_test.cc",
     "content_capture/content_capture_test.cc",
@@ -1332,6 +1333,7 @@
     "layout/layout_block_test.cc",
     "layout/layout_box_model_object_test.cc",
     "layout/layout_box_test.cc",
+    "layout/layout_embedded_content_test.cc",
     "layout/layout_flexible_box_test.cc",
     "layout/layout_grid_test.cc",
     "layout/layout_image_test.cc",
diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS
index 2819ec27..4015396 100644
--- a/third_party/blink/renderer/core/DEPS
+++ b/third_party/blink/renderer/core/DEPS
@@ -103,6 +103,7 @@
     "+ui/accessibility/ax_enums.mojom-blink-forward.h",
     "+ui/accessibility/ax_event.h",
     "+ui/accessibility/ax_event_intent.h",
+    "+ui/accessibility/ax_mode.h",
     "+ui/base/cursor/cursor.h",
     "+ui/base/ime/ime_text_span.h",
     "+ui/base/ime/mojom/ime_types.mojom-blink.h",
diff --git a/third_party/blink/renderer/core/accessibility/ax_context.cc b/third_party/blink/renderer/core/accessibility/ax_context.cc
index deb84151..fac2708 100644
--- a/third_party/blink/renderer/core/accessibility/ax_context.cc
+++ b/third_party/blink/renderer/core/accessibility/ax_context.cc
@@ -3,13 +3,15 @@
 // found in the LICENSE file.
 
 #include "third_party/blink/renderer/core/accessibility/ax_context.h"
+#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 
 namespace blink {
 
 class AXObjectCache;
 
-AXContext::AXContext(Document& document) : document_(&document) {
+AXContext::AXContext(Document& document, const ui::AXMode& ax_mode)
+    : document_(&document), ax_mode_(ax_mode) {
   DCHECK(document_);
   document_->AddAXContext(this);
 }
@@ -22,6 +24,11 @@
 AXObjectCache& AXContext::GetAXObjectCache() {
   DCHECK(document_);
   DCHECK(document_->IsActive());
+
+  DCHECK_EQ(
+      ax_mode_.mode(),
+      document_->ExistingAXObjectCache()->GetAXMode().mode() & ax_mode_.mode());
+
   return *document_->ExistingAXObjectCache();
 }
 
diff --git a/third_party/blink/renderer/core/accessibility/ax_context.h b/third_party/blink/renderer/core/accessibility/ax_context.h
index aac00c2..8302aeb 100644
--- a/third_party/blink/renderer/core/accessibility/ax_context.h
+++ b/third_party/blink/renderer/core/accessibility/ax_context.h
@@ -8,6 +8,7 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "ui/accessibility/ax_mode.h"
 
 namespace blink {
 
@@ -21,7 +22,8 @@
   USING_FAST_MALLOC(AXContext);
 
  public:
-  explicit AXContext(Document& document);
+  explicit AXContext(Document& document,
+                     const ui::AXMode& mode = ui::kAXModeComplete);
   AXContext(const AXContext&) = delete;
   AXContext& operator=(const AXContext&) = delete;
   virtual ~AXContext();
@@ -36,8 +38,11 @@
 
   Document* GetDocument();
 
+  ui::AXMode GetAXMode() { return ax_mode_; }
+
  protected:
   WeakPersistent<Document> document_;
+  const ui::AXMode ax_mode_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/accessibility/ax_context_test.cc b/third_party/blink/renderer/core/accessibility/ax_context_test.cc
new file mode 100644
index 0000000..5cf5e2c
--- /dev/null
+++ b/third_party/blink/renderer/core/accessibility/ax_context_test.cc
@@ -0,0 +1,59 @@
+// 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/accessibility/ax_context.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+#include "ui/accessibility/ax_mode.h"
+
+namespace blink {
+namespace test {
+
+class AXContextTest : public RenderingTest {};
+
+TEST_F(AXContextTest, AXContextCreatesAXObjectCache) {
+  SetBodyInnerHTML(R"HTML(<p>Hello, world</p>)HTML");
+
+  EXPECT_FALSE(GetDocument().ExistingAXObjectCache());
+  auto context =
+      std::make_unique<AXContext>(GetDocument(), ui::kAXModeComplete);
+  EXPECT_TRUE(GetDocument().ExistingAXObjectCache());
+  context.reset();
+  EXPECT_FALSE(GetDocument().ExistingAXObjectCache());
+}
+
+TEST_F(AXContextTest, AXContextSetsAXMode) {
+  SetBodyInnerHTML(R"HTML(<p>Hello, world</p>)HTML");
+
+  constexpr ui::AXMode mode_1 = ui::AXMode::kWebContents;
+  constexpr ui::AXMode mode_2 = ui::AXMode::kScreenReader;
+  ui::AXMode mode_combined = mode_1;
+  mode_combined |= mode_2;
+
+  EXPECT_FALSE(GetDocument().ExistingAXObjectCache());
+
+  // Create a context with mode_1.
+  auto context_1 = std::make_unique<AXContext>(GetDocument(), mode_1);
+  EXPECT_TRUE(GetDocument().ExistingAXObjectCache());
+  EXPECT_EQ(mode_1, GetDocument().ExistingAXObjectCache()->GetAXMode());
+
+  // Create a context with mode_2. The AXObjectCache should now use the
+  // logical OR of both modes.
+  auto context_2 = std::make_unique<AXContext>(GetDocument(), mode_2);
+  EXPECT_TRUE(GetDocument().ExistingAXObjectCache());
+  EXPECT_EQ(mode_combined, GetDocument().ExistingAXObjectCache()->GetAXMode());
+
+  // Remove the first context, check that we just get mode_2 active now.
+  context_1.reset();
+  EXPECT_TRUE(GetDocument().ExistingAXObjectCache());
+  EXPECT_EQ(mode_2, GetDocument().ExistingAXObjectCache()->GetAXMode());
+
+  // Remove the second context and the AXObjectCache should go away.
+  context_2.reset();
+  EXPECT_FALSE(GetDocument().ExistingAXObjectCache());
+}
+
+}  // namespace test
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.cc b/third_party/blink/renderer/core/accessibility/ax_object_cache.cc
index 5f714d8b..a5e96bf7 100644
--- a/third_party/blink/renderer/core/accessibility/ax_object_cache.cc
+++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.cc
@@ -50,9 +50,10 @@
   create_function_ = function;
 }
 
-AXObjectCache* AXObjectCache::Create(Document& document) {
+AXObjectCache* AXObjectCache::Create(Document& document,
+                                     const ui::AXMode& ax_mode) {
   DCHECK(create_function_);
-  return create_function_(document);
+  return create_function_(document, ax_mode);
 }
 
 namespace {
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.h b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
index d124445..3930949 100644
--- a/third_party/blink/renderer/core/accessibility/ax_object_cache.h
+++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
@@ -33,6 +33,10 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/platform/wtf/hash_counted_set.h"
 
+namespace ui {
+class AXMode;
+}
+
 namespace blink {
 
 class AbstractInlineTextBox;
@@ -51,7 +55,7 @@
                                                 BlinkAXEventIntentHash,
                                                 BlinkAXEventIntentHashTraits>;
 
-  static AXObjectCache* Create(Document&);
+  static AXObjectCache* Create(Document&, const ui::AXMode&);
 
   AXObjectCache(const AXObjectCache&) = delete;
   AXObjectCache& operator=(const AXObjectCache&) = delete;
@@ -60,6 +64,9 @@
 
   virtual void Dispose() = 0;
 
+  virtual const ui::AXMode& GetAXMode() = 0;
+  virtual void SetAXMode(const ui::AXMode&) = 0;
+
   // A Freeze() occurs during a serialization run.
   // Used here as a hint for DCHECKS to enforce the following behavior:
   // objects in the ax hierarchy should not be destroyed during serialization.
@@ -165,7 +172,8 @@
   virtual AXID GetAXID(Node*) = 0;
   virtual Element* GetElementFromAXID(AXID) = 0;
 
-  typedef AXObjectCache* (*AXObjectCacheCreateFunction)(Document&);
+  typedef AXObjectCache* (*AXObjectCacheCreateFunction)(Document&,
+                                                        const ui::AXMode&);
   static void Init(AXObjectCacheCreateFunction);
 
   // Static helper functions.
diff --git a/third_party/blink/renderer/core/animation/animatable.cc b/third_party/blink/renderer/core/animation/animatable.cc
index 2db8c01..3cea324 100644
--- a/third_party/blink/renderer/core/animation/animatable.cc
+++ b/third_party/blink/renderer/core/animation/animatable.cc
@@ -7,6 +7,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_animation_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_get_animations_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeanimationoptions_unrestricteddouble.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h"
 #include "third_party/blink/renderer/core/animation/animation.h"
 #include "third_party/blink/renderer/core/animation/document_animations.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
@@ -43,6 +45,25 @@
   }
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* CoerceEffectOptions(
+    const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options) {
+  switch (options->GetContentType()) {
+    case V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble::ContentType::
+        kKeyframeAnimationOptions:
+      return MakeGarbageCollected<
+          V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>(
+          options->GetAsKeyframeAnimationOptions());
+    case V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble::ContentType::
+        kUnrestrictedDouble:
+      return MakeGarbageCollected<
+          V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>(
+          options->GetAsUnrestrictedDouble());
+  }
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 UnrestrictedDoubleOrKeyframeEffectOptions CoerceEffectOptions(
     UnrestrictedDoubleOrKeyframeAnimationOptions options) {
   if (options.IsKeyframeAnimationOptions()) {
@@ -53,6 +74,7 @@
         options.GetAsUnrestrictedDouble());
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace
 
@@ -60,7 +82,11 @@
 Animation* Animatable::animate(
     ScriptState* script_state,
     const ScriptValue& keyframes,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const UnrestrictedDoubleOrKeyframeAnimationOptions& options,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   if (!script_state->ContextIsValid())
     return nullptr;
@@ -80,12 +106,22 @@
 
   ReportPermissionsPolicyViolationsIfNecessary(*element->GetExecutionContext(),
                                                *effect->Model());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  if (!options->IsKeyframeAnimationOptions())
+    return element->GetDocument().Timeline().Play(effect);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (!options.IsKeyframeAnimationOptions())
     return element->GetDocument().Timeline().Play(effect);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   Animation* animation;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const KeyframeAnimationOptions* options_dict =
+      options->GetAsKeyframeAnimationOptions();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   const KeyframeAnimationOptions* options_dict =
       options.GetAsKeyframeAnimationOptions();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (!options_dict->hasTimeline()) {
     animation = element->GetDocument().Timeline().Play(effect);
   } else if (AnimationTimeline* timeline = options_dict->timeline()) {
diff --git a/third_party/blink/renderer/core/animation/animatable.h b/third_party/blink/renderer/core/animation/animatable.h
index 041953e..5ed3192 100644
--- a/third_party/blink/renderer/core/animation/animatable.h
+++ b/third_party/blink/renderer/core/animation/animatable.h
@@ -38,12 +38,13 @@
 namespace blink {
 
 class Animation;
-class ExceptionState;
 class Element;
+class ExceptionState;
 class GetAnimationsOptions;
 class ScriptState;
 class ScriptValue;
 class UnrestrictedDoubleOrKeyframeAnimationOptions;
+class V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble;
 
 // https://drafts.csswg.org/web-animations-1/#the-animatable-interface-mixin
 class CORE_EXPORT Animatable {
@@ -52,10 +53,18 @@
   // called on.
   virtual Element* GetAnimationTarget() = 0;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Animation* animate(
+      ScriptState* script_state,
+      const ScriptValue& keyframes,
+      const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Animation* animate(ScriptState*,
                      const ScriptValue&,
                      const UnrestrictedDoubleOrKeyframeAnimationOptions&,
                      ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   Animation* animate(ScriptState*, const ScriptValue&, ExceptionState&);
 
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc
index f7e6982c..5d0854bf 100644
--- a/third_party/blink/renderer/core/animation/animation.cc
+++ b/third_party/blink/renderer/core/animation/animation.cc
@@ -37,6 +37,8 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h"
 #include "third_party/blink/renderer/core/animation/animation_timeline.h"
 #include "third_party/blink/renderer/core/animation/animation_utils.h"
 #include "third_party/blink/renderer/core/animation/compositor_animations.h"
@@ -183,6 +185,19 @@
 
   return a_ms > b_ms;
 }
+
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8CSSNumberish* CSSNumberishToV8CSSNumberish(const CSSNumberish& value) {
+  if (value.IsDouble()) {
+    return MakeGarbageCollected<V8CSSNumberish>(value.GetAsDouble());
+  } else if (value.IsCSSNumericValue()) {
+    return MakeGarbageCollected<V8CSSNumberish>(value.GetAsCSSNumericValue());
+  }
+  DCHECK(value.IsNull());
+  return nullptr;
+}
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 }  // namespace
 
 Animation* Animation::Create(AnimationEffect* effect,
@@ -199,14 +214,24 @@
 
   // TODO(crbug.com/1097041): Support 'auto' value.
   if (timeline->IsScrollTimeline()) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* time_range = To<ScrollTimeline>(timeline)->timeRange();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     DoubleOrScrollTimelineAutoKeyword time_range;
     To<ScrollTimeline>(timeline)->timeRange(time_range);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     // TODO(crbug.com/1140602): Support progress based animations
     // We are currently abusing the intended use of the "auto" keyword. We are
     // using it here as a signal to use progress based timeline instead of
     // having a range based current time. We are doing this maintain backwards
     // compatibility with existing tests.
-    if (time_range.IsScrollTimelineAutoKeyword()) {
+    if (
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+        time_range->IsScrollTimelineAutoKeyword()
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+        time_range.IsScrollTimelineAutoKeyword()
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ) {
       exception_state.ThrowDOMException(
           DOMExceptionCode::kNotSupportedError,
           "progress based animations are not supported");
@@ -322,9 +347,9 @@
 }
 
 // https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation.
-void Animation::setCurrentTime(CSSNumberish current_time,
+void Animation::setCurrentTime(const V8CSSNumberish* current_time,
                                ExceptionState& exception_state) {
-  if (current_time.IsNull()) {
+  if (!current_time) {
     // If the current time is resolved, then throw a TypeError.
     if (CurrentTimeInternal()) {
       exception_state.ThrowTypeError(
@@ -333,7 +358,7 @@
     return;
   }
 
-  if (current_time.IsCSSNumericValue()) {
+  if (current_time->IsCSSNumericValue()) {
     // Throw exception for CSSNumberish that is a CSSNumericValue
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
@@ -341,10 +366,10 @@
     return;
   }
 
-  DCHECK(current_time.IsDouble());
+  DCHECK(current_time->IsDouble());
   // Convert from double to AnimationTimeDelta for internal use.
   base::Optional<AnimationTimeDelta> new_current_time =
-      AnimationTimeDelta::FromMillisecondsD(current_time.GetAsDouble());
+      AnimationTimeDelta::FromMillisecondsD(current_time->GetAsDouble());
 
   DCHECK(new_current_time);
   SetCurrentTimeInternal(new_current_time.value());
@@ -368,11 +393,22 @@
   NotifyProbe();
 }
 
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+// https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation.
+void Animation::setCurrentTime(CSSNumberish current_time,
+                               ExceptionState& exception_state) {
+  // Forward to the new implementation.
+  setCurrentTime(CSSNumberishToV8CSSNumberish(current_time), exception_state);
+}
+
 void Animation::setCurrentTime(CSSNumberish current_time) {
   NonThrowableExceptionState exception_state;
   setCurrentTime(current_time, exception_state);
 }
 
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 // https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation
 // See steps for silently setting the current time. The preliminary step of
 // handling an unresolved time are to be handled by the caller.
@@ -415,13 +451,56 @@
   hold_phase_ = base::nullopt;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8CSSNumberish* Animation::startTime() const {
+  if (start_time_) {
+    return MakeGarbageCollected<V8CSSNumberish>(
+        start_time_.value().InMillisecondsF());
+  }
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void Animation::startTime(CSSNumberish& startTime) const {
   startTime =
       start_time_
           ? CSSNumberish::FromDouble(start_time_.value().InMillisecondsF())
           : CSSNumberish();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// https://drafts.csswg.org/web-animations/#the-current-time-of-an-animation
+V8CSSNumberish* Animation::currentTime() const {
+  // 1. If the animation’s hold time is resolved,
+  //    The current time is the animation’s hold time.
+  if (hold_time_.has_value()) {
+    return MakeGarbageCollected<V8CSSNumberish>(
+        hold_time_.value().InMillisecondsF());
+  }
+
+  // 2.  If any of the following are true:
+  //    * the animation has no associated timeline, or
+  //    * the associated timeline is inactive, or
+  //    * the animation’s start time is unresolved.
+  // The current time is an unresolved time value.
+  if (!timeline_ || !timeline_->IsActive() || !start_time_)
+    return nullptr;
+
+  // 3. Otherwise,
+  // current time = (timeline time - start time) × playback rate
+  base::Optional<AnimationTimeDelta> timeline_time = timeline_->CurrentTime();
+
+  // An active timeline should always have a value, and since inactive timeline
+  // is handled in step 2 above, make sure that timeline_time has a value.
+  DCHECK(timeline_time.has_value());
+
+  AnimationTimeDelta calculated_current_time =
+      (timeline_time.value() - start_time_.value()) * playback_rate_;
+
+  return MakeGarbageCollected<V8CSSNumberish>(
+      calculated_current_time.InMillisecondsF());
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 // https://drafts.csswg.org/web-animations/#the-current-time-of-an-animation
 void Animation::currentTime(CSSNumberish& currentTime) const {
   // 1. If the animation’s hold time is resolved,
@@ -454,6 +533,7 @@
   currentTime =
       CSSNumberish::FromDouble(calculated_current_time.InMillisecondsF());
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 bool Animation::ValidateHoldTimeAndPhase() const {
   return hold_phase_ ||
@@ -912,9 +992,9 @@
 }
 
 // https://drafts.csswg.org/web-animations/#setting-the-start-time-of-an-animation
-void Animation::setStartTime(CSSNumberish start_time,
+void Animation::setStartTime(const V8CSSNumberish* start_time,
                              ExceptionState& exception_state) {
-  if (!start_time.IsNull() && start_time.IsCSSNumericValue()) {
+  if (start_time && start_time->IsCSSNumericValue()) {
     // Throw exception for CSSNumberish that is a CSSNumericValue
     exception_state.ThrowDOMException(
         DOMExceptionCode::kNotSupportedError,
@@ -922,13 +1002,13 @@
     return;
   }
 
-  base::Optional<AnimationTimeDelta> new_start_time =
-      !start_time.IsNull()
-          ? base::make_optional(
-                AnimationTimeDelta::FromMillisecondsD(start_time.GetAsDouble()))
-          : base::nullopt;
+  base::Optional<AnimationTimeDelta> new_start_time;
+  if (start_time) {
+    new_start_time =
+        AnimationTimeDelta::FromMillisecondsD(start_time->GetAsDouble());
+  }
 
-  bool had_start_time = start_time_.has_value();
+  const bool had_start_time = start_time_.has_value();
 
   // 1. Let timeline time be the current time value of the timeline that
   //    animation is associated with. If there is no timeline associated with
@@ -1013,11 +1093,22 @@
   NotifyProbe();
 }
 
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+// https://drafts.csswg.org/web-animations/#setting-the-start-time-of-an-animation
+void Animation::setStartTime(CSSNumberish start_time,
+                             ExceptionState& exception_state) {
+  // Forward to the new implementation.
+  setStartTime(CSSNumberishToV8CSSNumberish(start_time), exception_state);
+}
+
 void Animation::setStartTime(CSSNumberish start_time) {
   NonThrowableExceptionState exception_state;
   setStartTime(start_time, exception_state);
 }
 
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 // https://drafts.csswg.org/web-animations-1/#setting-the-associated-effect
 void Animation::setEffect(AnimationEffect* new_effect) {
   // 1. Let old effect be the current associated effect of animation, if any.
@@ -1839,12 +1930,20 @@
   // 4. If previous time is resolved, set the current time of animation to
   //    previous time
   pending_playback_rate_ = base::nullopt;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* previous_current_time = currentTime();
+  playback_rate_ = playback_rate;
+  if (previous_current_time) {
+    setCurrentTime(previous_current_time, exception_state);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CSSNumberish previous_current_time;
   currentTime(previous_current_time);
   playback_rate_ = playback_rate;
   if (!previous_current_time.IsNull()) {
     setCurrentTime(previous_current_time, exception_state);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Adds a UseCounter to check if setting playbackRate causes a compensatory
   // seek forcing a change in start_time_
diff --git a/third_party/blink/renderer/core/animation/animation.h b/third_party/blink/renderer/core/animation/animation.h
index 28279f1..b36b5121 100644
--- a/third_party/blink/renderer/core/animation/animation.h
+++ b/third_party/blink/renderer/core/animation/animation.h
@@ -147,10 +147,18 @@
 
   void cancel();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* currentTime() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void currentTime(CSSNumberish&) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   base::Optional<AnimationTimeDelta> CurrentTimeInternal() const;
+  void setCurrentTime(const V8CSSNumberish* current_time,
+                      ExceptionState& exception_state);
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void setCurrentTime(CSSNumberish, ExceptionState& exception_state);
   void setCurrentTime(CSSNumberish);
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void SetCurrentTimeInternal(AnimationTimeDelta);
 
   base::Optional<AnimationTimeDelta> UnlimitedCurrentTime() const;
@@ -209,12 +217,20 @@
   virtual void setTimeline(AnimationTimeline* timeline);
   Document* GetDocument() const;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* startTime() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void startTime(CSSNumberish&) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   base::Optional<AnimationTimeDelta> StartTimeInternal() const {
     return start_time_;
   }
+  virtual void setStartTime(const V8CSSNumberish* start_time,
+                            ExceptionState& exception_state);
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   virtual void setStartTime(CSSNumberish, ExceptionState&);
   void setStartTime(CSSNumberish);
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   const AnimationEffect* effect() const { return content_.Get(); }
   AnimationEffect* effect() { return content_.Get(); }
diff --git a/third_party/blink/renderer/core/animation/animation_test.cc b/third_party/blink/renderer/core/animation/animation_test.cc
index 20d9e924..d5f3799 100644
--- a/third_party/blink/renderer/core/animation/animation_test.cc
+++ b/third_party/blink/renderer/core/animation/animation_test.cc
@@ -38,6 +38,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/animation/animation_clock.h"
 #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h"
 #include "third_party/blink/renderer/core/animation/css_number_interpolation_type.h"
@@ -89,7 +90,12 @@
     timeline = GetDocument().Timeline();
     timeline->ResetForTesting();
     animation = timeline->Play(nullptr);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     animation->setStartTime(CSSNumberish::FromDouble(0));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     animation->setEffect(MakeAnimation());
   }
 
@@ -141,13 +147,11 @@
     Timing timing;
     timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
 
-    Persistent<StringKeyframe> start_keyframe =
-        MakeGarbageCollected<StringKeyframe>();
+    StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>();
     start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
                                         SecureContextMode::kInsecureContext,
                                         nullptr);
-    Persistent<StringKeyframe> end_keyframe =
-        MakeGarbageCollected<StringKeyframe>();
+    StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>();
     end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
                                       SecureContextMode::kInsecureContext,
                                       nullptr);
@@ -216,28 +220,44 @@
     GetPage().Animator().ServiceScriptedAnimations(new_time);
   }
 
-  bool StartTimeIsSet(Persistent<blink::Animation> animation) {
+  bool StartTimeIsSet(Animation* animation) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    return animation->startTime();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     CSSNumberish start_time;
     animation->startTime(start_time);
     return !start_time.IsNull();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   }
 
-  bool CurrentTimeIsSet(Persistent<blink::Animation> animation) {
+  bool CurrentTimeIsSet(Animation* animation) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    return animation->currentTime();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     CSSNumberish current_time;
     animation->currentTime(current_time);
     return !current_time.IsNull();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   }
 
-  double GetStartTimeMs(Persistent<blink::Animation> animation) {
+  double GetStartTimeMs(Animation* animation) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    return animation->startTime()->GetAsDouble();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     CSSNumberish start_time;
     animation->startTime(start_time);
     return start_time.GetAsDouble();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   }
 
-  double GetCurrentTimeMs(Persistent<blink::Animation> animation) {
+  double GetCurrentTimeMs(Animation* animation) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    return animation->currentTime()->GetAsDouble();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     CSSNumberish current_time;
     animation->currentTime(current_time);
     return current_time.GetAsDouble();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   }
 
 #define EXPECT_TIME(expected, observed) \
@@ -259,12 +279,10 @@
     Timing timing;
     timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
 
-    Persistent<StringKeyframe> start_keyframe =
-        MakeGarbageCollected<StringKeyframe>();
+    StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>();
     start_keyframe->SetCSSPropertyValue(
         property_id, from, SecureContextMode::kInsecureContext, nullptr);
-    Persistent<StringKeyframe> end_keyframe =
-        MakeGarbageCollected<StringKeyframe>();
+    StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>();
     end_keyframe->SetCSSPropertyValue(
         property_id, to, SecureContextMode::kInsecureContext, nullptr);
 
@@ -334,7 +352,12 @@
 
 TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTime) {
   EXPECT_EQ("running", animation->playState());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("running", animation->playState());
   EXPECT_TIME(10000, GetCurrentTimeMs(animation));
 
@@ -344,14 +367,24 @@
 }
 
 TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeNegative) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(-10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("running", animation->playState());
   EXPECT_TIME(-10000, GetCurrentTimeMs(animation));
 
   SimulateFrame(20000);
   EXPECT_TIME(10000, GetCurrentTimeMs(animation));
   animation->setPlaybackRate(-2);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(-10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("finished", animation->playState());
   // A seek can set current time outside the range [0, EffectEnd()].
   EXPECT_TIME(-10000, GetCurrentTimeMs(animation));
@@ -379,12 +412,22 @@
   EXPECT_TIME(10000, GetCurrentTimeMs(animation));
   EXPECT_EQ("running", animation->playState());
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(-10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("finished", animation->playState());
 }
 
 TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimePastContentEnd) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(50000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("finished", animation->playState());
   EXPECT_TIME(50000, GetCurrentTimeMs(animation));
 
@@ -394,7 +437,12 @@
   // Reversing the play direction changes the play state from finished to
   // running.
   animation->setPlaybackRate(-2);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(50000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("running", animation->playState());
   EXPECT_TIME(50000, GetCurrentTimeMs(animation));
   SimulateAwaitReady();
@@ -409,15 +457,27 @@
   EXPECT_EQ(CompositorAnimations::kNoFailure,
             animation->CheckCanStartAnimationOnCompositor(nullptr));
   double limit = std::numeric_limits<double>::max();
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(limit),
+                            ASSERT_NO_EXCEPTION);
+  V8CSSNumberish* current_time = animation->currentTime();
+  ExpectRelativeErrorWithinEpsilon(limit, current_time->GetAsDouble());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(limit));
   CSSNumberish current_time;
   animation->currentTime(current_time);
   ExpectRelativeErrorWithinEpsilon(limit, current_time.GetAsDouble());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_TRUE(animation->CheckCanStartAnimationOnCompositor(nullptr) &
               CompositorAnimations::kEffectHasUnsupportedTimingParameters);
   SimulateFrame(100000);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  current_time = animation->currentTime();
+  ExpectRelativeErrorWithinEpsilon(limit, current_time->GetAsDouble());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->currentTime(current_time);
   ExpectRelativeErrorWithinEpsilon(limit, current_time.GetAsDouble());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 TEST_F(AnimationAnimationTestCompositing, SetCurrentTimeAboveMaxTimeDelta) {
@@ -428,16 +488,27 @@
   EXPECT_EQ(CompositorAnimations::kNoFailure,
             animation->CheckCanStartAnimationOnCompositor(nullptr));
   double limit = 1e30;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(limit),
+                            ASSERT_NO_EXCEPTION);
+  ignore_result(animation->currentTime());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(limit));
   CSSNumberish current_time;
   animation->currentTime(current_time);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_TRUE(animation->CheckCanStartAnimationOnCompositor(nullptr) &
               CompositorAnimations::kEffectHasUnsupportedTimingParameters);
 }
 
 TEST_F(AnimationAnimationTestNoCompositing, SetCurrentTimeSetsStartTime) {
   EXPECT_TIME(0, GetStartTimeMs(animation));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(1000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(1000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_TIME(-1000, GetStartTimeMs(animation));
 
   SimulateFrame(1000);
@@ -450,7 +521,12 @@
   EXPECT_EQ("running", animation->playState());
   EXPECT_TIME(0, GetStartTimeMs(animation));
   EXPECT_TIME(20000, GetCurrentTimeMs(animation));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(10000),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("running", animation->playState());
   EXPECT_TIME(10000, GetStartTimeMs(animation));
   EXPECT_TIME(10000, GetCurrentTimeMs(animation));
@@ -458,20 +534,35 @@
   SimulateFrame(30000);
   EXPECT_TIME(10000, GetStartTimeMs(animation));
   EXPECT_TIME(20000, GetCurrentTimeMs(animation));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-20000),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(-20000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("finished", animation->playState());
 }
 
 TEST_F(AnimationAnimationTestNoCompositing, SetStartTimeLimitsAnimation) {
   // Setting the start time is a seek operation, which is not constrained by the
   // normal limits on the animation.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-50000),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(-50000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("finished", animation->playState());
   EXPECT_TRUE(animation->Limited());
   EXPECT_TIME(50000, GetCurrentTimeMs(animation));
   animation->setPlaybackRate(-1);
   EXPECT_EQ("running", animation->playState());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-100000),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(-100000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("finished", animation->playState());
   EXPECT_TIME(-100000, GetCurrentTimeMs(animation));
   EXPECT_TRUE(animation->Limited());
@@ -481,14 +572,29 @@
   // The setStartTime method is a seek and thus not constrained by the normal
   // limits on the animation.
   SimulateFrame(30000);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-10000),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(-10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("finished", animation->playState());
   EXPECT_TIME(40000, GetCurrentTimeMs(animation));
   EXPECT_TRUE(animation->Limited());
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(50000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_TIME(50000, GetCurrentTimeMs(animation));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(-40000),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(-40000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_TIME(70000, GetCurrentTimeMs(animation));
   EXPECT_EQ("finished", animation->playState());
   EXPECT_TRUE(animation->Limited());
@@ -570,12 +676,22 @@
 
 TEST_F(AnimationAnimationTestNoCompositing, PlayRewindsToStart) {
   // Auto-replay when starting from limit.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(30000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(30000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->play();
   EXPECT_TIME(0, GetCurrentTimeMs(animation));
 
   // Auto-replay when starting past the upper bound.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(40000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->play();
   EXPECT_TIME(0, GetCurrentTimeMs(animation));
   EXPECT_EQ("running", animation->playState());
@@ -585,7 +701,12 @@
   // from a negative value of current time.
   SimulateFrame(10000);
   EXPECT_FALSE(animation->pending());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(-10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("running", animation->playState());
   EXPECT_FALSE(animation->pending());
   animation->play();
@@ -604,7 +725,12 @@
   EXPECT_TIME(30000, GetCurrentTimeMs(animation));
 
   // Snap to end if playing a reversed animation starting past the upper limit.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(40000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("running", animation->playState());
   EXPECT_TRUE(animation->pending());
   animation->play();
@@ -617,7 +743,12 @@
 
   // Snap to the end if playing a reversed animation starting with a negative
   // value for current time.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(-10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->play();
   EXPECT_TIME(30000, GetCurrentTimeMs(animation));
   EXPECT_EQ("running", animation->playState());
@@ -636,11 +767,21 @@
   animation->play();
   EXPECT_TIME(0, GetCurrentTimeMs(animation));
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(40000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->play();
   EXPECT_TIME(40000, GetCurrentTimeMs(animation));
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(-10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->play();
   EXPECT_TIME(-10000, GetCurrentTimeMs(animation));
 }
@@ -658,7 +799,12 @@
 }
 
 TEST_F(AnimationAnimationTestNoCompositing, Reverse) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->pause();
   animation->reverse();
   EXPECT_EQ("running", animation->playState());
@@ -675,7 +821,12 @@
 
 TEST_F(AnimationAnimationTestNoCompositing,
        ReverseHoldsCurrentTimeWithPlaybackRateZero) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setPlaybackRate(0);
   animation->pause();
   animation->reverse();
@@ -689,27 +840,47 @@
 }
 
 TEST_F(AnimationAnimationTestNoCompositing, ReverseSeeksToStart) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(-10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setPlaybackRate(-1);
   animation->reverse();
   EXPECT_TIME(0, GetCurrentTimeMs(animation));
 }
 
 TEST_F(AnimationAnimationTestNoCompositing, ReverseSeeksToEnd) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(40000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->reverse();
   EXPECT_TIME(30000, GetCurrentTimeMs(animation));
 }
 
 TEST_F(AnimationAnimationTestNoCompositing, ReverseBeyondLimit) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(40000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setPlaybackRate(-1);
   animation->reverse();
   EXPECT_EQ("running", animation->playState());
   EXPECT_TRUE(animation->pending());
   EXPECT_TIME(0, GetCurrentTimeMs(animation));
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(-10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->reverse();
   EXPECT_EQ("running", animation->playState());
   EXPECT_TRUE(animation->pending());
@@ -735,7 +906,12 @@
 TEST_F(AnimationAnimationTestNoCompositing, FinishAfterEffectEnd) {
   NonThrowableExceptionState exception_state;
   // OK to set current time out of bounds.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(40000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->finish(exception_state);
   // The finish method triggers a snap to the upper boundary.
   EXPECT_TIME(30000, GetCurrentTimeMs(animation));
@@ -743,7 +919,12 @@
 
 TEST_F(AnimationAnimationTestNoCompositing, FinishBeforeStart) {
   NonThrowableExceptionState exception_state;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(-10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setPlaybackRate(-1);
   animation->finish(exception_state);
   EXPECT_TIME(0, GetCurrentTimeMs(animation));
@@ -753,7 +934,12 @@
        FinishDoesNothingWithPlaybackRateZero) {
   // Cannot finish an animation that has a playback rate of zero.
   DummyExceptionStateForTesting exception_state;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setPlaybackRate(0);
   animation->finish(exception_state);
   EXPECT_TIME(10000, GetCurrentTimeMs(animation));
@@ -768,7 +954,12 @@
   timing.iteration_count = std::numeric_limits<double>::infinity();
   animation->setEffect(MakeGarbageCollected<KeyframeEffect>(
       nullptr, MakeEmptyEffectModel(), timing));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(10000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(10000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   DummyExceptionStateForTesting exception_state;
   animation->finish(exception_state);
@@ -864,7 +1055,12 @@
 
   SimulateFrame(20000);
   EXPECT_TIME(10000, GetCurrentTimeMs(animation));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(20000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(20000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_TIME(20000, GetCurrentTimeMs(animation));
 }
 
@@ -938,13 +1134,23 @@
 
 TEST_F(AnimationAnimationTestNoCompositing, SetEffect) {
   animation = timeline->Play(nullptr);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(0));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   AnimationEffect* effect1 = MakeAnimation();
   AnimationEffect* effect2 = MakeAnimation();
   animation->setEffect(effect1);
   EXPECT_EQ(effect1, animation->effect());
   EXPECT_TIME(0, GetCurrentTimeMs(animation));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(15000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(15000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setEffect(effect2);
   EXPECT_TIME(15000, GetCurrentTimeMs(animation));
   EXPECT_EQ(nullptr, effect1->GetAnimationForTesting());
@@ -953,7 +1159,12 @@
 }
 
 TEST_F(AnimationAnimationTestNoCompositing, SetEffectLimitsAnimation) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(20000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(20000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setEffect(MakeAnimation(10));
   EXPECT_TIME(20000, GetCurrentTimeMs(animation));
   EXPECT_TRUE(animation->Limited());
@@ -962,7 +1173,12 @@
 }
 
 TEST_F(AnimationAnimationTestNoCompositing, SetEffectUnlimitsAnimation) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(40000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(40000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setEffect(MakeAnimation(60));
   EXPECT_FALSE(animation->Limited());
   EXPECT_TIME(40000, GetCurrentTimeMs(animation));
@@ -999,7 +1215,12 @@
   auto* keyframe_effect = MakeGarbageCollected<KeyframeEffect>(
       nullptr, MakeEmptyEffectModel(), timing);
   animation = timeline->Play(keyframe_effect);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(0));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Next effect change at end of start delay.
   SimulateFrame(0);
@@ -1031,7 +1252,12 @@
   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
 
   // Reset to start of animation. Next effect at the end of the start delay.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(0),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(0));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   SimulateFrame(3000);
   EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(1),
                    animation->TimeToEffectChange().value());
@@ -1048,7 +1274,12 @@
   EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
 
   // Reversed animation from end time. Next effect after end delay.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(3000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(3000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setPlaybackRate(-1);
   animation->Update(kTimingUpdateOnDemand);
   SimulateFrame(3000);
@@ -1079,7 +1310,12 @@
        TimeToNextEffectWhenCancelledBeforeStart) {
   EXPECT_TIMEDELTA(AnimationTimeDelta(),
                    animation->TimeToEffectChange().value());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(-8000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(-8000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setPlaybackRate(2);
   EXPECT_EQ("running", animation->playState());
   animation->cancel();
@@ -1095,7 +1331,12 @@
        TimeToNextEffectWhenCancelledBeforeStartReverse) {
   EXPECT_TIMEDELTA(AnimationTimeDelta(),
                    animation->TimeToEffectChange().value());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(9000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(9000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setPlaybackRate(-3);
   EXPECT_EQ("running", animation->playState());
   animation->cancel();
@@ -1118,6 +1359,7 @@
 }
 
 TEST_F(AnimationAnimationTestNoCompositing, AttachedAnimations) {
+  // Prevent |element| from being collected by |CollectAllGarbageForTesting|.
   Persistent<Element> element = GetDocument().CreateElementForBinding("foo");
 
   Timing timing;
@@ -1164,7 +1406,12 @@
 
 TEST_F(AnimationAnimationTestNoCompositing, PlayBackwardsAfterCancel) {
   animation->setPlaybackRate(-1);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(15000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(15000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->cancel();
   EXPECT_EQ("idle", animation->playState());
   EXPECT_FALSE(animation->pending());
@@ -1406,12 +1653,10 @@
   animation->setPlaybackRate(1);
 
   // Finally, change the keyframes to something unsupported by the compositor.
-  Persistent<StringKeyframe> start_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>();
   start_keyframe->SetCSSPropertyValue(
       CSSPropertyID::kLeft, "0", SecureContextMode::kInsecureContext, nullptr);
-  Persistent<StringKeyframe> end_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>();
   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kLeft, "100px",
                                     SecureContextMode::kInsecureContext,
                                     nullptr);
@@ -1455,13 +1700,11 @@
 
   // Now change the keyframes; this should mark the animation as compositor
   // pending as we need to sync the compositor side.
-  Persistent<StringKeyframe> start_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>();
   start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
                                       SecureContextMode::kInsecureContext,
                                       nullptr);
-  Persistent<StringKeyframe> end_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>();
   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
                                     SecureContextMode::kInsecureContext,
                                     nullptr);
@@ -1522,7 +1765,12 @@
   EXPECT_TRUE(animation->HasActiveAnimationsOnCompositor());
 
   // Kick the animation out of the play-pending state.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(0));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // No size change and animation does not require a restart.
   keyframe_effect->UpdateBoxSizeAndCheckTransformAxisAlignment(
@@ -1571,7 +1819,12 @@
   EXPECT_TRUE(animation->HasActiveAnimationsOnCompositor());
   keyframe_effect->UpdateBoxSizeAndCheckTransformAxisAlignment(
       FloatSize(100, 200));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(0));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Transform is not height dependent and a change to the height does not force
   // an animation restart.
@@ -1613,7 +1866,12 @@
   EXPECT_TRUE(animation->HasActiveAnimationsOnCompositor());
   keyframe_effect->UpdateBoxSizeAndCheckTransformAxisAlignment(
       FloatSize(100, 200));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(0));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Transform is not width dependent and a change to the width does not force
   // an animation restart.
@@ -1660,13 +1918,11 @@
   Timing timing;
   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
 
-  Persistent<StringKeyframe> start_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>();
   start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
                                       SecureContextMode::kInsecureContext,
                                       nullptr);
-  Persistent<StringKeyframe> end_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>();
   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
                                     SecureContextMode::kInsecureContext,
                                     nullptr);
@@ -1727,13 +1983,11 @@
   Timing timing;
   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
 
-  Persistent<StringKeyframe> start_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>();
   start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
                                       SecureContextMode::kInsecureContext,
                                       nullptr);
-  Persistent<StringKeyframe> end_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>();
   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
                                     SecureContextMode::kInsecureContext,
                                     nullptr);
@@ -1759,7 +2013,13 @@
 
   UpdateAllLifecyclePhasesForTest();
   const double TEST_START_TIME = 10;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  scroll_animation->setStartTime(
+      MakeGarbageCollected<V8CSSNumberish>(TEST_START_TIME),
+      ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   scroll_animation->setStartTime(CSSNumberish::FromDouble(TEST_START_TIME));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   scroll_animation->play();
   EXPECT_EQ(scroll_animation->CheckCanStartAnimationOnCompositor(nullptr),
             CompositorAnimations::kNoFailure);
@@ -1861,13 +2121,11 @@
   // Create KeyframeEffect
   Timing timing;
   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
-  Persistent<StringKeyframe> start_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>();
   start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
                                       SecureContextMode::kInsecureContext,
                                       nullptr);
-  Persistent<StringKeyframe> end_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>();
   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
                                     SecureContextMode::kInsecureContext,
                                     nullptr);
@@ -1898,14 +2156,24 @@
 
   // Advances the animation to "finished" state. The composited animation will
   // be destroyed accordingly.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  scroll_animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000),
+                                   ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   scroll_animation->setCurrentTime(CSSNumberish::FromDouble(50000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ(scroll_animation->playState(), "finished");
   scroll_animation->Update(kTimingUpdateForAnimationFrame);
   GetDocument().GetPendingAnimations().Update(nullptr, true);
   EXPECT_FALSE(scroll_animation->HasActiveAnimationsOnCompositor());
 
   // Restarting the animation should create a new compositor animation.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  scroll_animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(100),
+                                   ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   scroll_animation->setCurrentTime(CSSNumberish::FromDouble(100));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   UpdateAllLifecyclePhasesForTest();
   EXPECT_EQ(scroll_animation->playState(), "running");
   scroll_animation->Update(kTimingUpdateForAnimationFrame);
@@ -1942,7 +2210,12 @@
   EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame));
 
   // Asynchronous completion.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(50000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("finished", animation->playState());
   EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame));
 }
@@ -1962,7 +2235,12 @@
   EXPECT_TRUE(animation->HasPendingActivity());
 
   // Resolving the finished promise clears the pending activity.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(50000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("finished", animation->playState());
   SimulateMicrotask();
   EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame));
@@ -1993,8 +2271,7 @@
   EXPECT_FALSE(animation->HasPendingActivity());
 
   // Attaching a listener for the finished event indicates pending activity.
-  Persistent<MockEventListener> event_listener =
-      MakeGarbageCollected<MockEventListener>();
+  MockEventListener* event_listener = MakeGarbageCollected<MockEventListener>();
   animation->addEventListener(event_type_names::kFinish, event_listener);
   EXPECT_TRUE(animation->HasPendingActivity());
 
@@ -2013,7 +2290,12 @@
   EXPECT_TRUE(animation->HasPendingActivity());
 
   // Finishing the animation asynchronously clears the pending activity.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(50000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ("finished", animation->playState());
   SimulateMicrotask();
   EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame));
@@ -2049,13 +2331,11 @@
   Animation* MakeAnimation(const char* target, CompositingMode mode) {
     Timing timing;
     timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
-    Persistent<StringKeyframe> start_keyframe =
-        MakeGarbageCollected<StringKeyframe>();
+    StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>();
     start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
                                         SecureContextMode::kInsecureContext,
                                         nullptr);
-    Persistent<StringKeyframe> end_keyframe =
-        MakeGarbageCollected<StringKeyframe>();
+    StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>();
     end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
                                       SecureContextMode::kInsecureContext,
                                       nullptr);
@@ -2103,8 +2383,8 @@
   RunDocumentLifecycle();
   SetBodyInnerHTML("<div id='foo'></div><div id='bar'></div>");
 
-  Persistent<Animation> animA = MakeAnimation("foo", kComposited);
-  Persistent<Animation> animB = MakeAnimation("bar", kNonComposited);
+  Animation* animA = MakeAnimation("foo", kComposited);
+  Animation* animB = MakeAnimation("bar", kNonComposited);
 
   // B's start time synchronized with A's start time.
   EXPECT_TRUE(Update());
@@ -2122,8 +2402,8 @@
   RunDocumentLifecycle();
   SetBodyInnerHTML("<div id='foo'></div><div id='bar'></div>");
 
-  Persistent<Animation> animA = MakeAnimation("foo", kComposited);
-  Persistent<Animation> animB = MakeAnimation("bar", kNonComposited);
+  Animation* animA = MakeAnimation("foo", kComposited);
+  Animation* animB = MakeAnimation("bar", kNonComposited);
 
   EXPECT_TRUE(Update());
   EXPECT_TRUE(animA->pending());
@@ -2141,8 +2421,8 @@
   SetBodyInnerHTML(
       "<div id='foo'></div><div id='bar'></div><div id='baz'></div>");
 
-  Persistent<Animation> animA = MakeAnimation("foo", kComposited);
-  Persistent<Animation> animB = MakeAnimation("bar", kNonComposited);
+  Animation* animA = MakeAnimation("foo", kComposited);
+  Animation* animB = MakeAnimation("bar", kNonComposited);
 
   // This test simulates the conditions in crbug.com/666710. The start of a
   // non-composited animation is deferred in order to synchronize with a
@@ -2156,8 +2436,8 @@
   EXPECT_TRUE(animB->pending());
   animA->cancel();
 
-  Persistent<Animation> animC = MakeAnimation("baz", kComposited);
-  Persistent<Animation> animD = MakeAnimation("bar", kNonComposited);
+  Animation* animC = MakeAnimation("baz", kComposited);
+  Animation* animD = MakeAnimation("bar", kNonComposited);
 
   EXPECT_TRUE(Update());
   // B's is unblocked despite newly created composited animation.
@@ -2206,13 +2486,11 @@
   Timing timing;
   timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
 
-  Persistent<StringKeyframe> start_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* start_keyframe = MakeGarbageCollected<StringKeyframe>();
   start_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "1.0",
                                       SecureContextMode::kInsecureContext,
                                       nullptr);
-  Persistent<StringKeyframe> end_keyframe =
-      MakeGarbageCollected<StringKeyframe>();
+  StringKeyframe* end_keyframe = MakeGarbageCollected<StringKeyframe>();
   end_keyframe->SetCSSPropertyValue(CSSPropertyID::kOpacity, "0.0",
                                     SecureContextMode::kInsecureContext,
                                     nullptr);
diff --git a/third_party/blink/renderer/core/animation/animation_test_helpers.cc b/third_party/blink/renderer/core/animation/animation_test_helpers.cc
index 57e7527f..081611a 100644
--- a/third_party/blink/renderer/core/animation/animation_test_helpers.cc
+++ b/third_party/blink/renderer/core/animation/animation_test_helpers.cc
@@ -77,8 +77,8 @@
   // document.GetStyleResolver().ResolveStyle(element). However that would
   // require our callers to properly register every animation they pass in
   // here, which the current tests do not do.
-  auto* style = document.GetStyleResolver().CreateComputedStyle();
-  StyleResolverState state(document, *element, StyleRequest(style));
+  auto style = document.GetStyleResolver().CreateComputedStyle();
+  StyleResolverState state(document, *element, StyleRequest(style.get()));
   state.SetStyle(style);
 
   ActiveInterpolationsMap map;
diff --git a/third_party/blink/renderer/core/animation/animation_timeline.cc b/third_party/blink/renderer/core/animation/animation_timeline.cc
index e6a822b..a949e930 100644
--- a/third_party/blink/renderer/core/animation/animation_timeline.cc
+++ b/third_party/blink/renderer/core/animation/animation_timeline.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/animation/animation_timeline.h"
 
 #include "base/trace_event/trace_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/animation/document_animations.h"
 #include "third_party/blink/renderer/core/animation/keyframe_effect.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -40,11 +41,20 @@
       Animation::CompareAnimationsOrdering::kPointerOrder);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8CSSNumberish* AnimationTimeline::currentTime() {
+  const base::Optional<base::TimeDelta>& result = CurrentPhaseAndTime().time;
+  if (result)
+    return MakeGarbageCollected<V8CSSNumberish>(result->InMillisecondsF());
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void AnimationTimeline::currentTime(CSSNumberish& currentTime) {
   base::Optional<base::TimeDelta> result = CurrentPhaseAndTime().time;
   currentTime = result ? CSSNumberish::FromDouble(result->InMillisecondsF())
                        : CSSNumberish();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 base::Optional<AnimationTimeDelta> AnimationTimeline::CurrentTime() {
   base::Optional<base::TimeDelta> result = CurrentPhaseAndTime().time;
@@ -63,9 +73,15 @@
   return result ? base::make_optional(result->InSecondsF()) : base::nullopt;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8CSSNumberish* AnimationTimeline::duration() {
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void AnimationTimeline::duration(CSSNumberish& duration) {
   duration = CSSNumberish();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 String AnimationTimeline::phase() {
   switch (CurrentPhaseAndTime().phase) {
diff --git a/third_party/blink/renderer/core/animation/animation_timeline.h b/third_party/blink/renderer/core/animation/animation_timeline.h
index 74ec818..b10daf7 100644
--- a/third_party/blink/renderer/core/animation/animation_timeline.h
+++ b/third_party/blink/renderer/core/animation/animation_timeline.h
@@ -35,12 +35,20 @@
   AnimationTimeline(Document*);
   ~AnimationTimeline() override = default;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  virtual V8CSSNumberish* currentTime();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   virtual void currentTime(CSSNumberish&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   base::Optional<AnimationTimeDelta> CurrentTime();
   base::Optional<double> CurrentTimeMilliseconds();
   base::Optional<double> CurrentTimeSeconds();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  virtual V8CSSNumberish* duration();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   virtual void duration(CSSNumberish&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   String phase();
   TimelinePhase Phase() { return CurrentPhaseAndTime().phase; }
diff --git a/third_party/blink/renderer/core/animation/animation_utils.cc b/third_party/blink/renderer/core/animation/animation_utils.cc
index 0915582..ecc6eef 100644
--- a/third_party/blink/renderer/core/animation/animation_utils.cc
+++ b/third_party/blink/renderer/core/animation/animation_utils.cc
@@ -37,7 +37,7 @@
     return;
 
   StyleResolver& resolver = target->GetDocument().GetStyleResolver();
-  ComputedStyle* style =
+  scoped_refptr<ComputedStyle> style =
       resolver.StyleForInterpolations(*target, interpolations);
 
   for (const auto& property : properties) {
diff --git a/third_party/blink/renderer/core/animation/compositor_animations_test.cc b/third_party/blink/renderer/core/animation/compositor_animations_test.cc
index 70441b1d..c075386b1 100644
--- a/third_party/blink/renderer/core/animation/compositor_animations_test.cc
+++ b/third_party/blink/renderer/core/animation/compositor_animations_test.cc
@@ -182,7 +182,7 @@
       const Timing& timing,
       const KeyframeEffectModelBase& effect) {
     // TODO(crbug.com/725385): Remove once compositor uses InterpolationTypes.
-    auto* style = GetDocument().GetStyleResolver().ResolveStyle(
+    auto style = GetDocument().GetStyleResolver().ResolveStyle(
         element_, StyleRecalcContext());
     effect.SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style,
                                                      nullptr);
@@ -455,7 +455,7 @@
     // As the compositor code only understands CompositorKeyframeValues, we must
     // snapshot the effect to make those available.
     // TODO(crbug.com/725385): Remove once compositor uses InterpolationTypes.
-    auto* style = GetDocument().GetStyleResolver().ResolveStyle(
+    auto style = GetDocument().GetStyleResolver().ResolveStyle(
         element_, StyleRecalcContext());
     effect.SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style,
                                                      nullptr);
@@ -515,7 +515,7 @@
 class LayoutObjectProxy : public LayoutObject {
  public:
   static LayoutObjectProxy* Create(Node* node) {
-    return MakeGarbageCollected<LayoutObjectProxy>(node);
+    return new LayoutObjectProxy(node);
   }
 
   static void Dispose(LayoutObjectProxy* proxy) { proxy->Destroy(); }
@@ -531,6 +531,7 @@
     EnsureIdForTesting();
   }
 
+ private:
   explicit LayoutObjectProxy(Node* node) : LayoutObject(node) {}
 };
 
@@ -635,7 +636,7 @@
   SetCustomProperty("--x", "5");
 
   UpdateAllLifecyclePhasesForTest();
-  auto* style = GetDocument().GetStyleResolver().ResolveStyle(
+  auto style = GetDocument().GetStyleResolver().ResolveStyle(
       element_, StyleRecalcContext());
   EXPECT_TRUE(style->NonInheritedVariables());
   EXPECT_TRUE(style->NonInheritedVariables()
@@ -944,7 +945,7 @@
   auto* keyframe_effect1 =
       MakeGarbageCollected<KeyframeEffect>(element_, animation_effect, timing);
   Animation* animation = timeline_->Play(keyframe_effect1);
-  auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
   animation_effect->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(),
                                                               *style, nullptr);
 
@@ -969,7 +970,7 @@
 
 TEST_P(AnimationCompositorAnimationsTest,
        CanStartElementOnCompositorEffectInvalid) {
-  auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
 
   // Check that we notice the value is not animatable correctly.
   const CSSProperty& target_property1(GetCSSPropertyOutlineStyle());
@@ -1061,7 +1062,7 @@
       MakeGarbageCollected<KeyframeEffect>(element_.Get(), effect1, timing_);
 
   Animation* animation1 = timeline_->Play(keyframe_effect1);
-  auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
   effect1->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(), *style,
                                                      nullptr);
 
@@ -1093,7 +1094,7 @@
 
 TEST_P(AnimationCompositorAnimationsTest,
        CanStartElementOnCompositorEffectTransform) {
-  auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
 
   StringKeyframeEffectModel* effect1 = CreateKeyframeEffectModel(
       CreateReplaceOpKeyframe(CSSPropertyID::kTransform, "none", 0),
@@ -1134,7 +1135,7 @@
 
 TEST_P(AnimationCompositorAnimationsTest,
        CheckCanStartEffectOnCompositorUnsupportedCSSProperties) {
-  auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
 
   StringKeyframeEffectModel* effect1 = CreateKeyframeEffectModel(
       CreateReplaceOpKeyframe(CSSPropertyID::kOpacity, "0", 0),
@@ -1843,7 +1844,7 @@
   auto* keyframe_effect1 = MakeGarbageCollected<KeyframeEffect>(
       element_.Get(), animation_effect1, timing);
   Animation* animation1 = timeline_->Play(keyframe_effect1);
-  auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
   animation_effect1->SnapshotAllCompositorKeyframesIfNecessary(*element_.Get(),
                                                                *style, nullptr);
   EXPECT_EQ(CheckCanStartEffectOnCompositor(timing, *element_.Get(), animation1,
diff --git a/third_party/blink/renderer/core/animation/css/css_animation.cc b/third_party/blink/renderer/core/animation/css/css_animation.cc
index 9e637788..34f54d3 100644
--- a/third_party/blink/renderer/core/animation/css/css_animation.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animation.cc
@@ -60,11 +60,19 @@
   ignore_css_timeline_ = true;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void CSSAnimation::setStartTime(const V8CSSNumberish* start_time,
+                                ExceptionState& exception_state) {
+  PlayStateTransitionScope scope(*this);
+  Animation::setStartTime(start_time, exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void CSSAnimation::setStartTime(CSSNumberish start_time_ms,
                                 ExceptionState& exception_state) {
   PlayStateTransitionScope scope(*this);
   Animation::setStartTime(start_time_ms, exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 AnimationEffect::EventDelegate* CSSAnimation::CreateEventDelegate(
     Element* target,
diff --git a/third_party/blink/renderer/core/animation/css/css_animation.h b/third_party/blink/renderer/core/animation/css/css_animation.h
index 32bfc8a..ad68b5b 100644
--- a/third_party/blink/renderer/core/animation/css/css_animation.h
+++ b/third_party/blink/renderer/core/animation/css/css_animation.h
@@ -51,7 +51,12 @@
   void play(ExceptionState& = ASSERT_NO_EXCEPTION) override;
   void reverse(ExceptionState& = ASSERT_NO_EXCEPTION) override;
   void setTimeline(AnimationTimeline*) override;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void setStartTime(const V8CSSNumberish* start_time,
+                    ExceptionState& exception_state) override;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void setStartTime(CSSNumberish, ExceptionState&) override;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // When set, subsequent changes to animation-play-state no longer affect the
   // play state.
diff --git a/third_party/blink/renderer/core/animation/css/css_animation_update.cc b/third_party/blink/renderer/core/animation/css/css_animation_update.cc
index 55eef78..8fd81d08 100644
--- a/third_party/blink/renderer/core/animation/css/css_animation_update.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animation_update.cc
@@ -50,9 +50,9 @@
 
 void CSSAnimationUpdate::StartTransition(
     const PropertyHandle& property,
-    const ComputedStyle* from,
-    const ComputedStyle* to,
-    const ComputedStyle* reversing_adjusted_start_value,
+    scoped_refptr<const ComputedStyle> from,
+    scoped_refptr<const ComputedStyle> to,
+    scoped_refptr<const ComputedStyle> reversing_adjusted_start_value,
     double reversing_shortening_factor,
     const InertEffect& effect) {
   NewTransition* new_transition = MakeGarbageCollected<NewTransition>();
@@ -73,11 +73,4 @@
 CSSAnimationUpdate::NewTransition::NewTransition() = default;
 CSSAnimationUpdate::NewTransition::~NewTransition() = default;
 
-void CSSAnimationUpdate::NewTransition::Trace(Visitor* visitor) const {
-  visitor->Trace(from);
-  visitor->Trace(to);
-  visitor->Trace(reversing_adjusted_start_value);
-  visitor->Trace(effect);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css/css_animation_update.h b/third_party/blink/renderer/core/animation/css/css_animation_update.h
index 6115ebd..d214301 100644
--- a/third_party/blink/renderer/core/animation/css/css_animation_update.h
+++ b/third_party/blink/renderer/core/animation/css/css_animation_update.h
@@ -154,12 +154,13 @@
     updated_compositor_keyframes_.push_back(animation);
   }
 
-  void StartTransition(const PropertyHandle&,
-                       const ComputedStyle* from,
-                       const ComputedStyle* to,
-                       const ComputedStyle* reversing_adjusted_start_value,
-                       double reversing_shortening_factor,
-                       const InertEffect&);
+  void StartTransition(
+      const PropertyHandle&,
+      scoped_refptr<const ComputedStyle> from,
+      scoped_refptr<const ComputedStyle> to,
+      scoped_refptr<const ComputedStyle> reversing_adjusted_start_value,
+      double reversing_shortening_factor,
+      const InertEffect&);
   void UnstartTransition(const PropertyHandle&);
   void CancelTransition(const PropertyHandle& property) {
     cancelled_transitions_.insert(property);
@@ -191,12 +192,12 @@
    public:
     NewTransition();
     virtual ~NewTransition();
-    void Trace(Visitor* visitor) const;
+    void Trace(Visitor* visitor) const { visitor->Trace(effect); }
 
     PropertyHandle property = HashTraits<blink::PropertyHandle>::EmptyValue();
-    Member<const ComputedStyle> from;
-    Member<const ComputedStyle> to;
-    Member<const ComputedStyle> reversing_adjusted_start_value;
+    scoped_refptr<const ComputedStyle> from;
+    scoped_refptr<const ComputedStyle> to;
+    scoped_refptr<const ComputedStyle> reversing_adjusted_start_value;
     double reversing_shortening_factor;
     Member<const InertEffect> effect;
   };
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc
index 63fbc07ea..782f46e 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -35,6 +35,7 @@
 
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/animation/animation.h"
 #include "third_party/blink/renderer/core/animation/compositor_animations.h"
 #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h"
@@ -1043,9 +1044,14 @@
 
     // Set the current time as the start time for retargeted transitions
     if (retargeted_compositor_transitions.Contains(property)) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      animation->setStartTime(element->GetDocument().Timeline().currentTime(),
+                              ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       CSSNumberish current_time;
       element->GetDocument().Timeline().currentTime(current_time);
       animation->setStartTime(current_time);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     }
     animation->Update(kTimingUpdateOnDemand);
     running_transition->animation = animation;
@@ -1204,14 +1210,14 @@
   }
 
   const ComputedStyle* reversing_adjusted_start_value =
-      state.before_change_style;
+      state.before_change_style.get();
   double reversing_shortening_factor = 1;
   if (interrupted_transition) {
     AnimationEffect* effect = interrupted_transition->animation->effect();
     const base::Optional<double> interrupted_progress =
         effect ? effect->Progress() : base::nullopt;
     if (interrupted_progress) {
-      reversing_adjusted_start_value = interrupted_transition->to;
+      reversing_adjusted_start_value = interrupted_transition->to.get();
       reversing_shortening_factor =
           clampTo((interrupted_progress.value() *
                    interrupted_transition->reversing_shortening_factor) +
@@ -1402,7 +1408,7 @@
                                           animating_element);
 }
 
-const ComputedStyle* CSSAnimations::CalculateBeforeChangeStyle(
+scoped_refptr<const ComputedStyle> CSSAnimations::CalculateBeforeChangeStyle(
     Element& animating_element,
     const ComputedStyle& base_style) {
   ActiveInterpolationsMap interpolations_map;
@@ -1429,17 +1435,32 @@
 
     // Sample animations and add to the interpolatzions map.
     for (Animation* animation : animations) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      V8CSSNumberish* current_time_numberish = animation->currentTime();
+      if (!current_time_numberish)
+        continue;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       CSSNumberish current_time_numberish;
       animation->currentTime(current_time_numberish);
       if (current_time_numberish.IsNull())
         continue;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
-      // CSSNumericValue is not yet supported, verify that it is not used
+        // CSSNumericValue is not yet supported, verify that it is not used
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      DCHECK(!current_time_numberish->IsCSSNumericValue());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       DCHECK(!current_time_numberish.IsCSSNumericValue());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
       base::Optional<AnimationTimeDelta> current_time =
           AnimationTimeDelta::FromMillisecondsD(
-              current_time_numberish.GetAsDouble());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+              current_time_numberish->GetAsDouble()
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+              current_time_numberish.GetAsDouble()
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+          );
 
       auto* effect = DynamicTo<KeyframeEffect>(animation->effect());
       if (!effect)
@@ -1936,11 +1957,4 @@
   visitor->Trace(previous_active_interpolations_for_custom_animations_);
 }
 
-void CSSAnimations::RunningTransition::Trace(Visitor* visitor) const {
-  visitor->Trace(animation);
-  visitor->Trace(from);
-  visitor->Trace(to);
-  visitor->Trace(reversing_adjusted_start_value);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.h b/third_party/blink/renderer/core/animation/css/css_animations.h
index f64d1e56..c326b7e8 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.h
+++ b/third_party/blink/renderer/core/animation/css/css_animations.h
@@ -157,12 +157,12 @@
    public:
     virtual ~RunningTransition() = default;
 
-    void Trace(Visitor*) const;
+    void Trace(Visitor* visitor) const { visitor->Trace(animation); }
 
     Member<Animation> animation;
-    Member<const ComputedStyle> from;
-    Member<const ComputedStyle> to;
-    Member<const ComputedStyle> reversing_adjusted_start_value;
+    scoped_refptr<const ComputedStyle> from;
+    scoped_refptr<const ComputedStyle> to;
+    scoped_refptr<const ComputedStyle> reversing_adjusted_start_value;
     double reversing_shortening_factor;
   };
 
@@ -185,8 +185,8 @@
     Element& animating_element;
     const ComputedStyle& old_style;
     const ComputedStyle& style;
-    const ComputedStyle* before_change_style;
-    const ComputedStyle* cloned_style;
+    scoped_refptr<const ComputedStyle> before_change_style;
+    scoped_refptr<const ComputedStyle> cloned_style;
     const TransitionMap* active_transitions;
     HashSet<PropertyHandle>& listed_properties;
     const CSSTransitionData* transition_data;
@@ -219,7 +219,7 @@
   // on the element as of the previous style change event, except with any
   // styles derived from declarative animations updated to the current time.
   // https://drafts.csswg.org/css-transitions-1/#before-change-style
-  static const ComputedStyle* CalculateBeforeChangeStyle(
+  static scoped_refptr<const ComputedStyle> CalculateBeforeChangeStyle(
       Element& animating_element,
       const ComputedStyle& base_style);
 
diff --git a/third_party/blink/renderer/core/animation/css/css_animations_test.cc b/third_party/blink/renderer/core/animation/css/css_animations_test.cc
index 9982f48a..1e2f5ab 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations_test.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animations_test.cc
@@ -6,6 +6,7 @@
 
 #include "cc/animation/animation.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/animation/animation.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
 #include "third_party/blink/renderer/core/animation/element_animations.h"
@@ -349,21 +350,37 @@
   Animation* animation = GetAnimation();
   int compositor_group = animation->CompositorGroup();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* start_time = animation->startTime();
+  V8CSSNumberish* current_time = animation->currentTime();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CSSNumberish start_time, current_time;
   animation->startTime(start_time);
   animation->currentTime(current_time);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Partially rewind the animation via setStartTime.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* new_start_time = MakeGarbageCollected<V8CSSNumberish>(
+      start_time->GetAsDouble() + (current_time->GetAsDouble() / 2));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CSSNumberish new_start_time = CSSNumberish::FromDouble(
       start_time.GetAsDouble() + (current_time.GetAsDouble() / 2));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   animation->setStartTime(new_start_time, ASSERT_NO_EXCEPTION);
   UpdateAllLifecyclePhasesForTest();
 
   // Verify blink updates.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  current_time = animation->currentTime();
+  EXPECT_TRUE(current_time->IsDouble());
+  EXPECT_NEAR(250, current_time->GetAsDouble(), kTimeToleranceMilliseconds);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->currentTime(current_time);
   EXPECT_TRUE(current_time.IsDouble());
   EXPECT_NEAR(250, current_time.GetAsDouble(), kTimeToleranceMilliseconds);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_NEAR(0.75, element_->GetComputedStyle()->Opacity(), kTolerance);
 
   // Compositor animation needs to restart and will have a new compositor group.
@@ -394,14 +411,25 @@
   int compositor_group = animation->CompositorGroup();
 
   // Advance current time.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(750),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(750), ASSERT_NO_EXCEPTION);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   UpdateAllLifecyclePhasesForTest();
 
   // Verify blink updates.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* current_time = animation->currentTime();
+  EXPECT_TRUE(current_time->IsDouble());
+  EXPECT_NEAR(750, current_time->GetAsDouble(), kTimeToleranceMilliseconds);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CSSNumberish current_time;
   animation->currentTime(current_time);
   EXPECT_TRUE(current_time.IsDouble());
   EXPECT_NEAR(750, current_time.GetAsDouble(), kTimeToleranceMilliseconds);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_NEAR(0.25, element_->GetComputedStyle()->Opacity(), kTolerance);
 
   // Compositor animation needs to restart and will have a new compositor group.
diff --git a/third_party/blink/renderer/core/animation/document_timeline_test.cc b/third_party/blink/renderer/core/animation/document_timeline_test.cc
index 4511af8c..d42c89d 100644
--- a/third_party/blink/renderer/core/animation/document_timeline_test.cc
+++ b/third_party/blink/renderer/core/animation/document_timeline_test.cc
@@ -33,6 +33,7 @@
 #include "base/test/simple_test_tick_clock.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/animation/animation_clock.h"
 #include "third_party/blink/renderer/core/animation/animation_effect.h"
 #include "third_party/blink/renderer/core/animation/keyframe_effect.h"
@@ -370,6 +371,14 @@
   Animation* animation2 = timeline->Play(anim2);
   timeline->PauseAnimationsForTesting(seek_time);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* current_time = animation1->currentTime();
+  EXPECT_NEAR(seek_time.InMillisecondsF(), current_time->GetAsDouble(),
+              Animation::kTimeToleranceMs);
+  current_time = animation2->currentTime();
+  EXPECT_NEAR(seek_time.InMillisecondsF(), current_time->GetAsDouble(),
+              Animation::kTimeToleranceMs);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CSSNumberish current_time;
   animation1->currentTime(current_time);
   EXPECT_NEAR(seek_time.InMillisecondsF(), current_time.GetAsDouble(),
@@ -377,6 +386,7 @@
   animation2->currentTime(current_time);
   EXPECT_NEAR(seek_time.InMillisecondsF(), current_time.GetAsDouble(),
               Animation::kTimeToleranceMs);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 TEST_F(AnimationDocumentTimelineTest, DelayBeforeAnimationStart) {
@@ -411,7 +421,12 @@
   Animation* animation = timeline->Play(nullptr);
   timeline.Clear();
   // Test passes if this does not crash.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setStartTime(MakeGarbageCollected<V8CSSNumberish>(0),
+                          ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setStartTime(CSSNumberish::FromDouble(0));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 TEST_F(AnimationDocumentTimelineTest, PlayAfterDocumentDeref) {
diff --git a/third_party/blink/renderer/core/animation/effect_stack_test.cc b/third_party/blink/renderer/core/animation/effect_stack_test.cc
index bf4f93e..5e69d20 100644
--- a/third_party/blink/renderer/core/animation/effect_stack_test.cc
+++ b/third_party/blink/renderer/core/animation/effect_stack_test.cc
@@ -5,7 +5,9 @@
 #include "third_party/blink/renderer/core/animation/effect_stack.h"
 
 #include <memory>
+
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/animation/animation_clock.h"
 #include "third_party/blink/renderer/core/animation/animation_test_helpers.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
@@ -34,7 +36,13 @@
 
   Animation* Play(KeyframeEffect* effect, double start_time) {
     Animation* animation = timeline->Play(effect);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    animation->setStartTime(
+        MakeGarbageCollected<V8CSSNumberish>(start_time * 1000),
+        ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     animation->setStartTime(CSSNumberish::FromDouble(start_time * 1000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     animation->Update(kTimingUpdateOnDemand);
     return animation;
   }
diff --git a/third_party/blink/renderer/core/animation/element_animations.cc b/third_party/blink/renderer/core/animation/element_animations.cc
index 450887c3..fa1b980 100644
--- a/third_party/blink/renderer/core/animation/element_animations.cc
+++ b/third_party/blink/renderer/core/animation/element_animations.cc
@@ -122,11 +122,10 @@
   visitor->Trace(effect_stack_);
   visitor->Trace(animations_);
   visitor->Trace(worklet_animations_);
-  visitor->Trace(base_computed_style_);
 }
 
 const ComputedStyle* ElementAnimations::BaseComputedStyle() const {
-  return base_computed_style_;
+  return base_computed_style_.get();
 }
 
 const CSSBitset* ElementAnimations::BaseImportantSet() const {
diff --git a/third_party/blink/renderer/core/animation/element_animations.h b/third_party/blink/renderer/core/animation/element_animations.h
index b973b9b..babb8cbf 100644
--- a/third_party/blink/renderer/core/animation/element_animations.h
+++ b/third_party/blink/renderer/core/animation/element_animations.h
@@ -106,7 +106,7 @@
   // change from the running animations) and use that during style recalc,
   // applying only the animation changes on top of it.
   bool animation_style_change_;
-  Member<ComputedStyle> base_computed_style_;
+  scoped_refptr<ComputedStyle> base_computed_style_;
   // Keeps track of the !important declarations used to build the base
   // computed style. These declarations must not be overwritten by animation
   // effects, hence we have to disable the base computed style optimization when
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect.cc b/third_party/blink/renderer/core/animation/keyframe_effect.cc
index c806b30..3970d9ce 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect.cc
+++ b/third_party/blink/renderer/core/animation/keyframe_effect.cc
@@ -32,6 +32,7 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h"
 #include "third_party/blink/renderer/core/animation/animation_input_helpers.h"
 #include "third_party/blink/renderer/core/animation/animation_utils.h"
 #include "third_party/blink/renderer/core/animation/compositor_animations.h"
@@ -87,7 +88,11 @@
     ScriptState* script_state,
     Element* element,
     const ScriptValue& keyframes,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const UnrestrictedDoubleOrKeyframeEffectOptions& options,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   Document* document = element ? &element->GetDocument() : nullptr;
   Timing timing = TimingInput::Convert(options, document, exception_state);
@@ -96,8 +101,18 @@
 
   EffectModel::CompositeOperation composite = EffectModel::kCompositeReplace;
   String pseudo = String();
-  if (options.IsKeyframeEffectOptions()) {
+  if (
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      options->IsKeyframeEffectOptions()
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      options.IsKeyframeEffectOptions()
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* effect_options = options->GetAsKeyframeEffectOptions();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     auto* effect_options = options.GetAsKeyframeEffectOptions();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     composite =
         EffectModel::StringToCompositeOperation(effect_options->composite())
             .value();
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect.h b/third_party/blink/renderer/core/animation/keyframe_effect.h
index 2fea972..a2e059df 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect.h
+++ b/third_party/blink/renderer/core/animation/keyframe_effect.h
@@ -47,6 +47,7 @@
 class PaintArtifactCompositor;
 class SampledEffect;
 class UnrestrictedDoubleOrKeyframeEffectOptions;
+class V8UnionKeyframeEffectOptionsOrUnrestrictedDouble;
 
 // Represents the effect of an Animation on an Element's properties.
 // https://drafts.csswg.org/web-animations/#keyframe-effect
@@ -57,12 +58,21 @@
   enum Priority { kDefaultPriority, kTransitionPriority };
 
   // Web Animations API Bindings constructors.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static KeyframeEffect* Create(
+      ScriptState* script_state,
+      Element* element,
+      const ScriptValue& keyframes,
+      const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static KeyframeEffect* Create(
       ScriptState*,
       Element*,
       const ScriptValue&,
       const UnrestrictedDoubleOrKeyframeEffectOptions&,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static KeyframeEffect* Create(ScriptState*,
                                 Element*,
                                 const ScriptValue&,
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc b/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
index ddc5ed2..f6f2cb4 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
+++ b/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
@@ -160,7 +160,7 @@
 
   auto* effect = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
 
-  auto* style =
+  auto style =
       document->GetStyleResolver().ResolveStyle(element, StyleRecalcContext());
 
   // Snapshot should update first time after construction
@@ -635,7 +635,7 @@
       KeyframesAtZeroAndOne(CSSPropertyID::kOpacity, "0", "1");
   auto* effect = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
 
-  auto* style = GetDocument().GetStyleResolver().ResolveStyle(
+  auto style = GetDocument().GetStyleResolver().ResolveStyle(
       element, StyleRecalcContext());
 
   const CompositorKeyframeValue* value;
@@ -672,7 +672,7 @@
   auto* effect =
       MakeGarbageCollected<StringKeyframeEffectModel>(opacity_keyframes);
 
-  auto* style = GetDocument().GetStyleResolver().ResolveStyle(
+  auto style = GetDocument().GetStyleResolver().ResolveStyle(
       element, StyleRecalcContext());
 
   EXPECT_TRUE(effect->SnapshotAllCompositorKeyframesIfNecessary(
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect_test.cc b/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
index c4f0032e..990602e 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
+++ b/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
@@ -14,6 +14,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h"
 #include "third_party/blink/renderer/core/animation/animation.h"
 #include "third_party/blink/renderer/core/animation/animation_clock.h"
 #include "third_party/blink/renderer/core/animation/animation_test_helpers.h"
@@ -88,8 +90,13 @@
     NonThrowableExceptionState exception_state;
     return KeyframeEffect::Create(
         script_state, element, keyframe_object,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+        MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>(
+            timing_input),
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
         UnrestrictedDoubleOrKeyframeEffectOptions::FromUnrestrictedDouble(
             timing_input),
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
         exception_state);
   }
   static KeyframeEffect* CreateAnimationFromOption(
@@ -100,8 +107,13 @@
     NonThrowableExceptionState exception_state;
     return KeyframeEffect::Create(
         script_state, element, keyframe_object,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+        MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>(
+            const_cast<KeyframeEffectOptions*>(timing_input)),
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
         UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions(
             const_cast<KeyframeEffectOptions*>(timing_input)),
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
         exception_state);
   }
   static KeyframeEffect* CreateAnimation(ScriptState* script_state,
@@ -378,28 +390,48 @@
             keyframe_effect->TimeToReverseEffectChange());
 
   // End of the before phase.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(100000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(100000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(100),
                    keyframe_effect->TimeToForwardsEffectChange());
   EXPECT_TIMEDELTA(AnimationTimeDelta(),
                    keyframe_effect->TimeToReverseEffectChange());
 
   // Nearing the end of the active phase.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(199000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(199000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(1),
                    keyframe_effect->TimeToForwardsEffectChange());
   EXPECT_TIMEDELTA(AnimationTimeDelta(),
                    keyframe_effect->TimeToReverseEffectChange());
 
   // End of the active phase.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(200000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(200000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(100),
                    keyframe_effect->TimeToForwardsEffectChange());
   EXPECT_TIMEDELTA(AnimationTimeDelta(),
                    keyframe_effect->TimeToReverseEffectChange());
 
   // End of the animation.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  animation->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(300000),
+                            ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   animation->setCurrentTime(CSSNumberish::FromDouble(300000));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ(AnimationTimeDelta::Max(),
             keyframe_effect->TimeToForwardsEffectChange());
   EXPECT_TIMEDELTA(AnimationTimeDelta::FromSecondsD(100),
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.cc b/third_party/blink/renderer/core/animation/scroll_timeline.cc
index 0dde5c2..95e272c 100644
--- a/third_party/blink/renderer/core/animation/scroll_timeline.cc
+++ b/third_party/blink/renderer/core/animation/scroll_timeline.cc
@@ -8,6 +8,9 @@
 
 #include "base/optional.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_csskeywordvalue_cssnumericvalue_scrolltimelineelementbasedoffset_string.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h"
 #include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h"
 #include "third_party/blink/renderer/core/animation/scroll_timeline_util.h"
 #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
@@ -294,6 +297,33 @@
   return true;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8CSSNumberish* ScrollTimeline::currentTime() {
+  // time returns either in milliseconds or a 0 to 100 value representing the
+  // progress of the timeline
+  auto current_time = timeline_state_snapshotted_.current_time;
+
+  // TODO(crbug.com/1140602): Support progress based animations
+  // We are currently abusing the intended use of the "auto" keyword. We are
+  // using it here as a signal to use progress based timeline instead of having
+  // a range based current time.
+  // We are doing this maintain backwards compatibility with existing tests.
+  if (time_range_) {
+    // not using progress based, return time as double
+    if (current_time) {
+      return MakeGarbageCollected<V8CSSNumberish>(
+          current_time->InMillisecondsF());
+    }
+    return nullptr;
+  } else {
+    if (current_time) {
+      return MakeGarbageCollected<V8CSSNumberish>(
+          CSSUnitValues::percent(current_time->InSecondsF()));
+    }
+    return nullptr;
+  }
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void ScrollTimeline::currentTime(CSSNumberish& currentTime) {
   // time returns either in milliseconds or a 0 to 100 value representing the
   // progress of the timeline
@@ -316,7 +346,17 @@
                       : CSSNumberish();
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8CSSNumberish* ScrollTimeline::duration() {
+  if (time_range_) {
+    return MakeGarbageCollected<V8CSSNumberish>(time_range_.value());
+  }
+  return MakeGarbageCollected<V8CSSNumberish>(
+      CSSUnitValues::percent(kScrollTimelineDuration));
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void ScrollTimeline::duration(CSSNumberish& duration) {
   if (time_range_) {
     duration = CSSNumberish::FromDouble(time_range_.value());
@@ -325,6 +365,7 @@
         CSSUnitValues::percent(kScrollTimelineDuration));
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 // https://drafts.csswg.org/scroll-animations-1/#current-time-algorithm
 ScrollTimeline::TimelineState ScrollTimeline::ComputeTimelineState() const {
@@ -459,6 +500,18 @@
   }
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+const HeapVector<Member<V8ScrollTimelineOffset>> ScrollTimeline::scrollOffsets()
+    const {
+  HeapVector<Member<V8ScrollTimelineOffset>> scroll_offsets;
+  for (auto& offset : scroll_offsets_) {
+    scroll_offsets.push_back(offset->ToV8ScrollTimelineOffset());
+    // 'auto' can only be the end offset.
+    DCHECK(!offset->IsDefaultValue() || scroll_offsets.size() == 2);
+  }
+  return scroll_offsets;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 const HeapVector<ScrollTimelineOffsetValue> ScrollTimeline::scrollOffsets()
     const {
   HeapVector<ScrollTimelineOffsetValue> scroll_offsets;
@@ -469,7 +522,23 @@
   }
   return scroll_offsets;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionDoubleOrScrollTimelineAutoKeyword* ScrollTimeline::timeRange() const {
+  // TODO(crbug.com/1140602): Support progress based animations
+  // We are currently abusing the intended use of the "auto" keyword. We are
+  // using it here as a signal to use progress based timeline instead of having
+  // a range based current time.
+  // We are doing this maintain backwards compatibility with existing tests.
+  if (time_range_) {
+    return MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(
+        time_range_.value());
+  }
+  return MakeGarbageCollected<V8UnionDoubleOrScrollTimelineAutoKeyword>(
+      V8ScrollTimelineAutoKeyword(V8ScrollTimelineAutoKeyword::Enum::kAuto));
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void ScrollTimeline::timeRange(DoubleOrScrollTimelineAutoKeyword& result) {
   // TODO(crbug.com/1140602): Support progress based animations
   // We are currently abusing the intended use of the "auto" keyword. We are
@@ -482,6 +551,7 @@
     result.SetScrollTimelineAutoKeyword("auto");
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void ScrollTimeline::GetCurrentAndMaxOffset(const LayoutBox* layout_box,
                                             double& current_offset,
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.h b/third_party/blink/renderer/core/animation/scroll_timeline.h
index 416cb045..081dcfb 100644
--- a/third_party/blink/renderer/core/animation/scroll_timeline.h
+++ b/third_party/blink/renderer/core/animation/scroll_timeline.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_H_
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/animation/animation_timeline.h"
 #include "third_party/blink/renderer/core/animation/scroll_timeline_offset.h"
 #include "third_party/blink/renderer/core/animation/timing.h"
@@ -16,6 +17,7 @@
 
 class DoubleOrScrollTimelineAutoKeyword;
 class ScrollTimelineOptions;
+class V8UnionDoubleOrScrollTimelineAutoKeyword;
 
 // Implements the ScrollTimeline concept from the Scroll-linked Animations spec.
 //
@@ -61,11 +63,21 @@
   // IDL API implementation.
   Element* scrollSource() const;
   String orientation();
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const HeapVector<Member<V8ScrollTimelineOffset>> scrollOffsets() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   const HeapVector<ScrollTimelineOffsetValue> scrollOffsets() const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* currentTime() override;
+  V8CSSNumberish* duration() override;
+  V8UnionDoubleOrScrollTimelineAutoKeyword* timeRange() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void currentTime(CSSNumberish&) override;
   void duration(CSSNumberish&) override;
   void timeRange(DoubleOrScrollTimelineAutoKeyword&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Returns the Node that should actually have the ScrollableArea (if one
   // exists). This can differ from |scrollSource| when |scroll_source_| is the
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc b/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc
index 6631be0..032c8733 100644
--- a/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc
+++ b/third_party/blink/renderer/core/animation/scroll_timeline_offset.cc
@@ -7,6 +7,7 @@
 #include "base/optional.h"
 #include "third_party/blink/renderer/bindings/core/v8/css_numeric_value_or_string_or_css_keyword_value_or_scroll_timeline_element_based_offset.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_element_based_offset.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_csskeywordvalue_cssnumericvalue_scrolltimelineelementbasedoffset_string.h"
 #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
 #include "third_party/blink/renderer/core/css/cssom/css_keyword_value.h"
 #include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h"
@@ -209,6 +210,19 @@
   }
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8ScrollTimelineOffset* ScrollTimelineOffset::ToV8ScrollTimelineOffset() const {
+  if (length_based_offset_) {
+    return MakeGarbageCollected<V8ScrollTimelineOffset>(
+        CSSNumericValue::FromCSSValue(*length_based_offset_.Get()));
+  } else if (element_based_offset_) {
+    return MakeGarbageCollected<V8ScrollTimelineOffset>(element_based_offset_);
+  }
+  // This is the default value (i.e., 'auto' value)
+  return MakeGarbageCollected<V8ScrollTimelineOffset>(
+      CSSKeywordValue::Create("auto"));
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 ScrollTimelineOffsetValue ScrollTimelineOffset::ToScrollTimelineOffsetValue()
     const {
   ScrollTimelineOffsetValue result;
@@ -224,6 +238,7 @@
 
   return result;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 bool ScrollTimelineOffset::operator==(const ScrollTimelineOffset& o) const {
   return DataEquivalent(length_based_offset_, o.length_based_offset_) &&
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_offset.h b/third_party/blink/renderer/core/animation/scroll_timeline_offset.h
index 067e7b1..f3516b5b 100644
--- a/third_party/blink/renderer/core/animation/scroll_timeline_offset.h
+++ b/third_party/blink/renderer/core/animation/scroll_timeline_offset.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_OFFSET_H_
 
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_element_based_offset.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/css/css_style_sheet.h"
 #include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
 #include "third_party/blink/renderer/core/scroll/scroll_types.h"
@@ -52,7 +53,11 @@
                                        double max_offset,
                                        double default_offset);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8ScrollTimelineOffset* ToV8ScrollTimelineOffset() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScrollTimelineOffsetValue ToScrollTimelineOffsetValue() const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool IsDefaultValue() const {
     return !length_based_offset_ && !element_based_offset_;
   }
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_util.cc b/third_party/blink/renderer/core/animation/scroll_timeline_util.cc
index f6719a1..dc30ad6 100644
--- a/third_party/blink/renderer/core/animation/scroll_timeline_util.cc
+++ b/third_party/blink/renderer/core/animation/scroll_timeline_util.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/animation/scroll_timeline_util.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h"
 #include "third_party/blink/renderer/core/animation/animation_timeline.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
 #include "third_party/blink/renderer/core/dom/node.h"
@@ -25,10 +26,15 @@
   base::Optional<CompositorElementId> element_id =
       GetCompositorScrollElementId(scroll_source);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* time_range = scroll_timeline->timeRange();
+  DCHECK(time_range);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DoubleOrScrollTimelineAutoKeyword time_range;
   scroll_timeline->timeRange(time_range);
   // TODO(smcgruer): Handle 'auto' time range value.
   DCHECK(time_range.IsDouble());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   LayoutBox* box =
       scroll_timeline->IsActive() ? scroll_source->GetLayoutBox() : nullptr;
@@ -38,7 +44,12 @@
 
   return CompositorScrollTimeline::Create(
       element_id, orientation, scroll_timeline->GetResolvedScrollOffsets(),
-      time_range.GetAsDouble());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      time_range->GetAsDouble()
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      time_range.GetAsDouble()
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  );
 }
 
 base::Optional<CompositorElementId> GetCompositorScrollElementId(
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc b/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc
index 023098e..69e4136c 100644
--- a/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc
+++ b/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc
@@ -140,68 +140,70 @@
                                        WritingMode::kVerticalRl};
   Vector<TextDirection> directions = {TextDirection::kLtr, TextDirection::kRtl};
 
-  ComputedStyle* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style =
+      GetDocument().GetStyleResolver().CreateComputedStyle();
   for (const WritingMode& writing_mode : writing_modes) {
     for (const TextDirection& direction : directions) {
       style->SetWritingMode(writing_mode);
       style->SetDirection(direction);
-      EXPECT_EQ(ConvertOrientation(ScrollTimeline::Vertical, style),
+      EXPECT_EQ(ConvertOrientation(ScrollTimeline::Vertical, style.get()),
                 CompositorScrollTimeline::ScrollDown);
-      EXPECT_EQ(ConvertOrientation(ScrollTimeline::Horizontal, style),
+      EXPECT_EQ(ConvertOrientation(ScrollTimeline::Horizontal, style.get()),
                 CompositorScrollTimeline::ScrollRight);
     }
   }
 }
 
 TEST_F(ScrollTimelineUtilTest, ConvertOrientationLogical) {
-  ComputedStyle* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style =
+      GetDocument().GetStyleResolver().CreateComputedStyle();
 
   // horizontal-tb, ltr
   style->SetWritingMode(WritingMode::kHorizontalTb);
   style->SetDirection(TextDirection::kLtr);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
             CompositorScrollTimeline::ScrollDown);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
             CompositorScrollTimeline::ScrollRight);
 
   // vertical-lr, ltr
   style->SetWritingMode(WritingMode::kVerticalLr);
   style->SetDirection(TextDirection::kLtr);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
             CompositorScrollTimeline::ScrollRight);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
             CompositorScrollTimeline::ScrollDown);
 
   // vertical-rl, ltr
   style->SetWritingMode(WritingMode::kVerticalRl);
   style->SetDirection(TextDirection::kLtr);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
             CompositorScrollTimeline::ScrollLeft);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
             CompositorScrollTimeline::ScrollDown);
 
   // horizontal-tb, rtl
   style->SetWritingMode(WritingMode::kHorizontalTb);
   style->SetDirection(TextDirection::kRtl);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
             CompositorScrollTimeline::ScrollDown);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
             CompositorScrollTimeline::ScrollLeft);
 
   // vertical-lr, rtl
   style->SetWritingMode(WritingMode::kVerticalLr);
   style->SetDirection(TextDirection::kRtl);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
             CompositorScrollTimeline::ScrollRight);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
             CompositorScrollTimeline::ScrollUp);
 
   // vertical-rl, rtl
   style->SetWritingMode(WritingMode::kVerticalRl);
   style->SetDirection(TextDirection::kRtl);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
             CompositorScrollTimeline::ScrollLeft);
-  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style),
+  EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
             CompositorScrollTimeline::ScrollUp);
 }
 
diff --git a/third_party/blink/renderer/core/animation/timing_input.cc b/third_party/blink/renderer/core/animation/timing_input.cc
index bb9c972..67f61794 100644
--- a/third_party/blink/renderer/core/animation/timing_input.cc
+++ b/third_party/blink/renderer/core/animation/timing_input.cc
@@ -9,6 +9,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_effect_timing.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeanimationoptions_unrestricteddouble.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h"
 #include "third_party/blink/renderer/core/animation/animation_effect.h"
 #include "third_party/blink/renderer/core/animation/animation_input_helpers.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -57,6 +59,37 @@
 
 }  // namespace
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+Timing TimingInput::Convert(
+    const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options,
+    Document* document,
+    ExceptionState& exception_state) {
+  if (!options) {
+    return Timing();
+  }
+
+  switch (options->GetContentType()) {
+    case V8UnionKeyframeEffectOptionsOrUnrestrictedDouble::ContentType::
+        kKeyframeEffectOptions:
+      return ConvertEffectTiming(options->GetAsKeyframeEffectOptions(),
+                                 document, exception_state);
+    case V8UnionKeyframeEffectOptionsOrUnrestrictedDouble::ContentType::
+        kUnrestrictedDouble: {
+      // https://drafts.csswg.org/web-animations-1/#dom-keyframeeffect-keyframeeffect
+      // If options is a double,
+      //   Let timing input be a new EffectTiming object with all members set to
+      //   their default values and duration set to options.
+      EffectTiming* timing_input = EffectTiming::Create();
+      timing_input->setDuration(
+          UnrestrictedDoubleOrString::FromUnrestrictedDouble(
+              options->GetAsUnrestrictedDouble()));
+      return ConvertEffectTiming(timing_input, document, exception_state);
+    }
+  }
+  NOTREACHED();
+  return Timing();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 Timing TimingInput::Convert(
     const UnrestrictedDoubleOrKeyframeEffectOptions& options,
     Document* document,
@@ -81,7 +114,39 @@
       options.GetAsUnrestrictedDouble()));
   return ConvertEffectTiming(timing_input, document, exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+Timing TimingInput::Convert(
+    const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options,
+    Document* document,
+    ExceptionState& exception_state) {
+  if (!options) {
+    return Timing();
+  }
+
+  switch (options->GetContentType()) {
+    case V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble::ContentType::
+        kKeyframeAnimationOptions:
+      return ConvertEffectTiming(options->GetAsKeyframeAnimationOptions(),
+                                 document, exception_state);
+    case V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble::ContentType::
+        kUnrestrictedDouble: {
+      // https://drafts.csswg.org/web-animations-1/#dom-keyframeeffect-keyframeeffect
+      // If options is a double,
+      //   Let timing input be a new EffectTiming object with all members set to
+      //   their default values and duration set to options.
+      EffectTiming* timing_input = EffectTiming::Create();
+      timing_input->setDuration(
+          UnrestrictedDoubleOrString::FromUnrestrictedDouble(
+              options->GetAsUnrestrictedDouble()));
+      return ConvertEffectTiming(timing_input, document, exception_state);
+    }
+  }
+  NOTREACHED();
+  return Timing();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 Timing TimingInput::Convert(
     const UnrestrictedDoubleOrKeyframeAnimationOptions& options,
     Document* document,
@@ -105,6 +170,7 @@
       options.GetAsUnrestrictedDouble()));
   return ConvertEffectTiming(timing_input, document, exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 template <class InputTiming>
 bool TimingInput::Update(Timing& timing,
diff --git a/third_party/blink/renderer/core/animation/timing_input.h b/third_party/blink/renderer/core/animation/timing_input.h
index cabc141..6a30531 100644
--- a/third_party/blink/renderer/core/animation/timing_input.h
+++ b/third_party/blink/renderer/core/animation/timing_input.h
@@ -15,6 +15,8 @@
 class ExceptionState;
 class UnrestrictedDoubleOrKeyframeAnimationOptions;
 class UnrestrictedDoubleOrKeyframeEffectOptions;
+class V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble;
+class V8UnionKeyframeEffectOptionsOrUnrestrictedDouble;
 
 class CORE_EXPORT TimingInput {
   STATIC_ONLY(TimingInput);
@@ -24,17 +26,31 @@
   // the 'options' parameter into timing information.
   //
   // https://drafts.csswg.org/web-animations-1/#dom-keyframeeffect-keyframeeffect
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static Timing Convert(
+      const V8UnionKeyframeEffectOptionsOrUnrestrictedDouble* options,
+      Document* document,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static Timing Convert(const UnrestrictedDoubleOrKeyframeEffectOptions&,
                         Document*,
                         ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Implements step 2 of the Animatable::animate() method, converting the
   // 'options' parameter into timing information.
   //
   // https://drafts.csswg.org/web-animations-1/#dom-animatable-animate
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static Timing Convert(
+      const V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble* options,
+      Document* document,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static Timing Convert(const UnrestrictedDoubleOrKeyframeAnimationOptions&,
                         Document*,
                         ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Implements the procedure to 'update the timing properties of an animation
   // effect'.
diff --git a/third_party/blink/renderer/core/animation/timing_input_test.cc b/third_party/blink/renderer/core/animation/timing_input_test.cc
index c1a53716..4a7b2bba 100644
--- a/third_party/blink/renderer/core/animation/timing_input_test.cc
+++ b/third_party/blink/renderer/core/animation/timing_input_test.cc
@@ -11,6 +11,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_animation_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeanimationoptions_unrestricteddouble.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_keyframeeffectoptions_unrestricteddouble.h"
 #include "third_party/blink/renderer/core/animation/animation_test_helpers.h"
 #include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
 #include "v8/include/v8.h"
@@ -62,9 +64,15 @@
       return Timing();
     }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* timing_input =
+        MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>(
+            timing_input_dictionary);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     UnrestrictedDoubleOrKeyframeEffectOptions timing_input =
         UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions(
             timing_input_dictionary);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     result = TimingInput::Convert(timing_input, GetDocument(), exception_state);
     if (exception_state.HadException())
       return Timing();
@@ -75,9 +83,15 @@
     if (exception_state.HadException())
       return Timing();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* timing_input = MakeGarbageCollected<
+        V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble>(
+        timing_input_dictionary);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     UnrestrictedDoubleOrKeyframeAnimationOptions timing_input =
         UnrestrictedDoubleOrKeyframeAnimationOptions::
             FromKeyframeAnimationOptions(timing_input_dictionary);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     result = TimingInput::Convert(timing_input, GetDocument(), exception_state);
     if (exception_state.HadException())
       return Timing();
@@ -106,9 +120,15 @@
     if (exception_state.HadException())
       return Timing();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* timing_input =
+        MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>(
+            timing_input_dictionary);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     UnrestrictedDoubleOrKeyframeEffectOptions timing_input =
         UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions(
             timing_input_dictionary);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     result = TimingInput::Convert(timing_input, GetDocument(), exception_state);
     if (exception_state.HadException())
       return Timing();
@@ -119,9 +139,15 @@
     if (exception_state.HadException())
       return Timing();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* timing_input = MakeGarbageCollected<
+        V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble>(
+        timing_input_dictionary);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     UnrestrictedDoubleOrKeyframeAnimationOptions timing_input =
         UnrestrictedDoubleOrKeyframeAnimationOptions::
             FromKeyframeAnimationOptions(timing_input_dictionary);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     result = TimingInput::Convert(timing_input, GetDocument(), exception_state);
     if (exception_state.HadException())
       return Timing();
@@ -453,9 +479,15 @@
 TEST_F(AnimationTimingInputTest, TimingInputEmpty) {
   DummyExceptionStateForTesting exception_state;
   Timing control_timing;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* timing_input =
+      MakeGarbageCollected<V8UnionKeyframeEffectOptionsOrUnrestrictedDouble>(
+          KeyframeEffectOptions::Create());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   UnrestrictedDoubleOrKeyframeEffectOptions timing_input =
       UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions(
           KeyframeEffectOptions::Create());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Timing updated_timing =
       TimingInput::Convert(timing_input, nullptr, exception_state);
   EXPECT_FALSE(exception_state.HadException());
@@ -472,9 +504,15 @@
 TEST_F(AnimationTimingInputTest, TimingInputEmptyKeyframeAnimationOptions) {
   DummyExceptionStateForTesting exception_state;
   Timing control_timing;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* input_timing =
+      MakeGarbageCollected<V8UnionKeyframeAnimationOptionsOrUnrestrictedDouble>(
+          KeyframeAnimationOptions::Create());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   UnrestrictedDoubleOrKeyframeAnimationOptions input_timing =
       UnrestrictedDoubleOrKeyframeAnimationOptions::
           FromKeyframeAnimationOptions(KeyframeAnimationOptions::Create());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Timing updated_timing =
       TimingInput::Convert(input_timing, nullptr, exception_state);
   EXPECT_FALSE(exception_state.HadException());
diff --git a/third_party/blink/renderer/core/css/css_math_expression_node_test.cc b/third_party/blink/renderer/core/css/css_math_expression_node_test.cc
index 1ed6e1d..5049bac 100644
--- a/third_party/blink/renderer/core/css/css_math_expression_node_test.cc
+++ b/third_party/blink/renderer/core/css/css_math_expression_node_test.cc
@@ -89,9 +89,10 @@
 }
 
 TEST(CSSCalculationValue, AccumulatePixelsAndPercent) {
-  ComputedStyle* style = ComputedStyle::CreateInitialStyleSingleton();
+  scoped_refptr<ComputedStyle> style =
+      ComputedStyle::CreateInitialStyleSingleton();
   style->SetEffectiveZoom(5);
-  CSSToLengthConversionData conversion_data(style, style, nullptr,
+  CSSToLengthConversionData conversion_data(style.get(), style.get(), nullptr,
                                             style->EffectiveZoom());
 
   TestAccumulatePixelsAndPercent(
diff --git a/third_party/blink/renderer/core/css/css_paint_value_test.cc b/third_party/blink/renderer/core/css/css_paint_value_test.cc
index 1e8d03e..1de40b3 100644
--- a/third_party/blink/renderer/core/css/css_paint_value_test.cc
+++ b/third_party/blink/renderer/core/css/css_paint_value_test.cc
@@ -133,7 +133,7 @@
 
   SetBodyInnerHTML(R"HTML(<div id="target"></div>)HTML");
   LayoutObject* target = GetLayoutObjectByElementId("target");
-  auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
   auto* ident = MakeGarbageCollected<CSSCustomIdentValue>("testpainter");
   CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident, true);
   StyleGeneratedImage* style_image =
diff --git a/third_party/blink/renderer/core/css/cssom/css_color_value.cc b/third_party/blink/renderer/core/css/cssom/css_color_value.cc
index 7ea10a3..5152b2db 100644
--- a/third_party/blink/renderer/core/css/cssom/css_color_value.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_color_value.cc
@@ -23,6 +23,19 @@
   return cssvalue::CSSColor::Create(ToColor().Rgb());
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CSSNumericValue* CSSColorValue::ToNumberOrPercentage(
+    const V8CSSNumberish* input) {
+  CSSNumericValue* value = CSSNumericValue::FromPercentish(input);
+  DCHECK(value);
+  if (!CSSOMTypes::IsCSSStyleValueNumber(*value) &&
+      !CSSOMTypes::IsCSSStyleValuePercentage(*value)) {
+    return nullptr;
+  }
+
+  return value;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CSSNumericValue* CSSColorValue::ToNumberOrPercentage(
     const CSSNumberish& input) {
   CSSNumericValue* value = CSSNumericValue::FromPercentish(input);
@@ -34,7 +47,18 @@
 
   return value;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CSSNumericValue* CSSColorValue::ToPercentage(const V8CSSNumberish* input) {
+  CSSNumericValue* value = CSSNumericValue::FromPercentish(input);
+  DCHECK(value);
+  if (!CSSOMTypes::IsCSSStyleValuePercentage(*value))
+    return nullptr;
+
+  return value;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CSSNumericValue* CSSColorValue::ToPercentage(const CSSNumberish& input) {
   CSSNumericValue* value = CSSNumericValue::FromPercentish(input);
   DCHECK(value);
@@ -43,6 +67,7 @@
 
   return value;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 float CSSColorValue::ComponentToColorInput(CSSNumericValue* input) {
   if (CSSOMTypes::IsCSSStyleValuePercentage(*input))
diff --git a/third_party/blink/renderer/core/css/cssom/css_color_value.h b/third_party/blink/renderer/core/css/cssom/css_color_value.h
index 2b7c55c8..9256a09 100644
--- a/third_party/blink/renderer/core/css/cssom/css_color_value.h
+++ b/third_party/blink/renderer/core/css/cssom/css_color_value.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_CSS_COLOR_VALUE_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_CSS_COLOR_VALUE_H_
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h"
 #include "third_party/blink/renderer/core/css/cssom/css_style_value.h"
@@ -31,8 +32,13 @@
   virtual Color ToColor() const = 0;
 
  protected:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSNumericValue* ToNumberOrPercentage(const V8CSSNumberish*);
+  static CSSNumericValue* ToPercentage(const V8CSSNumberish*);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSNumericValue* ToNumberOrPercentage(const CSSNumberish&);
   static CSSNumericValue* ToPercentage(const CSSNumberish&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static float ComponentToColorInput(CSSNumericValue*);
 };
 
diff --git a/third_party/blink/renderer/core/css/cssom/css_hsl.cc b/third_party/blink/renderer/core/css/cssom/css_hsl.cc
index e2af24b..759e4c3d 100644
--- a/third_party/blink/renderer/core/css/cssom/css_hsl.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_hsl.cc
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 #include "third_party/blink/renderer/core/css/cssom/css_hsl.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/css/cssom/css_unit_value.h"
 #include "third_party/blink/renderer/core/css/cssom/cssom_types.h"
 #include "third_party/blink/renderer/platform/graphics/color.h"
@@ -28,9 +30,15 @@
     : h_(h), s_(s), l_(l), alpha_(alpha) {}
 
 CSSHSL* CSSHSL::Create(CSSNumericValue* hue,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                       const V8CSSNumberish* saturation,
+                       const V8CSSNumberish* lightness,
+                       const V8CSSNumberish* alpha,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                        const CSSNumberish& saturation,
                        const CSSNumberish& lightness,
                        const CSSNumberish& alpha,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                        ExceptionState& exception_state) {
   if (!CSSOMTypes::IsCSSStyleValueAngle(*hue)) {
     exception_state.ThrowTypeError("Hue must be a CSS angle type.");
@@ -51,14 +59,22 @@
   return MakeGarbageCollected<CSSHSL>(hue, s, l, a);
 }
 
-Color CSSHSL::ToColor() const {
-  // MakeRGBAFromHSLA expects hue in the range [0, 6)
-  return MakeRGBAFromHSLA(
-      h_->to(CSSPrimitiveValue::UnitType::kDegrees)->value() / 60,
-      ComponentToColorInput(s_), ComponentToColorInput(l_),
-      ComponentToColorInput(alpha_));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8CSSNumberish* CSSHSL::s() const {
+  return MakeGarbageCollected<V8CSSNumberish>(s_);
 }
 
+V8CSSNumberish* CSSHSL::l() const {
+  return MakeGarbageCollected<V8CSSNumberish>(l_);
+}
+
+V8CSSNumberish* CSSHSL::alpha() const {
+  return MakeGarbageCollected<V8CSSNumberish>(alpha_);
+}
+
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void CSSHSL::setH(CSSNumericValue* hue, ExceptionState& exception_state) {
   if (CSSOMTypes::IsCSSStyleValueAngle(*hue))
     h_ = hue;
@@ -66,28 +82,51 @@
     exception_state.ThrowTypeError("Hue must be a CSS angle type.");
 }
 
-void CSSHSL::setS(const CSSNumberish& saturation,
-                  ExceptionState& exception_state) {
+void CSSHSL::setS(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8CSSNumberish* saturation,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const CSSNumberish& saturation,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   if (auto* value = ToPercentage(saturation))
     s_ = value;
   else
     exception_state.ThrowTypeError("Saturation must be a percentage.");
 }
 
-void CSSHSL::setL(const CSSNumberish& lightness,
-                  ExceptionState& exception_state) {
+void CSSHSL::setL(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8CSSNumberish* lightness,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const CSSNumberish& lightness,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   if (auto* value = ToPercentage(lightness))
     l_ = value;
   else
     exception_state.ThrowTypeError("Lightness must be a percentage.");
 }
 
-void CSSHSL::setAlpha(const CSSNumberish& alpha,
-                      ExceptionState& exception_state) {
+void CSSHSL::setAlpha(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8CSSNumberish* alpha,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const CSSNumberish& alpha,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   if (auto* value = ToPercentage(alpha))
     alpha_ = value;
   else
     exception_state.ThrowTypeError("Alpha must be a percentage.");
 }
 
+Color CSSHSL::ToColor() const {
+  // MakeRGBAFromHSLA expects hue in the range [0, 6)
+  return MakeRGBAFromHSLA(
+      h_->to(CSSPrimitiveValue::UnitType::kDegrees)->value() / 60,
+      ComponentToColorInput(s_), ComponentToColorInput(l_),
+      ComponentToColorInput(alpha_));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/css_hsl.h b/third_party/blink/renderer/core/css/cssom/css_hsl.h
index e7391d4..22f9fd4 100644
--- a/third_party/blink/renderer/core/css/cssom/css_hsl.h
+++ b/third_party/blink/renderer/core/css/cssom/css_hsl.h
@@ -19,11 +19,19 @@
 
  public:
   // Constructor defined in the IDL.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSHSL* Create(CSSNumericValue* hue,
+                        const V8CSSNumberish* saturation,
+                        const V8CSSNumberish* lightness,
+                        const V8CSSNumberish* alpha,
+                        ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSHSL* Create(CSSNumericValue* hue,
                         const CSSNumberish& saturation,
                         const CSSNumberish& lightness,
                         const CSSNumberish& alpha,
                         ExceptionState& exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Internal constructor used by blink.
   explicit CSSHSL(const Color&);
@@ -33,6 +41,16 @@
          CSSNumericValue*);
 
   // Getters and setters from the IDL
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Member<CSSNumericValue> h() const { return h_; }
+  V8CSSNumberish* s() const;
+  V8CSSNumberish* l() const;
+  V8CSSNumberish* alpha() const;
+  void setH(CSSNumericValue* h, ExceptionState& exception_state);
+  void setS(const V8CSSNumberish* s, ExceptionState& exception_state);
+  void setL(const V8CSSNumberish* l, ExceptionState& exception_state);
+  void setAlpha(const V8CSSNumberish* alpha, ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Member<CSSNumericValue> h() { return h_; }
   void s(CSSNumberish& g) { g.SetCSSNumericValue(s_); }
   void l(CSSNumberish& b) { b.SetCSSNumericValue(l_); }
@@ -41,6 +59,7 @@
   void setS(const CSSNumberish&, ExceptionState&);
   void setL(const CSSNumberish&, ExceptionState&);
   void setAlpha(const CSSNumberish&, ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor* visitor) const override {
     visitor->Trace(h_);
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_invert.cc b/third_party/blink/renderer/core/css/cssom/css_math_invert.cc
index e97e9d8..5d35259 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_invert.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_math_invert.cc
@@ -4,12 +4,19 @@
 
 #include "third_party/blink/renderer/core/css/cssom/css_math_invert.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/css/css_math_expression_node.h"
 #include "third_party/blink/renderer/core/css/cssom/css_numeric_sum_value.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
 namespace blink {
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8CSSNumberish* CSSMathInvert::value() {
+  return MakeGarbageCollected<V8CSSNumberish>(value_);
+}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 base::Optional<CSSNumericSumValue> CSSMathInvert::SumValue() const {
   auto sum = value_->SumValue();
   if (!sum || sum->terms.size() != 1)
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_invert.h b/third_party/blink/renderer/core/css/cssom/css_math_invert.h
index 64dd1e61..1895c2d 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_invert.h
+++ b/third_party/blink/renderer/core/css/cssom/css_math_invert.h
@@ -17,9 +17,15 @@
 
  public:
   // The constructor defined in the IDL.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSMathInvert* Create(V8CSSNumberish* arg) {
+    return Create(CSSNumericValue::FromNumberish(arg));
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSMathInvert* Create(const CSSNumberish& arg) {
     return Create(CSSNumericValue::FromNumberish(arg));
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // Blink-internal constructor
   static CSSMathInvert* Create(CSSNumericValue* value) {
     return MakeGarbageCollected<CSSMathInvert>(
@@ -33,7 +39,11 @@
 
   String getOperator() const final { return "invert"; }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* value();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void value(CSSNumberish& value) { value.SetCSSNumericValue(value_); }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Blink-internal methods
   const CSSNumericValue& Value() const { return *value_; }
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_max.cc b/third_party/blink/renderer/core/css/cssom/css_math_max.cc
index 328225e..65b0bd8 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_max.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_math_max.cc
@@ -10,6 +10,24 @@
 
 namespace blink {
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CSSMathMax* CSSMathMax::Create(const HeapVector<Member<V8CSSNumberish>>& args,
+                               ExceptionState& exception_state) {
+  if (args.IsEmpty()) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+                                      "Arguments can't be empty");
+    return nullptr;
+  }
+
+  CSSMathMax* result = Create(CSSNumberishesToNumericValues(args));
+  if (!result) {
+    exception_state.ThrowTypeError("Incompatible types");
+    return nullptr;
+  }
+
+  return result;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CSSMathMax* CSSMathMax::Create(const HeapVector<CSSNumberish>& args,
                                ExceptionState& exception_state) {
   if (args.IsEmpty()) {
@@ -26,6 +44,7 @@
 
   return result;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 CSSMathMax* CSSMathMax::Create(CSSNumericValueVector values) {
   bool error = false;
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_max.h b/third_party/blink/renderer/core/css/cssom/css_math_max.h
index b663518..f47258e 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_max.h
+++ b/third_party/blink/renderer/core/css/cssom/css_math_max.h
@@ -16,8 +16,13 @@
 
  public:
   // The constructor defined in the IDL.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSMathMax* Create(const HeapVector<Member<V8CSSNumberish>>& args,
+                            ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSMathMax* Create(const HeapVector<CSSNumberish>& args,
                             ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // Blink-internal constructor.
   static CSSMathMax* Create(CSSNumericValueVector);
 
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_min.cc b/third_party/blink/renderer/core/css/cssom/css_math_min.cc
index cff5f90..1114795d2 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_min.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_math_min.cc
@@ -10,6 +10,24 @@
 
 namespace blink {
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CSSMathMin* CSSMathMin::Create(const HeapVector<Member<V8CSSNumberish>>& args,
+                               ExceptionState& exception_state) {
+  if (args.IsEmpty()) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+                                      "Arguments can't be empty");
+    return nullptr;
+  }
+
+  CSSMathMin* result = Create(CSSNumberishesToNumericValues(args));
+  if (!result) {
+    exception_state.ThrowTypeError("Incompatible types");
+    return nullptr;
+  }
+
+  return result;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CSSMathMin* CSSMathMin::Create(const HeapVector<CSSNumberish>& args,
                                ExceptionState& exception_state) {
   if (args.IsEmpty()) {
@@ -26,6 +44,7 @@
 
   return result;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 CSSMathMin* CSSMathMin::Create(CSSNumericValueVector values) {
   bool error = false;
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_min.h b/third_party/blink/renderer/core/css/cssom/css_math_min.h
index 6a57b3ff..2489918 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_min.h
+++ b/third_party/blink/renderer/core/css/cssom/css_math_min.h
@@ -18,8 +18,13 @@
 
  public:
   // The constructor defined in the IDL.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSMathMin* Create(const HeapVector<Member<V8CSSNumberish>>& args,
+                            ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSMathMin* Create(const HeapVector<CSSNumberish>& args,
                             ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // Blink-internal constructor.
   static CSSMathMin* Create(CSSNumericValueVector);
 
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_negate.cc b/third_party/blink/renderer/core/css/cssom/css_math_negate.cc
index 7d2e41b..9d06fcc 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_negate.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_math_negate.cc
@@ -4,12 +4,19 @@
 
 #include "third_party/blink/renderer/core/css/cssom/css_math_negate.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/css/css_math_expression_node.h"
 #include "third_party/blink/renderer/core/css/cssom/css_numeric_sum_value.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
 namespace blink {
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8CSSNumberish* CSSMathNegate::value() {
+  return MakeGarbageCollected<V8CSSNumberish>(value_);
+}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 base::Optional<CSSNumericSumValue> CSSMathNegate::SumValue() const {
   auto maybe_sum = value_->SumValue();
   if (!maybe_sum)
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_negate.h b/third_party/blink/renderer/core/css/cssom/css_math_negate.h
index cb695d6..064ae16 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_negate.h
+++ b/third_party/blink/renderer/core/css/cssom/css_math_negate.h
@@ -16,9 +16,15 @@
 
  public:
   // The constructor defined in the IDL.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSMathNegate* Create(V8CSSNumberish* arg) {
+    return Create(CSSNumericValue::FromNumberish(arg));
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSMathNegate* Create(const CSSNumberish& arg) {
     return Create(CSSNumericValue::FromNumberish(arg));
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // Blink-internal constructor
   static CSSMathNegate* Create(CSSNumericValue* value) {
     return MakeGarbageCollected<CSSMathNegate>(value, value->Type());
@@ -31,7 +37,11 @@
 
   String getOperator() const final { return "negate"; }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* value();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void value(CSSNumberish& value) { value.SetCSSNumericValue(value_); }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Blink-internal methods
   const CSSNumericValue& Value() const { return *value_; }
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_product.cc b/third_party/blink/renderer/core/css/cssom/css_math_product.cc
index 96db73a..b9370fb 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_product.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_math_product.cc
@@ -31,6 +31,25 @@
 
 }  // namespace
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CSSMathProduct* CSSMathProduct::Create(
+    const HeapVector<Member<V8CSSNumberish>>& args,
+    ExceptionState& exception_state) {
+  if (args.IsEmpty()) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+                                      "Arguments can't be empty");
+    return nullptr;
+  }
+
+  CSSMathProduct* result = Create(CSSNumberishesToNumericValues(args));
+  if (!result) {
+    exception_state.ThrowTypeError("Incompatible types");
+    return nullptr;
+  }
+
+  return result;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CSSMathProduct* CSSMathProduct::Create(const HeapVector<CSSNumberish>& args,
                                        ExceptionState& exception_state) {
   if (args.IsEmpty()) {
@@ -47,6 +66,7 @@
 
   return result;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 CSSMathProduct* CSSMathProduct::Create(CSSNumericValueVector values) {
   bool error = false;
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_product.h b/third_party/blink/renderer/core/css/cssom/css_math_product.h
index efff524..104602d 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_product.h
+++ b/third_party/blink/renderer/core/css/cssom/css_math_product.h
@@ -16,8 +16,13 @@
 
  public:
   // The constructor defined in the IDL.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSMathProduct* Create(const HeapVector<Member<V8CSSNumberish>>& args,
+                                ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSMathProduct* Create(const HeapVector<CSSNumberish>& args,
                                 ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // Blink internal-constructor.
   static CSSMathProduct* Create(CSSNumericValueVector);
 
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_sum.cc b/third_party/blink/renderer/core/css/cssom/css_math_sum.cc
index 08187128..a2296ebd 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_sum.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_math_sum.cc
@@ -49,6 +49,25 @@
 
 }  // namespace
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CSSMathSum* CSSMathSum::Create(const HeapVector<Member<V8CSSNumberish>>& args,
+                               ExceptionState& exception_state) {
+  if (args.IsEmpty()) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+                                      "Arguments can't be empty");
+    return nullptr;
+  }
+
+  CSSMathSum* result =
+      Create(CSSNumberishesToNumericValues(args), exception_state);
+  if (!result) {
+    exception_state.ThrowTypeError("Incompatible types");
+    return nullptr;
+  }
+
+  return result;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CSSMathSum* CSSMathSum::Create(const HeapVector<CSSNumberish>& args,
                                ExceptionState& exception_state) {
   if (args.IsEmpty()) {
@@ -59,6 +78,7 @@
 
   return Create(CSSNumberishesToNumericValues(args), exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 CSSMathSum* CSSMathSum::Create(CSSNumericValueVector values,
                                ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/core/css/cssom/css_math_sum.h b/third_party/blink/renderer/core/css/cssom/css_math_sum.h
index 81e17354..15819f6 100644
--- a/third_party/blink/renderer/core/css/cssom/css_math_sum.h
+++ b/third_party/blink/renderer/core/css/cssom/css_math_sum.h
@@ -16,8 +16,13 @@
 
  public:
   // The constructor defined in the IDL.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSMathSum* Create(const HeapVector<Member<V8CSSNumberish>>& args,
+                            ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSMathSum* Create(const HeapVector<CSSNumberish>& args,
                             ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // Blink-internal constructor.
   static CSSMathSum* Create(CSSNumericValueVector,
                             ExceptionState& = ASSERT_NO_EXCEPTION);
diff --git a/third_party/blink/renderer/core/css/cssom/css_numeric_array.h b/third_party/blink/renderer/core/css/cssom/css_numeric_array.h
index 1cc19526..e4f2b9c9 100644
--- a/third_party/blink/renderer/core/css/cssom/css_numeric_array.h
+++ b/third_party/blink/renderer/core/css/cssom/css_numeric_array.h
@@ -14,12 +14,6 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static CSSNumericArray* FromNumberishes(
-      const HeapVector<CSSNumberish>& values) {
-    return MakeGarbageCollected<CSSNumericArray>(
-        CSSNumberishesToNumericValues(values));
-  }
-
   explicit CSSNumericArray(CSSNumericValueVector values)
       : values_(std::move(values)) {}
   CSSNumericArray(const CSSNumericArray&) = delete;
diff --git a/third_party/blink/renderer/core/css/cssom/css_numeric_value.cc b/third_party/blink/renderer/core/css/cssom/css_numeric_value.cc
index 440eb4bf..f06e4f93 100644
--- a/third_party/blink/renderer/core/css/cssom/css_numeric_value.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_numeric_value.cc
@@ -7,6 +7,7 @@
 #include <numeric>
 
 #include "third_party/blink/renderer/bindings/core/v8/v8_css_numeric_type.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/css/css_math_expression_node.h"
 #include "third_party/blink/renderer/core/css/css_math_function_value.h"
 #include "third_party/blink/renderer/core/css/css_primitive_value.h"
@@ -227,6 +228,7 @@
   return CSSPrimitiveValue::StringToUnitType(name);
 }
 
+// static
 CSSNumericValue* CSSNumericValue::parse(const String& css_text,
                                         ExceptionState& exception_state) {
   CSSTokenizer tokenizer(css_text);
@@ -270,6 +272,7 @@
   return nullptr;
 }
 
+// static
 CSSNumericValue* CSSNumericValue::FromCSSValue(const CSSPrimitiveValue& value) {
   if (value.IsCalculated()) {
     return CalcToNumericValue(
@@ -278,7 +281,17 @@
   return CSSUnitValue::FromCSSValue(To<CSSNumericLiteralValue>(value));
 }
 
-/* static */
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// static
+CSSNumericValue* CSSNumericValue::FromNumberish(const V8CSSNumberish* value) {
+  if (value->IsDouble()) {
+    return CSSUnitValue::Create(value->GetAsDouble(),
+                                CSSPrimitiveValue::UnitType::kNumber);
+  }
+  return value->GetAsCSSNumericValue();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// static
 CSSNumericValue* CSSNumericValue::FromNumberish(const CSSNumberish& value) {
   if (value.IsDouble()) {
     return CSSUnitValue::Create(value.GetAsDouble(),
@@ -286,8 +299,19 @@
   }
   return value.GetAsCSSNumericValue();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
-/* static */
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// static
+CSSNumericValue* CSSNumericValue::FromPercentish(const V8CSSNumberish* value) {
+  if (value->IsDouble()) {
+    return CSSUnitValue::Create(value->GetAsDouble() * 100,
+                                CSSPrimitiveValue::UnitType::kPercentage);
+  }
+  return value->GetAsCSSNumericValue();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// static
 CSSNumericValue* CSSNumericValue::FromPercentish(const CSSNumberish& value) {
   if (value.IsDouble()) {
     return CSSUnitValue::Create(value.GetAsDouble() * 100,
@@ -295,6 +319,7 @@
   }
   return value.GetAsCSSNumericValue();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 CSSUnitValue* CSSNumericValue::to(const String& unit_string,
                                   ExceptionState& exception_state) {
@@ -423,7 +448,11 @@
 }
 
 CSSNumericValue* CSSNumericValue::add(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8CSSNumberish>>& numberishes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const HeapVector<CSSNumberish>& numberishes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   auto values = CSSNumberishesToNumericValues(numberishes);
   PrependValueForArithmetic<kSumType>(values, this);
@@ -436,7 +465,11 @@
 }
 
 CSSNumericValue* CSSNumericValue::sub(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8CSSNumberish>>& numberishes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const HeapVector<CSSNumberish>& numberishes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   auto values = CSSNumberishesToNumericValues(numberishes);
   std::transform(values.begin(), values.end(), values.begin(),
@@ -451,7 +484,11 @@
 }
 
 CSSNumericValue* CSSNumericValue::mul(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8CSSNumberish>>& numberishes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const HeapVector<CSSNumberish>& numberishes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   auto values = CSSNumberishesToNumericValues(numberishes);
   PrependValueForArithmetic<kProductType>(values, this);
@@ -462,7 +499,11 @@
 }
 
 CSSNumericValue* CSSNumericValue::div(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8CSSNumberish>>& numberishes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const HeapVector<CSSNumberish>& numberishes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   auto values = CSSNumberishesToNumericValues(numberishes);
   for (auto& v : values) {
@@ -482,7 +523,11 @@
 }
 
 CSSNumericValue* CSSNumericValue::min(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8CSSNumberish>>& numberishes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const HeapVector<CSSNumberish>& numberishes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   auto values = CSSNumberishesToNumericValues(numberishes);
   PrependValueForArithmetic<kMinType>(values, this);
@@ -495,7 +540,11 @@
 }
 
 CSSNumericValue* CSSNumericValue::max(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8CSSNumberish>>& numberishes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const HeapVector<CSSNumberish>& numberishes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   auto values = CSSNumberishesToNumericValues(numberishes);
   PrependValueForArithmetic<kMaxType>(values, this);
@@ -507,8 +556,14 @@
   return CSSMathMax::Create(std::move(values));
 }
 
-bool CSSNumericValue::equals(const HeapVector<CSSNumberish>& args) {
-  CSSNumericValueVector values = CSSNumberishesToNumericValues(args);
+bool CSSNumericValue::equals(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8CSSNumberish>>& numberishes
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<CSSNumberish>& numberishes
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
+  CSSNumericValueVector values = CSSNumberishesToNumericValues(numberishes);
   return std::all_of(values.begin(), values.end(),
                      [this](const auto& v) { return this->Equals(*v); });
 }
@@ -527,6 +582,16 @@
   return CSSMathInvert::Create(this);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CSSNumericValueVector CSSNumberishesToNumericValues(
+    const HeapVector<Member<V8CSSNumberish>>& values) {
+  CSSNumericValueVector result;
+  for (const V8CSSNumberish* value : values) {
+    result.push_back(CSSNumericValue::FromNumberish(value));
+  }
+  return result;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CSSNumericValueVector CSSNumberishesToNumericValues(
     const HeapVector<CSSNumberish>& values) {
   CSSNumericValueVector result;
@@ -535,5 +600,6 @@
   }
   return result;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/css_numeric_value.h b/third_party/blink/renderer/core/css/cssom/css_numeric_value.h
index e5d0c27..166d43d2 100644
--- a/third_party/blink/renderer/core/css/cssom/css_numeric_value.h
+++ b/third_party/blink/renderer/core/css/cssom/css_numeric_value.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_CSS_NUMERIC_VALUE_H_
 
 #include "third_party/blink/renderer/bindings/core/v8/double_or_css_numeric_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/css/css_primitive_value.h"
 #include "third_party/blink/renderer/core/css/cssom/css_numeric_sum_value.h"
@@ -36,12 +37,32 @@
   static CSSNumericValue* parse(const String& css_text, ExceptionState&);
   // Blink-internal ways of creating CSSNumericValues.
   static CSSNumericValue* FromCSSValue(const CSSPrimitiveValue&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // https://drafts.css-houdini.org/css-typed-om/#rectify-a-numberish-value
-  static CSSNumericValue* FromNumberish(const CSSNumberish& value);
+  static CSSNumericValue* FromNumberish(const V8CSSNumberish* value);
   // https://drafts.css-houdini.org/css-typed-om/#rectify-a-percentish-value
+  static CSSNumericValue* FromPercentish(const V8CSSNumberish* value);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSNumericValue* FromNumberish(const CSSNumberish& value);
   static CSSNumericValue* FromPercentish(const CSSNumberish& value);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Methods defined in the IDL.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  CSSNumericValue* add(const HeapVector<Member<V8CSSNumberish>>& numberishes,
+                       ExceptionState& exception_state);
+  CSSNumericValue* sub(const HeapVector<Member<V8CSSNumberish>>& numberishes,
+                       ExceptionState& exception_state);
+  CSSNumericValue* mul(const HeapVector<Member<V8CSSNumberish>>& numberishes,
+                       ExceptionState& exception_state);
+  CSSNumericValue* div(const HeapVector<Member<V8CSSNumberish>>& numberishes,
+                       ExceptionState& exception_state);
+  CSSNumericValue* min(const HeapVector<Member<V8CSSNumberish>>& numberishes,
+                       ExceptionState& exception_state);
+  CSSNumericValue* max(const HeapVector<Member<V8CSSNumberish>>& numberishes,
+                       ExceptionState& exception_state);
+  bool equals(const HeapVector<Member<V8CSSNumberish>>& numberishes);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CSSNumericValue* add(const HeapVector<CSSNumberish>&, ExceptionState&);
   CSSNumericValue* sub(const HeapVector<CSSNumberish>&, ExceptionState&);
   CSSNumericValue* mul(const HeapVector<CSSNumberish>&, ExceptionState&);
@@ -49,6 +70,7 @@
   CSSNumericValue* min(const HeapVector<CSSNumberish>&, ExceptionState&);
   CSSNumericValue* max(const HeapVector<CSSNumberish>&, ExceptionState&);
   bool equals(const HeapVector<CSSNumberish>&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Converts between compatible types, as defined in the IDL.
   CSSUnitValue* to(const String&, ExceptionState&);
@@ -87,8 +109,13 @@
   CSSNumericValueType type_;
 };
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CSSNumericValueVector CSSNumberishesToNumericValues(
+    const HeapVector<Member<V8CSSNumberish>>& values);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CSSNumericValueVector CSSNumberishesToNumericValues(
     const HeapVector<CSSNumberish>&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/css/cssom/css_rgb.cc b/third_party/blink/renderer/core/css/cssom/css_rgb.cc
index a6f97084..8056dd5 100644
--- a/third_party/blink/renderer/core/css/cssom/css_rgb.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_rgb.cc
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 #include "third_party/blink/renderer/core/css/cssom/css_rgb.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/css/cssom/css_unit_value.h"
 #include "third_party/blink/renderer/platform/graphics/color.h"
 
@@ -24,11 +26,19 @@
                CSSNumericValue* alpha)
     : r_(r), g_(g), b_(b), alpha_(alpha) {}
 
-CSSRGB* CSSRGB::Create(const CSSNumberish& red,
-                       const CSSNumberish& green,
-                       const CSSNumberish& blue,
-                       const CSSNumberish& alpha,
-                       ExceptionState& exception_state) {
+CSSRGB* CSSRGB::Create(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8CSSNumberish* red,
+    const V8CSSNumberish* green,
+    const V8CSSNumberish* blue,
+    const V8CSSNumberish* alpha,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const CSSNumberish& red,
+    const CSSNumberish& green,
+    const CSSNumberish& blue,
+    const CSSNumberish& alpha,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   CSSNumericValue* r;
   CSSNumericValue* g;
   CSSNumericValue* b;
@@ -47,12 +57,33 @@
   return MakeGarbageCollected<CSSRGB>(r, g, b, a);
 }
 
-Color CSSRGB::ToColor() const {
-  return Color(ComponentToColorInput(r_), ComponentToColorInput(g_),
-               ComponentToColorInput(b_), ComponentToColorInput(alpha_));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8CSSNumberish* CSSRGB::r() const {
+  return MakeGarbageCollected<V8CSSNumberish>(r_);
 }
 
-void CSSRGB::setR(const CSSNumberish& red, ExceptionState& exception_state) {
+V8CSSNumberish* CSSRGB::g() const {
+  return MakeGarbageCollected<V8CSSNumberish>(g_);
+}
+
+V8CSSNumberish* CSSRGB::b() const {
+  return MakeGarbageCollected<V8CSSNumberish>(b_);
+}
+
+V8CSSNumberish* CSSRGB::alpha() const {
+  return MakeGarbageCollected<V8CSSNumberish>(alpha_);
+}
+
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+void CSSRGB::setR(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8CSSNumberish* red,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const CSSNumberish& red,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   if (auto* value = ToNumberOrPercentage(red)) {
     r_ = value;
   } else {
@@ -61,7 +92,13 @@
   }
 }
 
-void CSSRGB::setG(const CSSNumberish& green, ExceptionState& exception_state) {
+void CSSRGB::setG(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8CSSNumberish* green,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const CSSNumberish& green,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   if (auto* value = ToNumberOrPercentage(green)) {
     g_ = value;
   } else {
@@ -70,7 +107,13 @@
   }
 }
 
-void CSSRGB::setB(const CSSNumberish& blue, ExceptionState& exception_state) {
+void CSSRGB::setB(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8CSSNumberish* blue,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const CSSNumberish& blue,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   if (auto* value = ToNumberOrPercentage(blue)) {
     b_ = value;
   } else {
@@ -79,12 +122,22 @@
   }
 }
 
-void CSSRGB::setAlpha(const CSSNumberish& alpha,
-                      ExceptionState& exception_state) {
+void CSSRGB::setAlpha(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8CSSNumberish* alpha,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const CSSNumberish& alpha,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   if (auto* value = ToPercentage(alpha))
     alpha_ = value;
   else
     exception_state.ThrowTypeError("Alpha must be a percentage.");
 }
 
+Color CSSRGB::ToColor() const {
+  return Color(ComponentToColorInput(r_), ComponentToColorInput(g_),
+               ComponentToColorInput(b_), ComponentToColorInput(alpha_));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/css_rgb.h b/third_party/blink/renderer/core/css/cssom/css_rgb.h
index b4198414..39bd322 100644
--- a/third_party/blink/renderer/core/css/cssom/css_rgb.h
+++ b/third_party/blink/renderer/core/css/cssom/css_rgb.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_CSS_RGB_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_CSS_RGB_H_
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/css/cssom/css_color_value.h"
 #include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h"
@@ -19,11 +20,19 @@
 
  public:
   // Constructor defined in the IDL.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSRGB* Create(const V8CSSNumberish* r,
+                        const V8CSSNumberish* g,
+                        const V8CSSNumberish* b,
+                        const V8CSSNumberish* alpha,
+                        ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSRGB* Create(const CSSNumberish&,
                         const CSSNumberish&,
                         const CSSNumberish&,
                         const CSSNumberish&,
                         ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Internal constructor used by blink.
   explicit CSSRGB(const Color&);
@@ -33,6 +42,16 @@
          CSSNumericValue*);
 
   // Getters and setters from the IDL
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* r() const;
+  V8CSSNumberish* g() const;
+  V8CSSNumberish* b() const;
+  V8CSSNumberish* alpha() const;
+  void setR(const V8CSSNumberish* r, ExceptionState& exception_state);
+  void setG(const V8CSSNumberish* g, ExceptionState& exception_state);
+  void setB(const V8CSSNumberish* b, ExceptionState& exception_state);
+  void setAlpha(const V8CSSNumberish* alpha, ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void r(CSSNumberish& r) { r.SetCSSNumericValue(r_); }
   void g(CSSNumberish& g) { g.SetCSSNumericValue(g_); }
   void b(CSSNumberish& b) { b.SetCSSNumericValue(b_); }
@@ -41,6 +60,7 @@
   void setG(const CSSNumberish&, ExceptionState&);
   void setB(const CSSNumberish&, ExceptionState&);
   void setAlpha(const CSSNumberish&, ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor* visitor) const override {
     visitor->Trace(r_);
diff --git a/third_party/blink/renderer/core/css/cssom/css_rotate.cc b/third_party/blink/renderer/core/css/cssom/css_rotate.cc
index d7f6a5f8..4007a05 100644
--- a/third_party/blink/renderer/core/css/cssom/css_rotate.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_rotate.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/css/cssom/css_rotate.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/css/css_function_value.h"
 #include "third_party/blink/renderer/core/css/css_primitive_value.h"
 #include "third_party/blink/renderer/core/css/cssom/css_unit_value.h"
@@ -80,6 +81,29 @@
       angle, true /* is2D */);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CSSRotate* CSSRotate::Create(const V8CSSNumberish* x,
+                             const V8CSSNumberish* y,
+                             const V8CSSNumberish* z,
+                             CSSNumericValue* angle,
+                             ExceptionState& exception_state) {
+  CSSNumericValue* x_value = CSSNumericValue::FromNumberish(x);
+  CSSNumericValue* y_value = CSSNumericValue::FromNumberish(y);
+  CSSNumericValue* z_value = CSSNumericValue::FromNumberish(z);
+
+  if (!IsValidRotateCoord(x_value) || !IsValidRotateCoord(y_value) ||
+      !IsValidRotateCoord(z_value)) {
+    exception_state.ThrowTypeError("Must specify an number unit");
+    return nullptr;
+  }
+  if (!IsValidRotateAngle(angle)) {
+    exception_state.ThrowTypeError("Must pass an angle to CSSRotate");
+    return nullptr;
+  }
+  return MakeGarbageCollected<CSSRotate>(x_value, y_value, z_value, angle,
+                                         false /* is2D */);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CSSRotate* CSSRotate::Create(const CSSNumberish& x,
                              const CSSNumberish& y,
                              const CSSNumberish& z,
@@ -101,6 +125,7 @@
   return MakeGarbageCollected<CSSRotate>(x_value, y_value, z_value, angle,
                                          false /* is2D */);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 CSSRotate* CSSRotate::Create(CSSNumericValue* angle) {
   return MakeGarbageCollected<CSSRotate>(
@@ -189,6 +214,49 @@
   return result;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8CSSNumberish* CSSRotate::x() {
+  return MakeGarbageCollected<V8CSSNumberish>(x_);
+}
+
+V8CSSNumberish* CSSRotate::y() {
+  return MakeGarbageCollected<V8CSSNumberish>(y_);
+}
+
+V8CSSNumberish* CSSRotate::z() {
+  return MakeGarbageCollected<V8CSSNumberish>(z_);
+}
+
+void CSSRotate::setX(const V8CSSNumberish* x, ExceptionState& exception_state) {
+  CSSNumericValue* value = CSSNumericValue::FromNumberish(x);
+  if (!IsValidRotateCoord(value)) {
+    exception_state.ThrowTypeError("Must specify a number unit");
+    return;
+  }
+  x_ = value;
+}
+
+void CSSRotate::setY(const V8CSSNumberish* y, ExceptionState& exception_state) {
+  CSSNumericValue* value = CSSNumericValue::FromNumberish(y);
+  if (!IsValidRotateCoord(value)) {
+    exception_state.ThrowTypeError("Must specify a number unit");
+    return;
+  }
+  y_ = value;
+}
+
+void CSSRotate::setZ(const V8CSSNumberish* z, ExceptionState& exception_state) {
+  CSSNumericValue* value = CSSNumericValue::FromNumberish(z);
+  if (!IsValidRotateCoord(value)) {
+    exception_state.ThrowTypeError("Must specify a number unit");
+    return;
+  }
+  z_ = value;
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void CSSRotate::setX(const CSSNumberish& x, ExceptionState& exception_state) {
   CSSNumericValue* value = CSSNumericValue::FromNumberish(x);
   if (!IsValidRotateCoord(value)) {
@@ -216,6 +284,8 @@
   z_ = value;
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 CSSRotate::CSSRotate(CSSNumericValue* x,
                      CSSNumericValue* y,
                      CSSNumericValue* z,
diff --git a/third_party/blink/renderer/core/css/cssom/css_rotate.h b/third_party/blink/renderer/core/css/cssom/css_rotate.h
index 1a228e7..75d67e0 100644
--- a/third_party/blink/renderer/core/css/cssom/css_rotate.h
+++ b/third_party/blink/renderer/core/css/cssom/css_rotate.h
@@ -23,11 +23,19 @@
  public:
   // Constructors defined in the IDL.
   static CSSRotate* Create(CSSNumericValue* angle, ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSRotate* Create(const V8CSSNumberish* x,
+                           const V8CSSNumberish* y,
+                           const V8CSSNumberish* z,
+                           CSSNumericValue* angle,
+                           ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSRotate* Create(const CSSNumberish& x,
                            const CSSNumberish& y,
                            const CSSNumberish& z,
                            CSSNumericValue* angle,
                            ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Blink-internal ways of creating CSSRotates.
   static CSSRotate* Create(CSSNumericValue* angle);
@@ -48,12 +56,21 @@
   // Getters and setters for attributes defined in the IDL.
   CSSNumericValue* angle() { return angle_.Get(); }
   void setAngle(CSSNumericValue* angle, ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* x();
+  V8CSSNumberish* y();
+  V8CSSNumberish* z();
+  void setX(const V8CSSNumberish* x, ExceptionState& exception_state);
+  void setY(const V8CSSNumberish* y, ExceptionState& exception_state);
+  void setZ(const V8CSSNumberish* z, ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void x(CSSNumberish& x) { x.SetCSSNumericValue(x_); }
   void y(CSSNumberish& y) { y.SetCSSNumericValue(y_); }
   void z(CSSNumberish& z) { z.SetCSSNumericValue(z_); }
   void setX(const CSSNumberish&, ExceptionState&);
   void setY(const CSSNumberish&, ExceptionState&);
   void setZ(const CSSNumberish&, ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   DOMMatrix* toMatrix(ExceptionState&) const final;
 
diff --git a/third_party/blink/renderer/core/css/cssom/css_scale.cc b/third_party/blink/renderer/core/css/cssom/css_scale.cc
index 58b63ce..079301d9 100644
--- a/third_party/blink/renderer/core/css/cssom/css_scale.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_scale.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/css/cssom/css_scale.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/css/css_math_expression_node.h"
 #include "third_party/blink/renderer/core/css/css_primitive_value.h"
 #include "third_party/blink/renderer/core/css/cssom/css_numeric_value.h"
@@ -74,6 +75,41 @@
 
 }  // namespace
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+CSSScale* CSSScale::Create(const V8CSSNumberish* x,
+                           const V8CSSNumberish* y,
+                           ExceptionState& exception_state) {
+  CSSNumericValue* x_value = CSSNumericValue::FromNumberish(x);
+  CSSNumericValue* y_value = CSSNumericValue::FromNumberish(y);
+
+  if (!IsValidScaleCoord(x_value) || !IsValidScaleCoord(y_value)) {
+    exception_state.ThrowTypeError("Must specify an number unit");
+    return nullptr;
+  }
+
+  return CSSScale::Create(x_value, y_value);
+}
+
+CSSScale* CSSScale::Create(const V8CSSNumberish* x,
+                           const V8CSSNumberish* y,
+                           const V8CSSNumberish* z,
+                           ExceptionState& exception_state) {
+  CSSNumericValue* x_value = CSSNumericValue::FromNumberish(x);
+  CSSNumericValue* y_value = CSSNumericValue::FromNumberish(y);
+  CSSNumericValue* z_value = CSSNumericValue::FromNumberish(z);
+
+  if (!IsValidScaleCoord(x_value) || !IsValidScaleCoord(y_value) ||
+      !IsValidScaleCoord(z_value)) {
+    exception_state.ThrowTypeError("Must specify a number for X, Y and Z");
+    return nullptr;
+  }
+
+  return CSSScale::Create(x_value, y_value, z_value);
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 CSSScale* CSSScale::Create(const CSSNumberish& x,
                            const CSSNumberish& y,
                            ExceptionState& exception_state) {
@@ -105,6 +141,8 @@
   return CSSScale::Create(x_value, y_value, z_value);
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 CSSScale* CSSScale::FromCSSValue(const CSSFunctionValue& value) {
   switch (value.FunctionType()) {
     case CSSValueID::kScale:
@@ -121,6 +159,55 @@
   }
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8CSSNumberish* CSSScale::x() {
+  return MakeGarbageCollected<V8CSSNumberish>(x_);
+}
+
+V8CSSNumberish* CSSScale::y() {
+  return MakeGarbageCollected<V8CSSNumberish>(y_);
+}
+
+V8CSSNumberish* CSSScale::z() {
+  return MakeGarbageCollected<V8CSSNumberish>(z_);
+}
+
+void CSSScale::setX(const V8CSSNumberish* x, ExceptionState& exception_state) {
+  CSSNumericValue* value = CSSNumericValue::FromNumberish(x);
+
+  if (!IsValidScaleCoord(value)) {
+    exception_state.ThrowTypeError("Must specify a number unit");
+    return;
+  }
+
+  x_ = value;
+}
+
+void CSSScale::setY(const V8CSSNumberish* y, ExceptionState& exception_state) {
+  CSSNumericValue* value = CSSNumericValue::FromNumberish(y);
+
+  if (!IsValidScaleCoord(value)) {
+    exception_state.ThrowTypeError("Must specify a number unit");
+    return;
+  }
+
+  y_ = value;
+}
+
+void CSSScale::setZ(const V8CSSNumberish* z, ExceptionState& exception_state) {
+  CSSNumericValue* value = CSSNumericValue::FromNumberish(z);
+
+  if (!IsValidScaleCoord(value)) {
+    exception_state.ThrowTypeError("Must specify a number unit");
+    return;
+  }
+
+  z_ = value;
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void CSSScale::setX(const CSSNumberish& x, ExceptionState& exception_state) {
   CSSNumericValue* value = CSSNumericValue::FromNumberish(x);
 
@@ -154,6 +241,8 @@
   z_ = value;
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 DOMMatrix* CSSScale::toMatrix(ExceptionState& exception_state) const {
   CSSUnitValue* x = x_->to(CSSPrimitiveValue::UnitType::kNumber);
   CSSUnitValue* y = y_->to(CSSPrimitiveValue::UnitType::kNumber);
diff --git a/third_party/blink/renderer/core/css/cssom/css_scale.h b/third_party/blink/renderer/core/css/cssom/css_scale.h
index aacd6da..19bbe97 100644
--- a/third_party/blink/renderer/core/css/cssom/css_scale.h
+++ b/third_party/blink/renderer/core/css/cssom/css_scale.h
@@ -22,6 +22,15 @@
 
  public:
   // Constructors defined in the IDL.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSScale* Create(const V8CSSNumberish* x,
+                          const V8CSSNumberish* y,
+                          ExceptionState& exception_state);
+  static CSSScale* Create(const V8CSSNumberish* x,
+                          const V8CSSNumberish* y,
+                          const V8CSSNumberish* z,
+                          ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSScale* Create(const CSSNumberish&,
                           const CSSNumberish&,
                           ExceptionState&);
@@ -29,6 +38,7 @@
                           const CSSNumberish&,
                           const CSSNumberish&,
                           ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Blink-internal ways of creating CSSScales.
   static CSSScale* Create(CSSNumericValue* x, CSSNumericValue* y) {
@@ -50,12 +60,21 @@
   CSSScale& operator=(const CSSScale&) = delete;
 
   // Getters and setters for attributes defined in the IDL.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSNumberish* x();
+  V8CSSNumberish* y();
+  V8CSSNumberish* z();
+  void setX(const V8CSSNumberish* x, ExceptionState& exception_state);
+  void setY(const V8CSSNumberish* y, ExceptionState& exception_state);
+  void setZ(const V8CSSNumberish* z, ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void x(CSSNumberish& x) { x.SetCSSNumericValue(x_); }
   void y(CSSNumberish& y) { y.SetCSSNumericValue(y_); }
   void z(CSSNumberish& z) { z.SetCSSNumericValue(z_); }
   void setX(const CSSNumberish&, ExceptionState&);
   void setY(const CSSNumberish&, ExceptionState&);
   void setZ(const CSSNumberish&, ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   DOMMatrix* toMatrix(ExceptionState&) const final;
 
diff --git a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
index 119929b..813f96a 100644
--- a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
@@ -21,9 +21,18 @@
   return range.Consume().Value();
 }
 
-CSSUnparsedSegment VariableReferenceValue(
-    const StringView& variable_name,
-    const HeapVector<CSSUnparsedSegment>& tokens) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8CSSUnparsedSegment*
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CSSUnparsedSegment
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+VariableReferenceValue(const StringView& variable_name,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                       const HeapVector<Member<V8CSSUnparsedSegment>>& tokens
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                       const HeapVector<CSSUnparsedSegment>& tokens
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   CSSUnparsedValue* unparsed_value;
   if (tokens.size() == 0)
     unparsed_value = nullptr;
@@ -33,18 +42,35 @@
   CSSStyleVariableReferenceValue* variable_reference =
       CSSStyleVariableReferenceValue::Create(variable_name.ToString(),
                                              unparsed_value);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  return MakeGarbageCollected<V8CSSUnparsedSegment>(variable_reference);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   return CSSUnparsedSegment::FromCSSVariableReferenceValue(variable_reference);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
-HeapVector<CSSUnparsedSegment> ParserTokenRangeToTokens(
-    CSSParserTokenRange range) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+HeapVector<Member<V8CSSUnparsedSegment>>
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+HeapVector<CSSUnparsedSegment>
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+ParserTokenRangeToTokens(CSSParserTokenRange range) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8CSSUnparsedSegment>> tokens;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<CSSUnparsedSegment> tokens;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringBuilder builder;
   while (!range.AtEnd()) {
     if (range.Peek().FunctionId() == CSSValueID::kVar ||
         range.Peek().FunctionId() == CSSValueID::kEnv) {
       if (!builder.IsEmpty()) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+        tokens.push_back(
+            MakeGarbageCollected<V8CSSUnparsedSegment>(builder.ToString()));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
         tokens.push_back(CSSUnparsedSegment::FromString(builder.ToString()));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
         builder.Clear();
       }
       CSSParserTokenRange block = range.ConsumeBlock();
@@ -59,7 +85,12 @@
     }
   }
   if (!builder.IsEmpty()) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    tokens.push_back(
+        MakeGarbageCollected<V8CSSUnparsedSegment>(builder.ToString()));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     tokens.push_back(CSSUnparsedSegment::FromString(builder.ToString()));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   }
   return tokens;
 }
@@ -86,6 +117,40 @@
   return CSSUnparsedValue::Create(ParserTokenRangeToTokens(value.TokenRange()));
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8CSSUnparsedSegment* CSSUnparsedValue::AnonymousIndexedGetter(
+    uint32_t index,
+    ExceptionState& exception_state) const {
+  if (index < tokens_.size()) {
+    return tokens_[index];
+  }
+  return nullptr;
+}
+
+IndexedPropertySetterResult CSSUnparsedValue::AnonymousIndexedSetter(
+    uint32_t index,
+    V8CSSUnparsedSegment* segment,
+    ExceptionState& exception_state) {
+  if (index < tokens_.size()) {
+    tokens_[index] = segment;
+    return IndexedPropertySetterResult::kIntercepted;
+  }
+
+  if (index == tokens_.size()) {
+    tokens_.push_back(segment);
+    return IndexedPropertySetterResult::kIntercepted;
+  }
+
+  exception_state.ThrowRangeError(
+      ExceptionMessages::IndexOutsideRange<unsigned>(
+          "index", index, 0, ExceptionMessages::kInclusiveBound, tokens_.size(),
+          ExceptionMessages::kInclusiveBound));
+  return IndexedPropertySetterResult::kIntercepted;
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void CSSUnparsedValue::AnonymousIndexedGetter(
     unsigned index,
     CSSUnparsedSegment& return_value,
@@ -118,6 +183,8 @@
   return IndexedPropertySetterResult::kIntercepted;
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 const CSSValue* CSSUnparsedValue::ToCSSValue() const {
   CSSTokenizer tokenizer(ToString());
   const auto tokens = tokenizer.TokenizeToEOF();
@@ -134,6 +201,36 @@
           false /* needs_variable_resolution */, KURL(), WTF::TextEncoding()));
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+String CSSUnparsedValue::ToString() const {
+  StringBuilder input;
+
+  for (unsigned i = 0; i < tokens_.size(); i++) {
+    if (i) {
+      input.Append("/**/");
+    }
+    switch (tokens_[i]->GetContentType()) {
+      case V8CSSUnparsedSegment::ContentType::kCSSVariableReferenceValue: {
+        const auto* reference_value =
+            tokens_[i]->GetAsCSSVariableReferenceValue();
+        input.Append("var(");
+        input.Append(reference_value->variable());
+        if (reference_value->fallback()) {
+          input.Append(",");
+          input.Append(reference_value->fallback()->ToString());
+        }
+        input.Append(")");
+        break;
+      }
+      case V8CSSUnparsedSegment::ContentType::kString:
+        input.Append(tokens_[i]->GetAsString());
+        break;
+    }
+  }
+
+  return input.ToString();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 String CSSUnparsedValue::ToString() const {
   StringBuilder input;
 
@@ -159,5 +256,6 @@
 
   return input.ToString();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
index 39f3224..fa533cc 100644
--- a/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
+++ b/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h
@@ -6,6 +6,8 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSSOM_CSS_UNPARSED_VALUE_H_
 
 #include "third_party/blink/renderer/bindings/core/v8/string_or_css_variable_reference_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssvariablereferencevalue_string.h"
 #include "third_party/blink/renderer/core/css/cssom/css_style_value.h"
 #include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -21,26 +23,48 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSUnparsedValue* Create(
+      const HeapVector<Member<V8CSSUnparsedSegment>>& tokens) {
+    return MakeGarbageCollected<CSSUnparsedValue>(tokens);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSUnparsedValue* Create(
       const HeapVector<CSSUnparsedSegment>& tokens) {
     return MakeGarbageCollected<CSSUnparsedValue>(tokens);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Blink-internal constructor
   static CSSUnparsedValue* Create() {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    return Create(HeapVector<Member<V8CSSUnparsedSegment>>());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     return Create(HeapVector<CSSUnparsedSegment>());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   }
   static CSSUnparsedValue* FromCSSValue(const CSSVariableReferenceValue&);
   static CSSUnparsedValue* FromCSSValue(const CSSCustomPropertyDeclaration&);
   static CSSUnparsedValue* FromCSSVariableData(const CSSVariableData&);
   static CSSUnparsedValue* FromString(const String& string) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    HeapVector<Member<V8CSSUnparsedSegment>> tokens;
+    tokens.push_back(MakeGarbageCollected<V8CSSUnparsedSegment>(string));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     HeapVector<CSSUnparsedSegment> tokens;
     tokens.push_back(CSSUnparsedSegment::FromString(string));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     return Create(tokens);
   }
 
-  CSSUnparsedValue(const HeapVector<CSSUnparsedSegment>& tokens)
-      : CSSStyleValue(), tokens_(tokens) {}
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  explicit CSSUnparsedValue(
+      const HeapVector<Member<V8CSSUnparsedSegment>>& tokens)
+      : tokens_(tokens) {}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  explicit CSSUnparsedValue(const HeapVector<CSSUnparsedSegment>& tokens)
+      : tokens_(tokens) {}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CSSUnparsedValue(const CSSUnparsedValue&) = delete;
   CSSUnparsedValue& operator=(const CSSUnparsedValue&) = delete;
 
@@ -48,12 +72,22 @@
 
   StyleValueType GetType() const override { return kUnparsedType; }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8CSSUnparsedSegment* AnonymousIndexedGetter(
+      uint32_t index,
+      ExceptionState& exception_state) const;
+  IndexedPropertySetterResult AnonymousIndexedSetter(
+      uint32_t index,
+      V8CSSUnparsedSegment* segment,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void AnonymousIndexedGetter(uint32_t index,
                               CSSUnparsedSegment& return_value,
                               ExceptionState& exception_state) const;
   IndexedPropertySetterResult AnonymousIndexedSetter(unsigned,
                                                      const CSSUnparsedSegment&,
                                                      ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   wtf_size_t length() const { return tokens_.size(); }
 
@@ -65,9 +99,13 @@
   String ToString() const;
 
  private:
-  FRIEND_TEST_ALL_PREFIXES(CSSVariableReferenceValueTest, MixedList);
-
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8CSSUnparsedSegment>> tokens_;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<CSSUnparsedSegment> tokens_;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+  FRIEND_TEST_ALL_PREFIXES(CSSVariableReferenceValueTest, MixedList);
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/css/cssom/style_property_map.cc b/third_party/blink/renderer/core/css/cssom/style_property_map.cc
index 583f9a8a..54471296 100644
--- a/third_party/blink/renderer/core/css/cssom/style_property_map.cc
+++ b/third_party/blink/renderer/core/css/cssom/style_property_map.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/css/cssom/style_property_map.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssstylevalue_string.h"
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_property_name.h"
 #include "third_party/blink/renderer/core/css/css_value_list.h"
@@ -204,6 +205,37 @@
   return style_value.ToCSSValueWithProperty(property_id);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+const CSSValue* CoerceStyleValueOrString(
+    const CSSProperty& property,
+    const AtomicString& custom_property_name,
+    const V8UnionCSSStyleValueOrString* value,
+    const ExecutionContext& execution_context) {
+  DCHECK(!property.IsRepeated());
+  DCHECK_EQ(property.IDEquals(CSSPropertyID::kVariable),
+            !custom_property_name.IsNull());
+  DCHECK(value);
+
+  switch (value->GetContentType()) {
+    case V8UnionCSSStyleValueOrString::ContentType::kCSSStyleValue:
+      return StyleValueToCSSValue(property, custom_property_name,
+                                  *value->GetAsCSSStyleValue(),
+                                  execution_context);
+    case V8UnionCSSStyleValueOrString::ContentType::kString: {
+      const auto& values = StyleValueFactory::FromString(
+          property.PropertyID(), custom_property_name, value->GetAsString(),
+          MakeGarbageCollected<CSSParserContext>(execution_context));
+      if (values.size() != 1U)
+        return nullptr;
+      return StyleValueToCSSValue(property, custom_property_name, *values[0],
+                                  execution_context);
+    }
+  }
+
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 const CSSValue* CoerceStyleValueOrString(
     const CSSProperty& property,
     const AtomicString& custom_property_name,
@@ -231,11 +263,16 @@
                                 execution_context);
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 const CSSValue* CoerceStyleValuesOrStrings(
     const CSSProperty& property,
     const AtomicString& custom_property_name,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionCSSStyleValueOrString>>& values,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const HeapVector<CSSStyleValueOrString>& values,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const ExecutionContext& execution_context) {
   DCHECK(property.IsRepeated());
   DCHECK_EQ(property.IDEquals(CSSPropertyID::kVariable),
@@ -266,10 +303,15 @@
 
 }  // namespace
 
-void StylePropertyMap::set(const ExecutionContext* execution_context,
-                           const String& property_name,
-                           const HeapVector<CSSStyleValueOrString>& values,
-                           ExceptionState& exception_state) {
+void StylePropertyMap::set(
+    const ExecutionContext* execution_context,
+    const String& property_name,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionCSSStyleValueOrString>>& values,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<CSSStyleValueOrString>& values,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   const CSSPropertyID property_id =
       CssPropertyID(execution_context, property_name);
   if (property_id == CSSPropertyID::kInvalid) {
@@ -286,6 +328,21 @@
     }
 
     String css_text;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    switch (values[0]->GetContentType()) {
+      case V8UnionCSSStyleValueOrString::ContentType::kCSSStyleValue: {
+        CSSStyleValue* style_value = values[0]->GetAsCSSStyleValue();
+        if (CSSOMTypes::PropertyCanTake(property_id, g_null_atom,
+                                        *style_value)) {
+          css_text = style_value->toString();
+        }
+        break;
+      }
+      case V8UnionCSSStyleValueOrString::ContentType::kString:
+        css_text = values[0]->GetAsString();
+        break;
+    }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     if (values[0].IsCSSStyleValue()) {
       CSSStyleValue* style_value = values[0].GetAsCSSStyleValue();
       if (style_value &&
@@ -295,18 +352,20 @@
     } else {
       css_text = values[0].GetAsString();
     }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
     if (css_text.IsEmpty() ||
         !SetShorthandProperty(property.PropertyID(), css_text,
-                              execution_context->GetSecureContextMode()))
+                              execution_context->GetSecureContextMode())) {
       exception_state.ThrowTypeError("Invalid type for property");
+    }
 
     return;
   }
 
-  AtomicString custom_property_name = (property_id == CSSPropertyID::kVariable)
-                                          ? AtomicString(property_name)
-                                          : g_null_atom;
+  const AtomicString& custom_property_name =
+      (property_id == CSSPropertyID::kVariable) ? AtomicString(property_name)
+                                                : g_null_atom;
 
   const CSSValue* result = nullptr;
   if (property.IsRepeated()) {
@@ -328,10 +387,15 @@
     SetProperty(property_id, *result);
 }
 
-void StylePropertyMap::append(const ExecutionContext* execution_context,
-                              const String& property_name,
-                              const HeapVector<CSSStyleValueOrString>& values,
-                              ExceptionState& exception_state) {
+void StylePropertyMap::append(
+    const ExecutionContext* execution_context,
+    const String& property_name,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionCSSStyleValueOrString>>& values,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<CSSStyleValueOrString>& values,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   if (values.IsEmpty())
     return;
 
diff --git a/third_party/blink/renderer/core/css/cssom/style_property_map.h b/third_party/blink/renderer/core/css/cssom/style_property_map.h
index 0f8e649..bc01b784 100644
--- a/third_party/blink/renderer/core/css/cssom/style_property_map.h
+++ b/third_party/blink/renderer/core/css/cssom/style_property_map.h
@@ -13,6 +13,7 @@
 
 class ExceptionState;
 class ExecutionContext;
+class V8UnionCSSStyleValueOrString;
 
 class CORE_EXPORT StylePropertyMap : public StylePropertyMapReadOnlyMainThread {
   DEFINE_WRAPPERTYPEINFO();
@@ -21,6 +22,16 @@
   StylePropertyMap(const StylePropertyMap&) = delete;
   StylePropertyMap& operator=(const StylePropertyMap&) = delete;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void set(const ExecutionContext* execution_context,
+           const String& property_name,
+           const HeapVector<Member<V8UnionCSSStyleValueOrString>>& values,
+           ExceptionState& exception_state);
+  void append(const ExecutionContext* execution_context,
+              const String& property_name,
+              const HeapVector<Member<V8UnionCSSStyleValueOrString>>& values,
+              ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void set(const ExecutionContext*,
            const String& property_name,
            const HeapVector<CSSStyleValueOrString>& values,
@@ -29,6 +40,7 @@
               const String& property_name,
               const HeapVector<CSSStyleValueOrString>& values,
               ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void remove(const ExecutionContext*,
               const String& property_name,
               ExceptionState&);
diff --git a/third_party/blink/renderer/core/css/cssom/style_property_map_test.cc b/third_party/blink/renderer/core/css/cssom/style_property_map_test.cc
index cc87329f..136a47f 100644
--- a/third_party/blink/renderer/core/css/cssom/style_property_map_test.cc
+++ b/third_party/blink/renderer/core/css/cssom/style_property_map_test.cc
@@ -3,7 +3,9 @@
 // found in the LICENSE file.
 
 #include "third_party/blink/renderer/core/css/cssom/style_property_map.h"
+
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssstylevalue_string.h"
 #include "third_party/blink/renderer/core/css/cssom/css_keyword_value.h"
 #include "third_party/blink/renderer/core/css/cssom/inline_style_property_map.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
@@ -17,12 +19,23 @@
 TEST_F(StylePropertyMapTest, SetRevertWithFeatureEnabled) {
   DummyExceptionStateForTesting exception_state;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8UnionCSSStyleValueOrString>> revert_string;
+  revert_string.push_back(
+      MakeGarbageCollected<V8UnionCSSStyleValueOrString>(" revert"));
+
+  HeapVector<Member<V8UnionCSSStyleValueOrString>> revert_style_value;
+  revert_style_value.push_back(
+      MakeGarbageCollected<V8UnionCSSStyleValueOrString>(
+          CSSKeywordValue::Create("revert", exception_state)));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<CSSStyleValueOrString> revert_string;
   revert_string.push_back(CSSStyleValueOrString::FromString(" revert"));
 
   HeapVector<CSSStyleValueOrString> revert_style_value;
   revert_style_value.push_back(CSSStyleValueOrString::FromCSSStyleValue(
       CSSKeywordValue::Create("revert", exception_state)));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   auto* map =
       MakeGarbageCollected<InlineStylePropertyMap>(GetDocument().body());
@@ -53,8 +66,14 @@
 
   DummyExceptionStateForTesting exception_state;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8UnionCSSStyleValueOrString>> clip_string;
+  clip_string.push_back(
+      MakeGarbageCollected<V8UnionCSSStyleValueOrString>(" clip"));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<CSSStyleValueOrString> clip_string;
   clip_string.push_back(CSSStyleValueOrString::FromString(" clip"));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   auto* map =
       MakeGarbageCollected<InlineStylePropertyMap>(GetDocument().body());
@@ -76,9 +95,15 @@
 
   DummyExceptionStateForTesting exception_state;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8UnionCSSStyleValueOrString>> clip_style_value;
+  clip_style_value.push_back(MakeGarbageCollected<V8UnionCSSStyleValueOrString>(
+      CSSKeywordValue::Create("clip", exception_state)));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<CSSStyleValueOrString> clip_style_value;
   clip_style_value.push_back(CSSStyleValueOrString::FromCSSStyleValue(
       CSSKeywordValue::Create("clip", exception_state)));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   auto* map =
       MakeGarbageCollected<InlineStylePropertyMap>(GetDocument().body());
diff --git a/third_party/blink/renderer/core/css/cssom/style_value_factory.cc b/third_party/blink/renderer/core/css/cssom/style_value_factory.cc
index 32c441f6..4e8f713 100644
--- a/third_party/blink/renderer/core/css/cssom/style_value_factory.cc
+++ b/third_party/blink/renderer/core/css/cssom/style_value_factory.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/css/cssom/style_value_factory.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssstylevalue_string.h"
 #include "third_party/blink/renderer/core/css/css_color.h"
 #include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
 #include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
@@ -313,6 +314,42 @@
   return style_value;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CSSStyleValueVector StyleValueFactory::CoerceStyleValuesOrStrings(
+    const CSSProperty& property,
+    const AtomicString& custom_property_name,
+    const HeapVector<Member<V8UnionCSSStyleValueOrString>>& values,
+    const ExecutionContext& execution_context) {
+  const CSSParserContext* parser_context = nullptr;
+
+  CSSStyleValueVector style_values;
+  for (const auto& value : values) {
+    DCHECK(value);
+    switch (value->GetContentType()) {
+      case V8UnionCSSStyleValueOrString::ContentType::kCSSStyleValue:
+        style_values.push_back(*value->GetAsCSSStyleValue());
+        break;
+      case V8UnionCSSStyleValueOrString::ContentType::kString: {
+        if (!parser_context) {
+          parser_context =
+              MakeGarbageCollected<CSSParserContext>(execution_context);
+        }
+
+        const auto& subvalues = StyleValueFactory::FromString(
+            property.PropertyID(), custom_property_name, value->GetAsString(),
+            parser_context);
+        if (subvalues.IsEmpty())
+          return CSSStyleValueVector();
+
+        DCHECK(!subvalues.Contains(nullptr));
+        style_values.AppendVector(subvalues);
+        break;
+      }
+    }
+  }
+  return style_values;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CSSStyleValueVector StyleValueFactory::CoerceStyleValuesOrStrings(
     const CSSProperty& property,
     const AtomicString& custom_property_name,
@@ -345,6 +382,7 @@
   }
   return style_values;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 CSSStyleValueVector StyleValueFactory::CssValueToStyleValueVector(
     const CSSPropertyName& name,
diff --git a/third_party/blink/renderer/core/css/cssom/style_value_factory.h b/third_party/blink/renderer/core/css/cssom/style_value_factory.h
index e4c232a2..5741ba2 100644
--- a/third_party/blink/renderer/core/css/cssom/style_value_factory.h
+++ b/third_party/blink/renderer/core/css/cssom/style_value_factory.h
@@ -17,6 +17,7 @@
 class CSSPropertyName;
 class CSSValue;
 class ExecutionContext;
+class V8UnionCSSStyleValueOrString;
 
 class CORE_EXPORT StyleValueFactory {
   STATIC_ONLY(StyleValueFactory);
@@ -32,11 +33,19 @@
   static CSSStyleValueVector CssValueToStyleValueVector(const CSSPropertyName&,
                                                         const CSSValue&);
   // Returns an empty vector on error conditions.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CSSStyleValueVector CoerceStyleValuesOrStrings(
+      const CSSProperty& property,
+      const AtomicString& custom_property_name,
+      const HeapVector<Member<V8UnionCSSStyleValueOrString>>& values,
+      const ExecutionContext& execution_context);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CSSStyleValueVector CoerceStyleValuesOrStrings(
       const CSSProperty& property,
       const AtomicString& custom_property_name,
       const HeapVector<CSSStyleValueOrString>& values,
       const ExecutionContext&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // Reify a CSSStyleValue without the context of a CSS property. For most
   // CSSValues, this will result in a CSSUnsupportedStyleValue. Note that the
   // CSSUnsupportedStyleValue returned from this function (unlike regular
diff --git a/third_party/blink/renderer/core/css/element_rule_collector.cc b/third_party/blink/renderer/core/css/element_rule_collector.cc
index 9225ae7d..3b4fbd3 100644
--- a/third_party/blink/renderer/core/css/element_rule_collector.cc
+++ b/third_party/blink/renderer/core/css/element_rule_collector.cc
@@ -227,7 +227,7 @@
     bool matching_tree_boundary_rules) {
   DCHECK(match_request.rule_set);
 
-  SelectorChecker checker(style_, nullptr, pseudo_style_request_, mode_,
+  SelectorChecker checker(style_.get(), nullptr, pseudo_style_request_, mode_,
                           matching_ua_rules_);
 
   Element& element = context_.GetElement();
@@ -302,7 +302,7 @@
 
 void ElementRuleCollector::CollectMatchingShadowHostRules(
     const MatchRequest& match_request) {
-  SelectorChecker checker(style_, nullptr, pseudo_style_request_, mode_,
+  SelectorChecker checker(style_.get(), nullptr, pseudo_style_request_, mode_,
                           matching_ua_rules_);
 
   CollectMatchingRulesForList(match_request.rule_set->ShadowHostRules(),
@@ -314,8 +314,8 @@
     PartNames& part_names,
     bool for_shadow_pseudo) {
   PartRequest request{part_names, for_shadow_pseudo};
-  SelectorChecker checker(style_, &part_names, pseudo_style_request_, mode_,
-                          matching_ua_rules_);
+  SelectorChecker checker(style_.get(), &part_names, pseudo_style_request_,
+                          mode_, matching_ua_rules_);
 
   CollectMatchingRulesForList(match_request.rule_set->PartPseudoRules(),
                               match_request, checker, &request);
diff --git a/third_party/blink/renderer/core/css/element_rule_collector.h b/third_party/blink/renderer/core/css/element_rule_collector.h
index 23cc4cc8..98e86caf 100644
--- a/third_party/blink/renderer/core/css/element_rule_collector.h
+++ b/third_party/blink/renderer/core/css/element_rule_collector.h
@@ -177,7 +177,8 @@
   const ElementResolveContext& context_;
   StyleRecalcContext style_recalc_context_;
   const SelectorFilter& selector_filter_;
-  ComputedStyle* style_;  // FIXME: This can be mutated during matching!
+  scoped_refptr<ComputedStyle>
+      style_;  // FIXME: This can be mutated during matching!
 
   StyleRequest pseudo_style_request_;
   SelectorChecker::Mode mode_;
diff --git a/third_party/blink/renderer/core/css/element_rule_collector_test.cc b/third_party/blink/renderer/core/css/element_rule_collector_test.cc
index 447dfc3..bf154bb 100644
--- a/third_party/blink/renderer/core/css/element_rule_collector_test.cc
+++ b/third_party/blink/renderer/core/css/element_rule_collector_test.cc
@@ -39,9 +39,9 @@
     ElementResolveContext context(*element);
     SelectorFilter filter;
     MatchResult result;
-    auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+    auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
     ElementRuleCollector collector(context, StyleRecalcContext(), filter,
-                                   result, style, InsideLink(element));
+                                   result, style.get(), InsideLink(element));
 
     String rule = selector + " { color: green }";
     auto* style_rule =
diff --git a/third_party/blink/renderer/core/css/font_face.cc b/third_party/blink/renderer/core/css/font_face.cc
index 5926e6c..5b6a853a 100644
--- a/third_party/blink/renderer/core/css/font_face.cc
+++ b/third_party/blink/renderer/core/css/font_face.cc
@@ -34,6 +34,7 @@
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_array_buffer_or_array_buffer_view.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_font_face_descriptors.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview_string.h"
 #include "third_party/blink/renderer/core/css/binary_data_font_face_source.h"
 #include "third_party/blink/renderer/core/css/css_font_face.h"
 #include "third_party/blink/renderer/core/css/css_font_face_src_value.h"
@@ -122,6 +123,31 @@
 
 }  // namespace
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+FontFace* FontFace::Create(
+    ExecutionContext* execution_context,
+    const AtomicString& family,
+    const V8UnionArrayBufferOrArrayBufferViewOrString* source,
+    const FontFaceDescriptors* descriptors) {
+  DCHECK(source);
+
+  switch (source->GetContentType()) {
+    case V8UnionArrayBufferOrArrayBufferViewOrString::ContentType::kArrayBuffer:
+      return Create(execution_context, family, source->GetAsArrayBuffer(),
+                    descriptors);
+    case V8UnionArrayBufferOrArrayBufferViewOrString::ContentType::
+        kArrayBufferView:
+      return Create(execution_context, family,
+                    source->GetAsArrayBufferView().Get(), descriptors);
+    case V8UnionArrayBufferOrArrayBufferViewOrString::ContentType::kString:
+      return Create(execution_context, family, source->GetAsString(),
+                    descriptors);
+  }
+
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 FontFace* FontFace::Create(ExecutionContext* context,
                            const AtomicString& family,
                            StringOrArrayBufferOrArrayBufferView& source,
@@ -137,6 +163,7 @@
   NOTREACHED();
   return nullptr;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 FontFace* FontFace::Create(ExecutionContext* context,
                            const AtomicString& family,
diff --git a/third_party/blink/renderer/core/css/font_face.h b/third_party/blink/renderer/core/css/font_face.h
index 0c51930..a307e7b 100644
--- a/third_party/blink/renderer/core/css/font_face.h
+++ b/third_party/blink/renderer/core/css/font_face.h
@@ -46,6 +46,7 @@
 namespace blink {
 
 class CSSFontFace;
+class CSSPropertyValueSet;
 class CSSValue;
 class DOMArrayBuffer;
 class DOMArrayBufferView;
@@ -53,8 +54,8 @@
 class ExceptionState;
 class FontFaceDescriptors;
 class StringOrArrayBufferOrArrayBufferView;
-class CSSPropertyValueSet;
 class StyleRuleFontFace;
+class V8UnionArrayBufferOrArrayBufferViewOrString;
 struct FontMetricsOverride;
 
 class CORE_EXPORT FontFace : public ScriptWrappable,
@@ -65,10 +66,18 @@
  public:
   enum LoadStatusType { kUnloaded, kLoading, kLoaded, kError };
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static FontFace* Create(
+      ExecutionContext* execution_context,
+      const AtomicString& family,
+      const V8UnionArrayBufferOrArrayBufferViewOrString* source,
+      const FontFaceDescriptors* descriptors);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static FontFace* Create(ExecutionContext*,
                           const AtomicString& family,
                           StringOrArrayBufferOrArrayBufferView&,
                           const FontFaceDescriptors*);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static FontFace* Create(Document*, const StyleRuleFontFace*);
 
   explicit FontFace(ExecutionContext*);
diff --git a/third_party/blink/renderer/core/css/font_face_set_document.cc b/third_party/blink/renderer/core/css/font_face_set_document.cc
index 2aba9e3c..8cc0a73c 100644
--- a/third_party/blink/renderer/core/css/font_face_set_document.cc
+++ b/third_party/blink/renderer/core/css/font_face_set_document.cc
@@ -178,7 +178,7 @@
     return true;
   }
 
-  ComputedStyle* style =
+  scoped_refptr<ComputedStyle> style =
       GetDocument()->GetStyleResolver().CreateComputedStyle();
 
   FontFamily font_family;
@@ -192,7 +192,7 @@
   style->SetFontDescription(default_font_description);
 
   GetDocument()->GetStyleEngine().ComputeFont(*GetDocument()->documentElement(),
-                                              style, *parsed_style);
+                                              style.get(), *parsed_style);
 
   font = style->GetFont();
 
diff --git a/third_party/blink/renderer/core/css/properties/css_property_test.cc b/third_party/blink/renderer/core/css/properties/css_property_test.cc
index d1c5a9d5..196be04 100644
--- a/third_party/blink/renderer/core/css/properties/css_property_test.cc
+++ b/third_party/blink/renderer/core/css/properties/css_property_test.cc
@@ -29,8 +29,9 @@
     return &set->PropertyAt(0).Value();
   }
 
-  ComputedStyle* ComputedStyleWithValue(const CSSProperty& property,
-                                        const CSSValue& value) {
+  scoped_refptr<ComputedStyle> ComputedStyleWithValue(
+      const CSSProperty& property,
+      const CSSValue& value) {
     StyleResolverState state(GetDocument(), *GetDocument().body());
     state.SetStyle(GetDocument().GetStyleResolver().CreateComputedStyle());
 
@@ -79,7 +80,7 @@
 }
 
 TEST_F(CSSPropertyTest, VisitedPropertiesCanParseValues) {
-  ComputedStyle* initial_style =
+  scoped_refptr<ComputedStyle> initial_style =
       GetDocument().GetStyleResolver().CreateComputedStyle();
 
   // Count the number of 'visited' properties seen.
diff --git a/third_party/blink/renderer/core/css/resolver/element_resolve_context.h b/third_party/blink/renderer/core/css/resolver/element_resolve_context.h
index dc387b56..43503c9 100644
--- a/third_party/blink/renderer/core/css/resolver/element_resolve_context.h
+++ b/third_party/blink/renderer/core/css/resolver/element_resolve_context.h
@@ -43,7 +43,9 @@
   Element& GetElement() const { return *element_; }
   const ContainerNode* ParentNode() const { return parent_node_; }
   const ContainerNode* LayoutParent() const { return layout_parent_; }
-  const ComputedStyle* RootElementStyle() const { return root_element_style_; }
+  const ComputedStyle* RootElementStyle() const {
+    return root_element_style_.get();
+  }
   const ComputedStyle* ParentStyle() const {
     return ParentNode() && ParentNode()->IsElementNode()
                ? ParentNode()->GetComputedStyle()
@@ -58,7 +60,7 @@
   Element* element_;
   ContainerNode* parent_node_;
   ContainerNode* layout_parent_;
-  const ComputedStyle* root_element_style_ = nullptr;
+  scoped_refptr<const ComputedStyle> root_element_style_;
   EInsideLink element_link_state_;
 };
 
diff --git a/third_party/blink/renderer/core/css/resolver/font_builder_test.cc b/third_party/blink/renderer/core/css/resolver/font_builder_test.cc
index 1573c83f..3a4dd40 100644
--- a/third_party/blink/renderer/core/css/resolver/font_builder_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/font_builder_test.cc
@@ -45,12 +45,12 @@
                                 public testing::TestWithParam<FunctionPair> {};
 
 TEST_F(FontBuilderInitTest, InitialFontSizeNotScaled) {
-  ComputedStyle* initial =
+  scoped_refptr<ComputedStyle> initial =
       GetDocument().GetStyleResolver().CreateComputedStyle();
 
   FontBuilder builder(&GetDocument());
   builder.SetInitial(1.0f);  // FIXME: Remove unused param.
-  builder.CreateFont(*initial, initial);
+  builder.CreateFont(*initial, initial.get());
 
   EXPECT_EQ(16.0f, initial->GetFontDescription().ComputedSize());
 }
@@ -69,16 +69,17 @@
   FontDescription parent_description;
   funcs.set_base_value(parent_description);
 
-  ComputedStyle* parent_style =
+  scoped_refptr<ComputedStyle> parent_style =
       GetDocument().GetStyleResolver().CreateComputedStyle();
   parent_style->SetFontDescription(parent_description);
 
-  ComputedStyle* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style =
+      GetDocument().GetStyleResolver().CreateComputedStyle();
   style->InheritFrom(*parent_style);
 
   FontBuilder font_builder(&GetDocument());
   funcs.set_value(font_builder);
-  font_builder.CreateFont(*style, parent_style);
+  font_builder.CreateFont(*style, parent_style.get());
 
   FontDescription output_description = style->GetFontDescription();
 
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
index 51c2ffc0..bd9bdfa 100644
--- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
+++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
@@ -98,11 +98,6 @@
   return true;
 }
 
-void CachedMatchedProperties::Trace(Visitor* visitor) const {
-  visitor->Trace(computed_style);
-  visitor->Trace(parent_computed_style);
-}
-
 MatchedPropertiesCache::MatchedPropertiesCache() = default;
 
 MatchedPropertiesCache::Key::Key(const MatchResult& result)
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
index 848453cd..9a29b5bf 100644
--- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
+++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h
@@ -45,8 +45,8 @@
   Vector<UntracedMember<CSSPropertyValueSet>> matched_properties;
   Vector<MatchedProperties::Data> matched_properties_types;
 
-  Member<ComputedStyle> computed_style;
-  Member<ComputedStyle> parent_computed_style;
+  scoped_refptr<ComputedStyle> computed_style;
+  scoped_refptr<ComputedStyle> parent_computed_style;
 
   void Set(const ComputedStyle&,
            const ComputedStyle& parent_style,
@@ -55,7 +55,7 @@
 
   bool DependenciesEqual(const StyleResolverState&);
 
-  void Trace(Visitor*) const;
+  void Trace(Visitor*) const {}
 
   bool operator==(const MatchedPropertiesVector& properties);
   bool operator!=(const MatchedPropertiesVector& properties);
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc b/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc
index 4e263f58..4c1f4dc3 100644
--- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache_test.cc
@@ -79,7 +79,7 @@
 
 class MatchedPropertiesCacheTest : public PageTestBase {
  public:
-  ComputedStyle* CreateStyle() {
+  scoped_refptr<ComputedStyle> CreateStyle() {
     return GetDocument().GetStyleResolver().InitialStyleForElement();
   }
 };
@@ -108,8 +108,8 @@
   TestCache cache(GetDocument());
   TestKey key("color:red", 1, GetDocument());
 
-  ComputedStyle* style = CreateStyle();
-  ComputedStyle* parent = CreateStyle();
+  auto style = CreateStyle();
+  auto parent = CreateStyle();
 
   EXPECT_FALSE(cache.Find(key, *style, *parent));
 }
@@ -118,8 +118,8 @@
   TestCache cache(GetDocument());
   TestKey key("color:red", 1, GetDocument());
 
-  ComputedStyle* style = CreateStyle();
-  ComputedStyle* parent = CreateStyle();
+  auto style = CreateStyle();
+  auto parent = CreateStyle();
 
   cache.Add(key, *style, *parent);
   EXPECT_TRUE(cache.Find(key, *style, *parent));
@@ -128,8 +128,8 @@
 TEST_F(MatchedPropertiesCacheTest, HitOnlyForAddedEntry) {
   TestCache cache(GetDocument());
 
-  ComputedStyle* style = CreateStyle();
-  ComputedStyle* parent = CreateStyle();
+  auto style = CreateStyle();
+  auto parent = CreateStyle();
 
   TestKey key1("color:red", 1, GetDocument());
   TestKey key2("display:block", 2, GetDocument());
@@ -143,9 +143,9 @@
 TEST_F(MatchedPropertiesCacheTest, EnsuredInDisplayNone) {
   TestCache cache(GetDocument());
 
-  ComputedStyle* style = CreateStyle();
-  ComputedStyle* parent = CreateStyle();
-  ComputedStyle* ensured_parent = CreateStyle();
+  auto style = CreateStyle();
+  auto parent = CreateStyle();
+  auto ensured_parent = CreateStyle();
   ensured_parent->SetIsEnsuredInDisplayNone();
 
   TestKey key1("display:block", 1, GetDocument());
@@ -162,9 +162,9 @@
 TEST_F(MatchedPropertiesCacheTest, EnsuredOutsideFlatTree) {
   TestCache cache(GetDocument());
 
-  ComputedStyle* style = CreateStyle();
-  ComputedStyle* parent = CreateStyle();
-  ComputedStyle* ensured_style = CreateStyle();
+  auto style = CreateStyle();
+  auto parent = CreateStyle();
+  auto ensured_style = CreateStyle();
   ensured_style->SetIsEnsuredOutsideFlatTree();
 
   TestKey key1("display:block", 1, GetDocument());
@@ -181,10 +181,10 @@
 TEST_F(MatchedPropertiesCacheTest, EnsuredOutsideFlatTreeAndDisplayNone) {
   TestCache cache(GetDocument());
 
-  ComputedStyle* parent = CreateStyle();
-  ComputedStyle* parent_none = CreateStyle();
-  ComputedStyle* style = CreateStyle();
-  ComputedStyle* style_flat = CreateStyle();
+  auto parent = CreateStyle();
+  auto parent_none = CreateStyle();
+  auto style = CreateStyle();
+  auto style_flat = CreateStyle();
   parent_none->SetIsEnsuredInDisplayNone();
   style_flat->SetIsEnsuredOutsideFlatTree();
 
@@ -200,10 +200,10 @@
 TEST_F(MatchedPropertiesCacheTest, WritingModeDependency) {
   TestCache cache(GetDocument());
 
-  auto* parent_a = CreateStyle();
-  auto* parent_b = CreateStyle();
-  auto* style_a = CreateStyle();
-  auto* style_b = CreateStyle();
+  auto parent_a = CreateStyle();
+  auto parent_b = CreateStyle();
+  auto style_a = CreateStyle();
+  auto style_b = CreateStyle();
   parent_a->SetWritingMode(WritingMode::kHorizontalTb);
   parent_b->SetWritingMode(WritingMode::kVerticalRl);
 
@@ -218,10 +218,10 @@
 TEST_F(MatchedPropertiesCacheTest, DirectionDependency) {
   TestCache cache(GetDocument());
 
-  auto* parent_a = CreateStyle();
-  auto* parent_b = CreateStyle();
-  auto* style_a = CreateStyle();
-  auto* style_b = CreateStyle();
+  auto parent_a = CreateStyle();
+  auto parent_b = CreateStyle();
+  auto style_a = CreateStyle();
+  auto style_b = CreateStyle();
   parent_a->SetDirection(TextDirection::kLtr);
   parent_b->SetDirection(TextDirection::kRtl);
 
@@ -236,10 +236,10 @@
 TEST_F(MatchedPropertiesCacheTest, VariableDependency) {
   TestCache cache(GetDocument());
 
-  auto* parent_a = CreateStyle();
-  auto* parent_b = CreateStyle();
-  auto* style_a = CreateStyle();
-  auto* style_b = CreateStyle();
+  auto parent_a = CreateStyle();
+  auto parent_b = CreateStyle();
+  auto style_a = CreateStyle();
+  auto style_b = CreateStyle();
   parent_a->SetVariableData("--x", CreateVariableData("1px"), true);
   parent_b->SetVariableData("--x", CreateVariableData("2px"), true);
   style_a->SetHasVariableReferenceFromNonInheritedProperty();
@@ -256,10 +256,10 @@
 TEST_F(MatchedPropertiesCacheTest, VariableDependencyNoVars) {
   TestCache cache(GetDocument());
 
-  auto* parent_a = CreateStyle();
-  auto* parent_b = CreateStyle();
-  auto* style_a = CreateStyle();
-  auto* style_b = CreateStyle();
+  auto parent_a = CreateStyle();
+  auto parent_b = CreateStyle();
+  auto style_a = CreateStyle();
+  auto style_b = CreateStyle();
   style_a->SetHasVariableReferenceFromNonInheritedProperty();
   style_b->SetHasVariableReferenceFromNonInheritedProperty();
 
@@ -275,10 +275,10 @@
 TEST_F(MatchedPropertiesCacheTest, NoVariableDependency) {
   TestCache cache(GetDocument());
 
-  auto* parent_a = CreateStyle();
-  auto* parent_b = CreateStyle();
-  auto* style_a = CreateStyle();
-  auto* style_b = CreateStyle();
+  auto parent_a = CreateStyle();
+  auto parent_b = CreateStyle();
+  auto style_a = CreateStyle();
+  auto style_b = CreateStyle();
   parent_a->SetVariableData("--x", CreateVariableData("1px"), true);
   parent_b->SetVariableData("--x", CreateVariableData("2px"), true);
 
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_test.cc b/third_party/blink/renderer/core/css/resolver/style_builder_test.cc
index e8977d9..5983d83 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_test.cc
@@ -32,15 +32,15 @@
 
   for (const CSSProperty* property : properties) {
     for (const CSSValue* value : values) {
-      auto* parent_style =
+      auto parent_style =
           GetDocument().GetStyleResolver().CreateComputedStyle();
-      auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+      auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
       // This test assumes that initial 'writing-mode' is not 'vertical-lr'.
       ASSERT_NE(WritingMode::kVerticalLr, style->GetWritingMode());
       style->SetWritingMode(WritingMode::kVerticalLr);
 
       StyleResolverState state(GetDocument(), *GetDocument().body(),
-                               StyleRequest(parent_style));
+                               StyleRequest(parent_style.get()));
       state.SetStyle(style);
 
       ASSERT_FALSE(state.GetFontBuilder().FontDirty());
@@ -65,15 +65,15 @@
 
   for (const CSSProperty* property : properties) {
     for (const CSSValue* value : values) {
-      auto* parent_style =
+      auto parent_style =
           GetDocument().GetStyleResolver().CreateComputedStyle();
-      auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+      auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
       // This test assumes that initial 'text-orientation' is not 'upright'.
       ASSERT_NE(ETextOrientation::kUpright, style->GetTextOrientation());
       style->SetTextOrientation(ETextOrientation::kUpright);
 
       StyleResolverState state(GetDocument(), *GetDocument().body(),
-                               StyleRequest(parent_style));
+                               StyleRequest(parent_style.get()));
       state.SetStyle(style);
 
       ASSERT_FALSE(state.GetFontBuilder().FontDirty());
@@ -85,10 +85,10 @@
 }
 
 TEST_F(StyleBuilderTest, HasExplicitInheritance) {
-  auto* parent_style = GetDocument().GetStyleResolver().CreateComputedStyle();
-  auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  auto parent_style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
   StyleResolverState state(GetDocument(), *GetDocument().body(),
-                           StyleRequest(parent_style));
+                           StyleRequest(parent_style.get()));
   state.SetStyle(style);
   EXPECT_FALSE(style->HasExplicitInheritance());
 
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
index aff2928..d9ccf4fa4 100644
--- a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
@@ -85,12 +85,12 @@
       : state_(document, target ? *target : *document.body()),
         cascade_(InitState(state_)) {}
 
-  ComputedStyle* TakeStyle() { return state_.TakeStyle(); }
+  scoped_refptr<ComputedStyle> TakeStyle() { return state_.TakeStyle(); }
 
   StyleResolverState& State() { return state_; }
   StyleCascade& InnerCascade() { return cascade_; }
 
-  void InheritFrom(ComputedStyle* parent) {
+  void InheritFrom(scoped_refptr<ComputedStyle> parent) {
     state_.SetParentStyle(parent);
     state_.StyleRef().InheritFrom(*parent);
   }
@@ -214,7 +214,7 @@
     return state;
   }
 
-  static ComputedStyle* InitialStyle(Document& document) {
+  static scoped_refptr<ComputedStyle> InitialStyle(Document& document) {
     return document.GetStyleResolver().InitialStyleForElement();
   }
 
@@ -2534,7 +2534,7 @@
   cascade.Apply();
   EXPECT_EQ("rgb(150, 150, 150)", cascade.ComputedValue("background-color"));
 
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
 
   style->SetInsideLink(EInsideLink::kInsideVisitedLink);
   EXPECT_EQ(Color(255, 0, 0),
@@ -2562,7 +2562,7 @@
   cascade.Apply();
   EXPECT_EQ("rgb(150, 150, 150)", cascade.ComputedValue("color"));
 
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
 
   style->SetInsideLink(EInsideLink::kInsideVisitedLink);
   EXPECT_EQ(Color(150, 150, 150),
@@ -2912,7 +2912,7 @@
   cascade.Add("--x", "1px");
   cascade.Add("width", "var(--x)");
   cascade.Apply();
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
   EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty());
 }
 
@@ -2921,7 +2921,7 @@
   cascade.Add("--x", "1px");
   cascade.Add("margin", "var(--x)");
   cascade.Apply();
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
   EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty());
 }
 
@@ -2929,7 +2929,7 @@
   TestCascade cascade(GetDocument());
   cascade.Add("width", "var(--x)");
   cascade.Apply();
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
   EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty());
 }
 
@@ -2937,7 +2937,7 @@
   TestCascade cascade(GetDocument());
   cascade.Add("margin", "var(--x)");
   cascade.Apply();
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
   EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty());
 }
 
@@ -2945,7 +2945,7 @@
   TestCascade cascade(GetDocument());
   cascade.Add("color", "var(--x)");
   cascade.Apply();
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
   EXPECT_FALSE(style->HasVariableReferenceFromNonInheritedProperty());
 }
 
@@ -2953,7 +2953,7 @@
   TestCascade cascade(GetDocument());
   cascade.Add("width", "1px");
   cascade.Apply();
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
   EXPECT_FALSE(style->HasVariableReferenceFromNonInheritedProperty());
 }
 
@@ -3051,7 +3051,7 @@
   cascade.Add("border-block-start-color", "red", Origin::kUserAgent);
   cascade.Add("border-block-start-color", "green", Origin::kAuthor);
   cascade.Apply();
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
   EXPECT_TRUE(style->HasAuthorBorder());
 }
 
@@ -3063,7 +3063,7 @@
   cascade.Add("background-clip", "padding-box", Origin::kUser);
   cascade.Add("border-right-color", "green", Origin::kUser);
   cascade.Apply();
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
   EXPECT_FALSE(style->HasAuthorBackground());
   EXPECT_FALSE(style->HasAuthorBorder());
 }
@@ -3074,7 +3074,7 @@
   cascade.Add("background-color", "red", Origin::kUserAgent);
   cascade.Add("background-color", "revert", Origin::kAuthor);
   cascade.Apply();
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
   EXPECT_FALSE(style->HasAuthorBackground());
 }
 
@@ -3084,7 +3084,7 @@
   cascade.Add("border-top-color", "red", Origin::kUserAgent);
   cascade.Add("border-top-color", "revert", Origin::kAuthor);
   cascade.Apply();
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
   EXPECT_FALSE(style->HasAuthorBorder());
 }
 
@@ -3094,7 +3094,7 @@
   cascade.Add("border-block-start-color", "red", Origin::kUserAgent);
   cascade.Add("border-block-start-color", "revert", Origin::kAuthor);
   cascade.Apply();
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
   EXPECT_FALSE(style->HasAuthorBorder());
 }
 
@@ -3279,7 +3279,7 @@
   cascade.Add("display:block");
   cascade.Apply();  // Should not affect 'color'.
 
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
 
   style->SetInsideLink(EInsideLink::kInsideVisitedLink);
   EXPECT_EQ(Color(255, 0, 0),
@@ -3307,7 +3307,7 @@
 
   cascade.Apply();
 
-  ComputedStyle* style = cascade.TakeStyle();
+  auto style = cascade.TakeStyle();
 
   style->SetInsideLink(EInsideLink::kInsideVisitedLink);
   EXPECT_EQ(Color::kWhite, style->VisitedDependentColor(GetCSSPropertyColor()));
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index ef45cbf..2190fb8 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -253,7 +253,7 @@
 StyleResolver::~StyleResolver() = default;
 
 void StyleResolver::Dispose() {
-  initial_style_.Clear();
+  initial_style_.reset();
   matched_properties_cache_.Clear();
 }
 
@@ -662,8 +662,8 @@
                              : element.GetTreeScope());
 }
 
-ComputedStyle* StyleResolver::StyleForViewport() {
-  ComputedStyle* viewport_style = InitialStyleForElement();
+scoped_refptr<ComputedStyle> StyleResolver::StyleForViewport() {
+  scoped_refptr<ComputedStyle> viewport_style = InitialStyleForElement();
 
   viewport_style->SetZIndex(0);
   viewport_style->SetIsStackingContextWithoutContainment(true);
@@ -737,7 +737,7 @@
   }
 }
 
-ComputedStyle* StyleResolver::ResolveStyle(
+scoped_refptr<ComputedStyle> StyleResolver::ResolveStyle(
     Element* element,
     const StyleRecalcContext& style_recalc_context,
     const StyleRequest& style_request) {
@@ -810,7 +810,7 @@
     const StyleRequest& style_request,
     StyleResolverState& state) {
   if (AllowsInheritance(style_request, state.ParentStyle())) {
-    ComputedStyle* style = CreateComputedStyle();
+    scoped_refptr<ComputedStyle> style = CreateComputedStyle();
     style->InheritFrom(
         *state.ParentStyle(),
         (!style_request.IsPseudoStyleRequest() && IsAtShadowBoundary(&element))
@@ -1020,17 +1020,17 @@
                                                 offset);
 }
 
-const ComputedStyle* StyleResolver::StyleForPage(
+scoped_refptr<const ComputedStyle> StyleResolver::StyleForPage(
     uint32_t page_index,
     const AtomicString& page_name) {
-  const ComputedStyle* initial_style = InitialStyleForElement();
+  scoped_refptr<const ComputedStyle> initial_style = InitialStyleForElement();
   if (!GetDocument().documentElement())
     return initial_style;
 
   StyleResolverState state(GetDocument(), *GetDocument().documentElement(),
-                           StyleRequest(initial_style));
+                           StyleRequest(initial_style.get()));
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   const ComputedStyle* root_element_style =
       state.RootElementStyle() ? state.RootElementStyle()
                                : GetDocument().GetComputedStyle();
@@ -1060,14 +1060,14 @@
   return *initial_style_;
 }
 
-ComputedStyle* StyleResolver::CreateComputedStyle() const {
+scoped_refptr<ComputedStyle> StyleResolver::CreateComputedStyle() const {
   return ComputedStyle::Clone(*initial_style_);
 }
 
-ComputedStyle* StyleResolver::InitialStyleForElement() const {
+scoped_refptr<ComputedStyle> StyleResolver::InitialStyleForElement() const {
   const LocalFrame* frame = GetDocument().GetFrame();
 
-  ComputedStyle* initial_style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> initial_style = CreateComputedStyle();
 
   initial_style->SetRtlOrdering(
       GetDocument().VisuallyOrdered() ? EOrder::kVisual : EOrder::kLogical);
@@ -1097,7 +1097,8 @@
   return initial_style;
 }
 
-const ComputedStyle* StyleResolver::StyleForText(Text* text_node) {
+scoped_refptr<const ComputedStyle> StyleResolver::StyleForText(
+    Text* text_node) {
   DCHECK(text_node);
   if (Node* parent_node = LayoutTreeBuilderTraversal::Parent(*text_node)) {
     const ComputedStyle* style = parent_node->GetComputedStyle();
@@ -1496,7 +1497,7 @@
                                                    *state.Style());
 }
 
-ComputedStyle* StyleResolver::StyleForInterpolations(
+scoped_refptr<ComputedStyle> StyleResolver::StyleForInterpolations(
     Element& element,
     ActiveInterpolationsMap& interpolations) {
   StyleRequest style_request;
@@ -1519,7 +1520,8 @@
   cascade.Apply();
 }
 
-ComputedStyle* StyleResolver::BeforeChangeStyleForTransitionUpdate(
+scoped_refptr<ComputedStyle>
+StyleResolver::BeforeChangeStyleForTransitionUpdate(
     Element& element,
     const ComputedStyle& base_style,
     ActiveInterpolationsMap& transition_interpolations) {
@@ -1642,7 +1644,6 @@
   visitor->Trace(matched_properties_cache_);
   visitor->Trace(selector_filter_);
   visitor->Trace(document_);
-  visitor->Trace(initial_style_);
   visitor->Trace(tracker_);
 }
 
@@ -1656,17 +1657,18 @@
          state.Style()->ForcedColorAdjust() != EForcedColorAdjust::kNone;
 }
 
-ComputedStyle* StyleResolver::CreateAnonymousStyleWithDisplay(
+scoped_refptr<ComputedStyle> StyleResolver::CreateAnonymousStyleWithDisplay(
     const ComputedStyle& parent_style,
     EDisplay display) {
-  ComputedStyle* new_style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> new_style = CreateComputedStyle();
   new_style->InheritFrom(parent_style);
   new_style->SetUnicodeBidi(parent_style.GetUnicodeBidi());
   new_style->SetDisplay(display);
   return new_style;
 }
 
-ComputedStyle* StyleResolver::CreateInheritedDisplayContentsStyleIfNeeded(
+scoped_refptr<ComputedStyle>
+StyleResolver::CreateInheritedDisplayContentsStyleIfNeeded(
     const ComputedStyle& parent_style,
     const ComputedStyle& layout_parent_style) {
   if (parent_style.InheritedEqual(layout_parent_style))
@@ -1727,7 +1729,8 @@
 
   const ComputedStyle& viewport_style =
       GetDocument().GetLayoutView()->StyleRef();
-  ComputedStyle* new_viewport_style = ComputedStyle::Clone(viewport_style);
+  scoped_refptr<ComputedStyle> new_viewport_style =
+      ComputedStyle::Clone(viewport_style);
   bool changed = false;
   bool update_scrollbar_style = false;
 
@@ -1889,7 +1892,7 @@
   }
 
   changed |= PropagateScrollSnapStyleToViewport(
-      GetDocument(), document_element_style, new_viewport_style);
+      GetDocument(), document_element_style, new_viewport_style.get());
 
   if (changed) {
     new_viewport_style->UpdateFontOrientation();
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.h b/third_party/blink/renderer/core/css/resolver/style_resolver.h
index 0f287669..7eadad1 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.h
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.h
@@ -64,20 +64,21 @@
   ~StyleResolver();
   void Dispose();
 
-  ComputedStyle* ResolveStyle(Element*,
-                              const StyleRecalcContext&,
-                              const StyleRequest& = StyleRequest());
+  scoped_refptr<ComputedStyle> ResolveStyle(
+      Element*,
+      const StyleRecalcContext&,
+      const StyleRequest& = StyleRequest());
 
   // Return a reference to the initial style singleton.
   const ComputedStyle& InitialStyle() const;
 
   // Create a new ComputedStyle copy based on the initial style singleton.
-  ComputedStyle* CreateComputedStyle() const;
+  scoped_refptr<ComputedStyle> CreateComputedStyle() const;
 
   // Create a ComputedStyle for initial styles to be used as the basis for the
   // root element style. In addition to initial values things like zoom, font,
   // forced color mode etc. is set.
-  ComputedStyle* InitialStyleForElement() const;
+  scoped_refptr<ComputedStyle> InitialStyleForElement() const;
 
   static CompositorKeyframeValue* CreateCompositorKeyframeValueSnapshot(
       Element&,
@@ -87,23 +88,24 @@
       const CSSValue*,
       double offset);
 
-  const ComputedStyle* StyleForPage(uint32_t page_index,
-                                    const AtomicString& page_name);
-  const ComputedStyle* StyleForText(Text*);
-  ComputedStyle* StyleForViewport();
+  scoped_refptr<const ComputedStyle> StyleForPage(
+      uint32_t page_index,
+      const AtomicString& page_name);
+  scoped_refptr<const ComputedStyle> StyleForText(Text*);
+  scoped_refptr<ComputedStyle> StyleForViewport();
 
   // Propagate computed values from the root or body element to the viewport
   // when specified to do so.
   void PropagateStyleToViewport();
 
   // Create ComputedStyle for anonymous boxes.
-  ComputedStyle* CreateAnonymousStyleWithDisplay(
+  scoped_refptr<ComputedStyle> CreateAnonymousStyleWithDisplay(
       const ComputedStyle& parent_style,
       EDisplay);
 
   // Create ComputedStyle for anonymous wrappers between text boxes and
   // display:contents elements.
-  ComputedStyle* CreateInheritedDisplayContentsStyleIfNeeded(
+  scoped_refptr<ComputedStyle> CreateInheritedDisplayContentsStyleIfNeeded(
       const ComputedStyle& parent_style,
       const ComputedStyle& layout_parent_style);
 
@@ -159,15 +161,16 @@
                                       const CSSPropertyName&,
                                       const CSSValue&);
 
-  ComputedStyle* StyleForInterpolations(Element& element,
-                                        ActiveInterpolationsMap& animations);
+  scoped_refptr<ComputedStyle> StyleForInterpolations(
+      Element& element,
+      ActiveInterpolationsMap& animations);
 
   // When updating transitions, the "before change style" is the style from
   // the previous style change with the addition of all declarative animations
   // ticked to the current time. Ticking the animations is required to ensure
   // smooth retargeting of transitions.
   // https://drafts.csswg.org/css-transitions-1/#before-change-style
-  ComputedStyle* BeforeChangeStyleForTransitionUpdate(
+  scoped_refptr<ComputedStyle> BeforeChangeStyleForTransitionUpdate(
       Element& element,
       const ComputedStyle& base_style,
       ActiveInterpolationsMap& transition_interpolations);
@@ -267,7 +270,7 @@
 
   MatchedPropertiesCache matched_properties_cache_;
   Member<Document> document_;
-  Member<const ComputedStyle> initial_style_;
+  scoped_refptr<const ComputedStyle> initial_style_;
   SelectorFilter selector_filter_;
 
   Member<StyleRuleUsageTracker> tracker_;
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
index 220f234..04d8b796 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
@@ -82,15 +82,15 @@
   animation_update_.Clear();
 }
 
-void StyleResolverState::SetStyle(ComputedStyle* style) {
+void StyleResolverState::SetStyle(scoped_refptr<ComputedStyle> style) {
   // FIXME: Improve RAII of StyleResolverState to remove this function.
   style_ = std::move(style);
   css_to_length_conversion_data_ = CSSToLengthConversionData(
-      style_, RootElementStyle(), GetDocument().GetLayoutView(),
+      style_.get(), RootElementStyle(), GetDocument().GetLayoutView(),
       style_->EffectiveZoom());
 }
 
-ComputedStyle* StyleResolverState::TakeStyle() {
+scoped_refptr<ComputedStyle> StyleResolverState::TakeStyle() {
   if (had_no_matched_properties_ &&
       pseudo_request_type_ == StyleRequest::kForRenderer) {
     return nullptr;
@@ -119,13 +119,14 @@
   return UnzoomedLengthConversionData(Style());
 }
 
-void StyleResolverState::SetParentStyle(const ComputedStyle* parent_style) {
-  parent_style_ = parent_style;
+void StyleResolverState::SetParentStyle(
+    scoped_refptr<const ComputedStyle> parent_style) {
+  parent_style_ = std::move(parent_style);
 }
 
 void StyleResolverState::SetLayoutParentStyle(
-    const ComputedStyle* parent_style) {
-  layout_parent_style_ = parent_style;
+    scoped_refptr<const ComputedStyle> parent_style) {
+  layout_parent_style_ = std::move(parent_style);
 }
 
 void StyleResolverState::LoadPendingResources() {
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
index 0605a46..b0379a7 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h
@@ -83,14 +83,14 @@
     return element_context_;
   }
 
-  void SetStyle(ComputedStyle*);
-  const ComputedStyle* Style() const { return style_; }
-  ComputedStyle* Style() { return style_; }
+  void SetStyle(scoped_refptr<ComputedStyle>);
+  const ComputedStyle* Style() const { return style_.get(); }
+  ComputedStyle* Style() { return style_.get(); }
   ComputedStyle& StyleRef() {
     DCHECK(style_);
     return *style_;
   }
-  ComputedStyle* TakeStyle();
+  scoped_refptr<ComputedStyle> TakeStyle();
 
   const CSSToLengthConversionData& CssToLengthConversionData() const {
     return css_to_length_conversion_data_;
@@ -113,12 +113,12 @@
 
   Element* GetAnimatingElement() const;
 
-  void SetParentStyle(const ComputedStyle*);
-  const ComputedStyle* ParentStyle() const { return parent_style_; }
+  void SetParentStyle(scoped_refptr<const ComputedStyle>);
+  const ComputedStyle* ParentStyle() const { return parent_style_.get(); }
 
-  void SetLayoutParentStyle(const ComputedStyle*);
+  void SetLayoutParentStyle(scoped_refptr<const ComputedStyle>);
   const ComputedStyle* LayoutParentStyle() const {
-    return layout_parent_style_;
+    return layout_parent_style_.get();
   }
 
   ElementStyleResources& GetElementStyleResources() {
@@ -170,17 +170,17 @@
   Document* document_;
 
   // style_ is the primary output for each element's style resolve.
-  ComputedStyle* style_ = nullptr;
+  scoped_refptr<ComputedStyle> style_;
 
   CSSToLengthConversionData css_to_length_conversion_data_;
 
   // parent_style_ is not always just ElementResolveContext::ParentStyle(),
   // so we keep it separate.
-  const ComputedStyle* parent_style_;
+  scoped_refptr<const ComputedStyle> parent_style_;
   // This will almost-always be the same that parent_style_, except in the
   // presence of display: contents. This is the style against which we have to
   // do adjustment.
-  const ComputedStyle* layout_parent_style_;
+  scoped_refptr<const ComputedStyle> layout_parent_style_;
 
   CSSAnimationUpdate animation_update_;
   StyleRequest::RequestType pseudo_request_type_;
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
index c571cdf1..261b0ba 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
 #include "third_party/blink/renderer/core/animation/animation_test_helpers.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
 #include "third_party/blink/renderer/core/animation/element_animations.h"
@@ -31,9 +32,9 @@
 
 class StyleResolverTest : public PageTestBase {
  protected:
-  ComputedStyle* StyleForId(AtomicString id) {
+  scoped_refptr<ComputedStyle> StyleForId(AtomicString id) {
     Element* element = GetDocument().getElementById(id);
-    auto* style = GetStyleEngine().GetStyleResolver().ResolveStyle(
+    auto style = GetStyleEngine().GetStyleResolver().ResolveStyle(
         element, StyleRecalcContext());
     DCHECK(style);
     return style;
@@ -274,7 +275,12 @@
   EXPECT_EQ("20px", ComputedValue("font-size", *StyleForId("target")));
 
   // Bump the animation time to ensure a transition reversal.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  transition->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(50),
+                             ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   transition->setCurrentTime(CSSNumberish::FromDouble(50));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   transition->pause();
   UpdateAllLifecyclePhasesForTest();
   const String before_reversal_font_size =
@@ -318,7 +324,12 @@
   EXPECT_TRUE(transition);
 
   // Advance to the midpoint of the transition.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  transition->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(500),
+                             ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   transition->setCurrentTime(CSSNumberish::FromDouble(500));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   UpdateAllLifecyclePhasesForTest();
   EXPECT_EQ("rgb(0, 64, 0)", ComputedValue("color", *StyleForId("target")));
   EXPECT_TRUE(element_animations->BaseComputedStyle());
@@ -357,7 +368,7 @@
 
   div->SetNeedsAnimationStyleRecalc();
   GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
-  ComputedStyle* computed_style = StyleForId("div");
+  auto computed_style = StyleForId("div");
 
   EXPECT_TRUE(computed_style->HasFontRelativeUnits());
   ASSERT_TRUE(div->GetElementAnimations());
@@ -381,9 +392,8 @@
   EXPECT_EQ("50px", ComputedValue("height", *StyleForId("div")));
 
   div->SetNeedsAnimationStyleRecalc();
-
   GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
-  ComputedStyle* computed_style = StyleForId("div");
+  auto computed_style = StyleForId("div");
 
   EXPECT_TRUE(computed_style->HasFontRelativeUnits());
   ASSERT_TRUE(div->GetElementAnimations());
@@ -589,7 +599,7 @@
   )HTML");
 
   GetDocument().GetStyleEngine().UpdateActiveStyle();
-  const ComputedStyle* page_style =
+  scoped_refptr<const ComputedStyle> page_style =
       GetDocument().GetStyleResolver().StyleForPage(0, "");
   ASSERT_TRUE(page_style);
   const CSSValue* computed_value = ComputedStyleUtils::ComputedPropertyValue(
@@ -626,7 +636,7 @@
   StyleRequest target_text_style_request = pseudo_style_request;
   target_text_style_request.pseudo_id = kPseudoIdTargetText;
 
-  ComputedStyle* target_text_style =
+  scoped_refptr<ComputedStyle> target_text_style =
       GetDocument().GetStyleResolver().ResolveStyle(GetDocument().body(),
                                                     StyleRecalcContext(),
                                                     target_text_style_request);
@@ -635,7 +645,7 @@
   StyleRequest selection_style_style_request = pseudo_style_request;
   selection_style_style_request.pseudo_id = kPseudoIdSelection;
 
-  ComputedStyle* selection_style =
+  scoped_refptr<ComputedStyle> selection_style =
       GetDocument().GetStyleResolver().ResolveStyle(
           GetDocument().body(), StyleRecalcContext(),
           selection_style_style_request);
@@ -649,7 +659,8 @@
   ASSERT_TRUE(image);
   EXPECT_TRUE(image->IsPendingImage());
 
-  for (const auto* pseudo_style : {target_text_style, selection_style}) {
+  for (const auto* pseudo_style :
+       {target_text_style.get(), selection_style.get()}) {
     // Check that the color applies.
     EXPECT_EQ(Color(0, 128, 0),
               pseudo_style->VisitedDependentColor(GetCSSPropertyColor()));
diff --git a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc
index 78100ef..59e9698 100644
--- a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc
@@ -246,13 +246,13 @@
   LocalFrameView* view = document_->GetFrame()->View();
   DCHECK(view);
 
-  CSSToLengthConversionData::FontSizes font_sizes(initial_style_,
-                                                  initial_style_);
+  CSSToLengthConversionData::FontSizes font_sizes(initial_style_.get(),
+                                                  initial_style_.get());
   CSSToLengthConversionData::ViewportSize viewport_size(
       view->InitialViewportWidth(), view->InitialViewportHeight());
 
   Length result = primitive_value->ConvertToLength(CSSToLengthConversionData(
-      initial_style_, font_sizes, viewport_size, 1.0f));
+      initial_style_.get(), font_sizes, viewport_size, 1.0f));
 
   if (result.IsFixed() && document_->GetPage()) {
     float scaled_value =
@@ -325,7 +325,6 @@
 void ViewportStyleResolver::Trace(Visitor* visitor) const {
   visitor->Trace(document_);
   visitor->Trace(property_set_);
-  visitor->Trace(initial_style_);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h
index 1d6e7cc..d12a8068 100644
--- a/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h
+++ b/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h
@@ -75,7 +75,7 @@
 
   Member<Document> document_;
   Member<MutableCSSPropertyValueSet> property_set_;
-  Member<ComputedStyle> initial_style_;
+  scoped_refptr<ComputedStyle> initial_style_;
   bool has_viewport_units_ = false;
   UpdateType needs_update_ = kCollectRules;
 };
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
index 71c5494b..ca8c054 100644
--- a/third_party/blink/renderer/core/css/style_engine.cc
+++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -1677,7 +1677,8 @@
   MarkViewportStyleDirty();
 }
 
-void StyleEngine::ApplyVisionDeficiencyStyle(ComputedStyle* layout_view_style) {
+void StyleEngine::ApplyVisionDeficiencyStyle(
+    scoped_refptr<ComputedStyle> layout_view_style) {
   LoadVisionDeficiencyFilter();
   if (vision_deficiency_filter_) {
     FilterOperations ops;
@@ -2372,9 +2373,9 @@
 
   viewport_style_dirty_ = false;
 
-  ComputedStyle* viewport_style = resolver_->StyleForViewport();
+  scoped_refptr<ComputedStyle> viewport_style = resolver_->StyleForViewport();
   if (ComputedStyle::ComputeDifference(
-          viewport_style, GetDocument().GetLayoutView()->Style()) !=
+          viewport_style.get(), GetDocument().GetLayoutView()->Style()) !=
       ComputedStyle::Difference::kEqual) {
     GetDocument().GetLayoutView()->SetStyle(std::move(viewport_style));
   }
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h
index 70adc7b5..9935144d 100644
--- a/third_party/blink/renderer/core/css/style_engine.h
+++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -364,7 +364,8 @@
                                const ActiveStyleSheetVector& new_style_sheets);
 
   void VisionDeficiencyChanged();
-  void ApplyVisionDeficiencyStyle(ComputedStyle* layout_view_style);
+  void ApplyVisionDeficiencyStyle(
+      scoped_refptr<ComputedStyle> layout_view_style);
 
   void CollectMatchingUserRules(ElementRuleCollector&) const;
 
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc
index d51b06b1..ad6fffad 100644
--- a/third_party/blink/renderer/core/css/style_engine_test.cc
+++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -2475,7 +2475,8 @@
   before->SetNeedsAnimationStyleRecalc();
   UpdateAllLifecyclePhases();
 
-  ComputedStyle* base_computed_style = animations->base_computed_style_;
+  scoped_refptr<ComputedStyle> base_computed_style =
+      animations->base_computed_style_;
   EXPECT_TRUE(base_computed_style);
 
   before->SetNeedsAnimationStyleRecalc();
@@ -2562,8 +2563,8 @@
   EXPECT_FALSE(innermost->GetComputedStyle());
 
   inner->EnsureComputedStyle();
-  const ComputedStyle* outer_style = outer->GetComputedStyle();
-  const ComputedStyle* inner_style = inner->GetComputedStyle();
+  scoped_refptr<const ComputedStyle> outer_style = outer->GetComputedStyle();
+  scoped_refptr<const ComputedStyle> inner_style = inner->GetComputedStyle();
 
   ASSERT_TRUE(outer_style);
   ASSERT_TRUE(inner_style);
@@ -3343,7 +3344,7 @@
 
 void SetDependsOnContainerQueries(Element& element) {
   if (const ComputedStyle* style = element.GetComputedStyle()) {
-    ComputedStyle* cloned_style = ComputedStyle::Clone(*style);
+    scoped_refptr<ComputedStyle> cloned_style = ComputedStyle::Clone(*style);
     cloned_style->SetDependsOnContainerQueries(true);
     element.SetComputedStyle(cloned_style);
   }
@@ -3518,7 +3519,8 @@
   ASSERT_TRUE(affected);
   SetDependsOnContainerQueries(*affected);
 
-  const ComputedStyle* old_inner_style = inner_editor->GetComputedStyle();
+  scoped_refptr<const ComputedStyle> old_inner_style =
+      inner_editor->GetComputedStyle();
   EXPECT_TRUE(old_inner_style);
 
   unsigned start_count = GetStyleEngine().StyleForElementCount();
diff --git a/third_party/blink/renderer/core/dom/child_node.h b/third_party/blink/renderer/core/dom/child_node.h
index 4a985a6..0d6f838 100644
--- a/third_party/blink/renderer/core/dom/child_node.h
+++ b/third_party/blink/renderer/core/dom/child_node.h
@@ -14,21 +14,36 @@
   STATIC_ONLY(ChildNode);
 
  public:
-  static void before(Node& node,
-                     const HeapVector<NodeOrStringOrTrustedScript>& nodes,
-                     ExceptionState& exception_state) {
+  static void before(
+      Node& node,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      ExceptionState& exception_state) {
     return node.Before(nodes, exception_state);
   }
 
-  static void after(Node& node,
-                    const HeapVector<NodeOrStringOrTrustedScript>& nodes,
-                    ExceptionState& exception_state) {
+  static void after(
+      Node& node,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      ExceptionState& exception_state) {
     return node.After(nodes, exception_state);
   }
 
-  static void replaceWith(Node& node,
-                          const HeapVector<NodeOrStringOrTrustedScript>& nodes,
-                          ExceptionState& exception_state) {
+  static void replaceWith(
+      Node& node,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      ExceptionState& exception_state) {
     return node.ReplaceWith(nodes, exception_state);
   }
 
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index cc6d433..710ce51 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -84,6 +84,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_element_registration_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_interest_cohort.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_elementcreationoptions_string.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_htmlscriptelement_svgscriptelement.h"
 #include "third_party/blink/renderer/bindings/core/v8/window_proxy.h"
 #include "third_party/blink/renderer/core/accessibility/ax_context.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
@@ -1043,6 +1045,30 @@
       QualifiedName(g_null_atom, name, g_null_atom), this);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+AtomicString GetTypeExtension(
+    Document* document,
+    const V8UnionElementCreationOptionsOrString* string_or_options) {
+  DCHECK(string_or_options);
+
+  switch (string_or_options->GetContentType()) {
+    case V8UnionElementCreationOptionsOrString::ContentType::
+        kElementCreationOptions: {
+      const ElementCreationOptions* options =
+          string_or_options->GetAsElementCreationOptions();
+      if (options->hasIs())
+        return AtomicString(options->is());
+      return AtomicString();
+    }
+    case V8UnionElementCreationOptionsOrString::ContentType::kString:
+      UseCounter::Count(document,
+                        WebFeature::kDocumentCreateElement2ndArgStringHandling);
+      return AtomicString(string_or_options->GetAsString());
+  }
+  NOTREACHED();
+  return AtomicString();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 AtomicString GetTypeExtension(
     Document* document,
     const StringOrElementCreationOptions& string_or_options) {
@@ -1064,15 +1090,26 @@
 
   return AtomicString();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 // https://dom.spec.whatwg.org/#dom-document-createelement
 Element* Document::CreateElementForBinding(
     const AtomicString& local_name,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionElementCreationOptionsOrString* string_or_options,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const StringOrElementCreationOptions& string_or_options,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  if (!string_or_options) {
+    return CreateElementForBinding(local_name, exception_state);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (string_or_options.IsNull()) {
     return CreateElementForBinding(local_name, exception_state);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // 1. If localName does not match Name production, throw InvalidCharacterError
   if (!IsValidElementName(this, local_name)) {
@@ -1089,8 +1126,10 @@
                            ? html_names::xhtmlNamespaceURI
                            : g_null_atom);
 
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool create_builtin = string_or_options.IsElementCreationOptions() ||
                         string_or_options.IsString();
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // 3.
   const AtomicString& is = GetTypeExtension(this, string_or_options);
@@ -1098,7 +1137,12 @@
   // 5. Let element be the result of creating an element given ...
   Element* element =
       CreateElement(q_name, CreateElementFlags::ByCreateElement(),
-                    create_builtin ? is : g_null_atom);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                    is
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                    create_builtin ? is : g_null_atom
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      );
 
   return element;
 }
@@ -1143,10 +1187,18 @@
 Element* Document::createElementNS(
     const AtomicString& namespace_uri,
     const AtomicString& qualified_name,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionElementCreationOptionsOrString* string_or_options,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const StringOrElementCreationOptions& string_or_options,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DCHECK(string_or_options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (string_or_options.IsNull())
     return createElementNS(namespace_uri, qualified_name, exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // 1. Validate and extract
   QualifiedName q_name(
@@ -1154,8 +1206,10 @@
   if (q_name == QualifiedName::Null())
     return nullptr;
 
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool create_builtin = string_or_options.IsElementCreationOptions() ||
                         string_or_options.IsString();
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // 2.
   const AtomicString& is = GetTypeExtension(this, string_or_options);
@@ -1171,7 +1225,12 @@
   // 3. Let element be the result of creating an element
   Element* element =
       CreateElement(q_name, CreateElementFlags::ByCreateElement(),
-                    create_builtin ? is : g_null_atom);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                    is
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                    create_builtin ? is : g_null_atom
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      );
 
   return element;
 }
@@ -2479,7 +2538,7 @@
     focused_element_->blur();
 }
 
-const ComputedStyle* Document::StyleForPage(int32_t page_index) {
+scoped_refptr<const ComputedStyle> Document::StyleForPage(uint32_t page_index) {
   UpdateDistributionForUnknownReasons();
 
   AtomicString page_name;
@@ -2514,7 +2573,7 @@
 
 void Document::GetPageDescription(uint32_t page_index,
                                   WebPrintPageDescription* description) {
-  const ComputedStyle* style = StyleForPage(page_index);
+  scoped_refptr<const ComputedStyle> style = StyleForPage(page_index);
 
   double width = description->size.Width();
   double height = description->size.Height();
@@ -2626,7 +2685,7 @@
   DCHECK_EQ(lifecycle_.GetState(), DocumentLifecycle::kInactive);
   DCHECK(!ax_object_cache_ || this != &AXObjectCacheOwner());
 
-  layout_view_ = MakeGarbageCollected<LayoutView>(this);
+  layout_view_ = new LayoutView(this);
   SetLayoutObject(layout_view_);
 
   layout_view_->SetStyle(GetStyleResolver().StyleForViewport());
@@ -2830,6 +2889,13 @@
   return *doc;
 }
 
+static ui::AXMode ComputeAXModeFromAXContexts(Vector<AXContext*> ax_contexts) {
+  ui::AXMode ax_mode = 0;
+  for (AXContext* context : ax_contexts)
+    ax_mode |= context->GetAXMode();
+  return ax_mode;
+}
+
 void Document::AddAXContext(AXContext* context) {
   // The only case when |&cache_owner| is not |this| is when this is a
   // pop-up. We want pop-ups to share the AXObjectCache of their parent
@@ -2843,11 +2909,16 @@
     return;
 
   ax_contexts_.push_back(context);
-  if (ax_contexts_.size() != 1)
+  if (ax_contexts_.size() != 1) {
+    DCHECK(ax_object_cache_);
+    ax_object_cache_->SetAXMode(ComputeAXModeFromAXContexts(ax_contexts_));
     return;
+  }
 
-  if (!ax_object_cache_)
-    ax_object_cache_ = AXObjectCache::Create(*this);
+  if (!ax_object_cache_) {
+    ax_object_cache_ =
+        AXObjectCache::Create(*this, ComputeAXModeFromAXContexts(ax_contexts_));
+  }
 }
 
 void Document::RemoveAXContext(AXContext* context) {
@@ -2856,8 +2927,12 @@
                    [&context](const auto& item) { return item == context; });
   if (iter != ax_contexts_.end())
     ax_contexts_.erase(iter);
-  if (ax_contexts_.size() == 0)
+  if (ax_contexts_.size() == 0) {
     ClearAXObjectCache();
+  } else {
+    DCHECK(ax_object_cache_);
+    ax_object_cache_->SetAXMode(ComputeAXModeFromAXContexts(ax_contexts_));
+  }
 }
 
 void Document::ClearAXObjectCache() {
@@ -2876,8 +2951,10 @@
   // to invalidate / reset the AXObjectCache while keeping it around. We
   // should rewrite that as a method on AXObjectCache rather than destroying
   // and recreating it here.
-  if (ax_contexts_.size() > 0 && GetLayoutView())
-    ax_object_cache_ = AXObjectCache::Create(*this);
+  if (ax_contexts_.size() > 0 && GetLayoutView()) {
+    ax_object_cache_ =
+        AXObjectCache::Create(*this, ComputeAXModeFromAXContexts(ax_contexts_));
+  }
 }
 
 AXObjectCache* Document::ExistingAXObjectCache() const {
@@ -6248,6 +6325,16 @@
   return KURL();
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8HTMLOrSVGScriptElement* Document::currentScriptForBinding() const {
+  if (current_script_stack_.IsEmpty())
+    return nullptr;
+  ScriptElementBase* script_element_base = current_script_stack_.back();
+  if (!script_element_base)
+    return nullptr;
+  return script_element_base->AsV8HTMLOrSVGScriptElement();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void Document::currentScriptForBinding(
     HTMLScriptElementOrSVGScriptElement& script_element) const {
   if (!current_script_stack_.IsEmpty()) {
@@ -6255,6 +6342,7 @@
       script_element_base->SetScriptElementForBinding(script_element);
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void Document::PushCurrentScript(ScriptElementBase* new_current_script) {
   current_script_stack_.push_back(new_current_script);
@@ -7805,7 +7893,6 @@
   visitor->Trace(did_associate_form_controls_timer_);
   visitor->Trace(user_action_elements_);
   visitor->Trace(svg_extensions_);
-  visitor->Trace(layout_view_);
   visitor->Trace(document_animations_);
   visitor->Trace(timeline_);
   visitor->Trace(pending_animations_);
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 837a0653..2a2f19e3 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -47,6 +47,7 @@
 #include "third_party/blink/public/mojom/permissions/permission.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/permissions_policy/document_policy_feature.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink-forward.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/accessibility/axid.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/css/media_value_change.h"
@@ -142,9 +143,9 @@
 class FontMatchingMetrics;
 class FormController;
 class FrameCallback;
+class FrameScheduler;
 class HTMLAllCollection;
 class HTMLBodyElement;
-class FrameScheduler;
 class HTMLCollection;
 class HTMLDialogElement;
 class HTMLElement;
@@ -162,9 +163,9 @@
 class LazyLoadImageObserver;
 class LiveNodeListBase;
 class LocalDOMWindow;
-class Locale;
 class LocalFrame;
 class LocalFrameView;
+class Locale;
 class Location;
 class MediaQueryListListener;
 class MediaQueryMatcher;
@@ -179,18 +180,16 @@
 class Range;
 class ResourceFetcher;
 class RootScrollerController;
-class ScriptValue;
-class ScriptedIdleTaskController;
 class SVGDocumentExtensions;
 class SVGUseElement;
-class Text;
-class TrustedHTML;
 class ScriptElementBase;
 class ScriptPromise;
 class ScriptRegexp;
 class ScriptRunner;
+class ScriptValue;
 class ScriptableDocumentParser;
 class ScriptedAnimationController;
+class ScriptedIdleTaskController;
 class SecurityOrigin;
 class SelectorQueryCache;
 class SerializedScriptValue;
@@ -199,13 +198,16 @@
 class SnapCoordinator;
 class StringOrElementCreationOptions;
 class StyleEngine;
-class StyleResolver;
 class StylePropertyMapReadOnly;
+class StyleResolver;
 class StyleSheetList;
+class Text;
 class TextAutosizer;
 class TransformSource;
 class TreeWalker;
+class TrustedHTML;
 class V8NodeFilter;
+class V8UnionElementCreationOptionsOrString;
 class ViewportData;
 class VisitedLinkState;
 class WebComputedAXTree;
@@ -367,16 +369,31 @@
 
   Element* CreateElementForBinding(const AtomicString& local_name,
                                    ExceptionState& = ASSERT_NO_EXCEPTION);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Element* CreateElementForBinding(
+      const AtomicString& local_name,
+      const V8UnionElementCreationOptionsOrString* string_or_options,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Element* CreateElementForBinding(const AtomicString& local_name,
                                    const StringOrElementCreationOptions&,
                                    ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Element* createElementNS(const AtomicString& namespace_uri,
                            const AtomicString& qualified_name,
                            ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Element* createElementNS(
+      const AtomicString& namespace_uri,
+      const AtomicString& qualified_name,
+      const V8UnionElementCreationOptionsOrString* string_or_options,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Element* createElementNS(const AtomicString& namespace_uri,
                            const AtomicString& qualified_name,
                            const StringOrElementCreationOptions&,
                            ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DocumentFragment* createDocumentFragment();
   Text* createTextNode(const String& data);
   Comment* createComment(const String& data);
@@ -602,7 +619,7 @@
   void IncLayoutFlexboxCounterNG() { ++layout_flexbox_counter_ng_; }
   void IncLayoutGridCounterNG() { ++layout_grid_counter_ng_; }
 
-  const ComputedStyle* StyleForPage(int32_t page_index);
+  scoped_refptr<const ComputedStyle> StyleForPage(uint32_t page_index);
 
   // Ensures that location-based data will be valid for a given node.
   //
@@ -1159,7 +1176,11 @@
 
   ScriptRunner* GetScriptRunner() { return script_runner_.Get(); }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8HTMLOrSVGScriptElement* currentScriptForBinding() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void currentScriptForBinding(HTMLScriptElementOrSVGScriptElement&) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void PushCurrentScript(ScriptElementBase*);
   void PopCurrentScript(ScriptElementBase*);
 
@@ -2045,7 +2066,7 @@
   bool is_srcdoc_document_;
   bool is_mobile_document_;
 
-  Member<LayoutView> layout_view_;
+  LayoutView* layout_view_;
 
   // The last element in |top_layer_elements_| is topmost in the top layer
   // stack and is thus the one that will be visually on top.
diff --git a/third_party/blink/renderer/core/dom/element-hot.cc b/third_party/blink/renderer/core/dom/element-hot.cc
index 69278b1..aca8d116 100644
--- a/third_party/blink/renderer/core/dom/element-hot.cc
+++ b/third_party/blink/renderer/core/dom/element-hot.cc
@@ -163,12 +163,15 @@
                        kNotInSynchronizationOfLazyAttribute);
 }
 
-void Element::SetAttributeHinted(
-    const AtomicString& local_name,
-    WTF::AtomicStringTable::WeakResult hint,
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
-        string_or_trusted,
-    ExceptionState& exception_state) {
+void Element::SetAttributeHinted(const AtomicString& local_name,
+                                 WTF::AtomicStringTable::WeakResult hint,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                 const V8TrustedString* trusted_string,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                 const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
+                                     string_or_trusted,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                 ExceptionState& exception_state) {
   if (!Document::IsValidName(local_name)) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kInvalidCharacterError,
@@ -180,9 +183,15 @@
   wtf_size_t index;
   QualifiedName q_name = QualifiedName::Null();
   std::tie(index, q_name) = LookupAttributeQNameHinted(local_name, hint);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  AtomicString value(TrustedTypesCheckFor(
+      ExpectedTrustedTypeForAttribute(q_name), trusted_string,
+      GetExecutionContext(), exception_state));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   AtomicString value(TrustedTypesCheckFor(
       ExpectedTrustedTypeForAttribute(q_name), string_or_trusted,
       GetExecutionContext(), exception_state));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (exception_state.HadException())
     return;
   SetAttributeInternal(index, q_name, value,
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 70f33a2..b271305 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_to_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_boolean_scrollintoviewoptions.h"
 #include "third_party/blink/renderer/core/accessibility/ax_context.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/animation/css/css_animations.h"
@@ -1068,6 +1069,24 @@
   EnsureElementRareData().SetNonce(nonce);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void Element::scrollIntoView(const V8UnionBooleanOrScrollIntoViewOptions* arg) {
+  ScrollIntoViewOptions* options = nullptr;
+  switch (arg->GetContentType()) {
+    case V8UnionBooleanOrScrollIntoViewOptions::ContentType::kBoolean:
+      options = ScrollIntoViewOptions::Create();
+      options->setBlock(arg->GetAsBoolean() ? "start" : "end");
+      options->setInlinePosition("nearest");
+      break;
+    case V8UnionBooleanOrScrollIntoViewOptions::ContentType::
+        kScrollIntoViewOptions:
+      options = arg->GetAsScrollIntoViewOptions();
+      break;
+  }
+  DCHECK(options);
+  scrollIntoViewWithOptions(options);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void Element::scrollIntoView(ScrollIntoViewOptionsOrBoolean arg) {
   ScrollIntoViewOptions* options = ScrollIntoViewOptions::Create();
   if (arg.IsBoolean()) {
@@ -1081,10 +1100,16 @@
   }
   scrollIntoViewWithOptions(options);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void Element::scrollIntoView(bool align_to_top) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(align_to_top);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScrollIntoViewOptionsOrBoolean arg;
   arg.SetBoolean(align_to_top);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   scrollIntoView(arg);
 }
 
@@ -2817,7 +2842,7 @@
   GetDocument().GetStyleEngine().ClearNeedsWhitespaceReattachmentFor(this);
 }
 
-ComputedStyle* Element::StyleForLayoutObject(
+scoped_refptr<ComputedStyle> Element::StyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
   DCHECK(GetDocument().InStyleRecalc());
 
@@ -2827,7 +2852,7 @@
   if (ElementAnimations* element_animations = GetElementAnimations())
     element_animations->CssAnimations().ClearPendingUpdate();
 
-  ComputedStyle* style =
+  scoped_refptr<ComputedStyle> style =
       HasCustomStyleCallbacks()
           ? CustomStyleForLayoutObject(style_recalc_context)
           : OriginalStyleForLayoutObject(style_recalc_context);
@@ -2849,7 +2874,7 @@
   return style;
 }
 
-ComputedStyle* Element::OriginalStyleForLayoutObject(
+scoped_refptr<ComputedStyle> Element::OriginalStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
   return GetDocument().GetStyleResolver().ResolveStyle(this,
                                                        style_recalc_context);
@@ -2963,7 +2988,7 @@
     DidRecalcStyle(child_change);
 }
 
-ComputedStyle* Element::PropagateInheritedProperties() {
+scoped_refptr<ComputedStyle> Element::PropagateInheritedProperties() {
   if (IsPseudoElement())
     return nullptr;
   if (NeedsStyleRecalc())
@@ -2976,7 +3001,7 @@
   if (!style || style->Animations() || style->Transitions() ||
       style->HasVariableReference() || style->HasVariableDeclaration())
     return nullptr;
-  ComputedStyle* new_style = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> new_style = ComputedStyle::Clone(*style);
   new_style->PropagateIndependentInheritedProperties(*parent_style);
   INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
                                 independent_inherited_styles_propagated, 1);
@@ -3013,8 +3038,8 @@
       element_animations->SetAnimationStyleChange(false);
   }
 
-  ComputedStyle* new_style = nullptr;
-  const ComputedStyle* old_style = GetComputedStyle();
+  scoped_refptr<ComputedStyle> new_style;
+  scoped_refptr<const ComputedStyle> old_style = GetComputedStyle();
 
   StyleRecalcChange child_change = change.ForChildren(*this);
 
@@ -3032,7 +3057,7 @@
   }
 
   ComputedStyle::Difference diff =
-      ComputedStyle::ComputeDifference(old_style, new_style);
+      ComputedStyle::ComputeDifference(old_style.get(), new_style.get());
 
   if (old_style && old_style->IsEnsuredInDisplayNone()) {
     // Make sure we traverse children for clearing ensured computed styles
@@ -3058,7 +3083,8 @@
 
   if (!child_change.ReattachLayoutTree() &&
       (GetForceReattachLayoutTree() ||
-       ComputedStyle::NeedsReattachLayoutTree(*this, old_style, new_style))) {
+       ComputedStyle::NeedsReattachLayoutTree(*this, old_style.get(),
+                                              new_style.get()))) {
     child_change = child_change.ForceReattachLayoutTree();
   }
 
@@ -3072,9 +3098,10 @@
   } else {
     INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
                                   styles_changed, 1);
-    probe::DidUpdateComputedStyle(this, old_style, new_style);
+    probe::DidUpdateComputedStyle(this, old_style.get(), new_style.get());
     if (this == GetDocument().documentElement()) {
-      if (GetDocument().GetStyleEngine().UpdateRemUnits(old_style, new_style)) {
+      if (GetDocument().GetStyleEngine().UpdateRemUnits(old_style.get(),
+                                                        new_style.get())) {
         // Trigger a full document recalc on rem unit changes. We could keep
         // track of which elements depend on rem units like we do for viewport
         // styles, but we assume root font size changes are rare and just
@@ -3083,7 +3110,7 @@
       }
     }
     child_change = ApplyComputedStyleDiff(child_change, diff);
-    UpdateCallbackSelectors(old_style, new_style);
+    UpdateCallbackSelectors(old_style.get(), new_style.get());
   }
 
   if (auto* context = GetDisplayLockContext()) {
@@ -3101,7 +3128,7 @@
         old_style->HasChildDependentFlags())
       new_style->CopyChildDependentFlagsFrom(*old_style);
     if (RuntimeEnabledFeatures::LayoutNGEnabled())
-      UpdateForceLegacyLayout(*new_style, old_style);
+      UpdateForceLegacyLayout(*new_style, old_style.get());
   }
 
   if (child_change.ReattachLayoutTree()) {
@@ -3112,7 +3139,7 @@
 
   if (LayoutObject* layout_object = GetLayoutObject()) {
     DCHECK(new_style);
-    const ComputedStyle* layout_style(std::move(new_style));
+    scoped_refptr<const ComputedStyle> layout_style(std::move(new_style));
     if (auto* pseudo_element = DynamicTo<PseudoElement>(this)) {
       if (layout_style->Display() == EDisplay::kContents) {
         layout_style =
@@ -3130,7 +3157,7 @@
         diff == ComputedStyle::Difference::kEqual
             ? LayoutObject::ApplyStyleChanges::kNo
             : LayoutObject::ApplyStyleChanges::kYes;
-    layout_object->SetStyle(layout_style, apply_changes);
+    layout_object->SetStyle(layout_style.get(), apply_changes);
   }
   return child_change;
 }
@@ -3783,20 +3810,29 @@
   return true;
 }
 
-void Element::setAttributeNS(
-    const AtomicString& namespace_uri,
-    const AtomicString& qualified_name,
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
-        string_or_trusted,
-    ExceptionState& exception_state) {
+void Element::setAttributeNS(const AtomicString& namespace_uri,
+                             const AtomicString& qualified_name,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                             const V8TrustedString* trusted_string,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                             const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
+                                 string_or_trusted,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                             ExceptionState& exception_state) {
   QualifiedName parsed_name = g_any_name;
   if (!ParseAttributeName(parsed_name, namespace_uri, qualified_name,
                           exception_state))
     return;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  AtomicString value(TrustedTypesCheckFor(
+      ExpectedTrustedTypeForAttribute(parsed_name), trusted_string,
+      GetExecutionContext(), exception_state));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   AtomicString value(TrustedTypesCheckFor(
       ExpectedTrustedTypeForAttribute(parsed_name), string_or_trusted,
       GetExecutionContext(), exception_state));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (exception_state.HadException())
     return;
 
@@ -4924,14 +4960,14 @@
       element_style = nullptr;
     }
     if (!element_style) {
-      ComputedStyle* new_style = nullptr;
+      scoped_refptr<ComputedStyle> new_style = nullptr;
       // TODO(crbug.com/953707): Avoid setting inline style during
       // HTMLImageElement::CustomStyleForLayoutObject.
       if (HasCustomStyleCallbacks() && !IsA<HTMLImageElement>(*this))
         new_style = CustomStyleForLayoutObject(style_recalc_context);
       else
         new_style = OriginalStyleForLayoutObject(style_recalc_context);
-      element_style = new_style;
+      element_style = new_style.get();
       new_style->SetIsEnsuredInDisplayNone();
       SetComputedStyle(std::move(new_style));
     }
@@ -4960,8 +4996,9 @@
   style_request.layout_parent_override = layout_parent_style;
   style_request.pseudo_argument = pseudo_argument;
 
-  ComputedStyle* result = GetDocument().GetStyleResolver().ResolveStyle(
-      this, style_recalc_context, style_request);
+  scoped_refptr<ComputedStyle> result =
+      GetDocument().GetStyleResolver().ResolveStyle(this, style_recalc_context,
+                                                    style_request);
   DCHECK(result);
   result->SetIsEnsuredInDisplayNone();
   return element_style->AddCachedPseudoElementStyle(std::move(result));
@@ -5092,9 +5129,9 @@
     // RemainingTextLayoutObject should have been cleared from DetachLayoutTree.
     DCHECK(!To<FirstLetterPseudoElement>(element)->RemainingTextLayoutObject());
     DCHECK(text_node_changed);
-    ComputedStyle* pseudo_style =
+    scoped_refptr<ComputedStyle> pseudo_style =
         element->StyleForLayoutObject(style_recalc_context);
-    if (PseudoElementLayoutObjectIsNeeded(pseudo_style, this))
+    if (PseudoElementLayoutObjectIsNeeded(pseudo_style.get(), this))
       element->SetComputedStyle(std::move(pseudo_style));
     else
       GetElementRareData()->SetPseudoElement(kPseudoIdFirstLetter, nullptr);
@@ -5161,9 +5198,9 @@
   EnsureElementRareData().SetPseudoElement(pseudo_id, pseudo_element);
   pseudo_element->InsertedInto(*this);
 
-  ComputedStyle* pseudo_style =
+  scoped_refptr<ComputedStyle> pseudo_style =
       pseudo_element->StyleForLayoutObject(style_recalc_context);
-  if (!PseudoElementLayoutObjectIsNeeded(pseudo_style, this)) {
+  if (!PseudoElementLayoutObjectIsNeeded(pseudo_style.get(), this)) {
     GetElementRareData()->SetPseudoElement(pseudo_id, nullptr);
     return nullptr;
   }
@@ -5247,21 +5284,21 @@
           style->GetCachedPseudoElementStyle(pseudo_id))
     return cached;
 
-  ComputedStyle* result =
+  scoped_refptr<ComputedStyle> result =
       UncachedStyleForPseudoElement(StyleRequest(pseudo_id, style));
   if (result)
     return style->AddCachedPseudoElementStyle(std::move(result));
   return nullptr;
 }
 
-ComputedStyle* Element::UncachedStyleForPseudoElement(
+scoped_refptr<ComputedStyle> Element::UncachedStyleForPseudoElement(
     const StyleRequest& request) {
   // TODO(crbug.com/1145970): Use actual StyleRecalcContext.
   StyleRecalcContext style_recalc_context;
   return StyleForPseudoElement(style_recalc_context, request);
 }
 
-ComputedStyle* Element::StyleForPseudoElement(
+scoped_refptr<ComputedStyle> Element::StyleForPseudoElement(
     const StyleRecalcContext& style_recalc_context,
     const StyleRequest& request) {
   const bool is_before_or_after = request.pseudo_id == kPseudoIdBefore ||
@@ -5294,8 +5331,9 @@
         IsPseudoElement() ? To<PseudoElement>(this)->GetPseudoId()
                           : kPseudoIdNone;
     Element* target = IsPseudoElement() ? parentElement() : this;
-    ComputedStyle* result = GetDocument().GetStyleResolver().ResolveStyle(
-        target, style_recalc_context, first_line_inherited_request);
+    scoped_refptr<ComputedStyle> result =
+        GetDocument().GetStyleResolver().ResolveStyle(
+            target, style_recalc_context, first_line_inherited_request);
     if (result)
       result->SetStyleType(kPseudoIdFirstLineInherited);
     return result;
@@ -5857,7 +5895,7 @@
   DCHECK(HasCustomStyleCallbacks());
 }
 
-ComputedStyle* Element::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> Element::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
   DCHECK(HasCustomStyleCallbacks());
   return OriginalStyleForLayoutObject(style_recalc_context);
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index d523876..651fecb7 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -28,6 +28,7 @@
 #include "base/dcheck_is_on.h"
 #include "third_party/blink/public/common/input/pointer_id.h"
 #include "third_party/blink/public/common/metrics/document_update_reason.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/animation/animatable.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/css/css_primitive_value.h"
@@ -80,7 +81,6 @@
 class NamedNodeMap;
 class PointerLockOptions;
 class PseudoElement;
-class StyleRequest;
 class ResizeObservation;
 class ResizeObserver;
 class ScrollIntoViewOptions;
@@ -93,6 +93,8 @@
 class StylePropertyMap;
 class StylePropertyMapReadOnly;
 class StyleRecalcContext;
+class StyleRequest;
+class V8UnionBooleanOrScrollIntoViewOptions;
 
 enum class CSSPropertyID;
 enum class CSSValueID;
@@ -241,6 +243,14 @@
   }
 
   // Trusted Types variant for explicit setAttribute() use.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void setAttribute(const AtomicString& name,
+                    const V8TrustedString* trusted_string,
+                    ExceptionState& exception_state) {
+    SetAttributeHinted(name, WeakLowercaseIfNecessary(name), trusted_string,
+                       exception_state);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void setAttribute(const AtomicString& name,
                     const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
                         string_or_trusted,
@@ -248,6 +258,7 @@
     SetAttributeHinted(name, WeakLowercaseIfNecessary(name), string_or_trusted,
                        exception_state);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Returns attributes that should be checked against Trusted Types
   virtual const AttrNameToTrustedType& GetCheckedAttributeTypes() const;
@@ -258,11 +269,18 @@
                                  const AtomicString& namespace_uri,
                                  const AtomicString& qualified_name,
                                  ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void setAttributeNS(const AtomicString& namespace_uri,
+                      const AtomicString& qualified_name,
+                      const V8TrustedString* trusted_string,
+                      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void setAttributeNS(
       const AtomicString& namespace_uri,
       const AtomicString& qualified_name,
       const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   bool toggleAttribute(const AtomicString&, ExceptionState&);
   bool toggleAttribute(const AtomicString&, bool force, ExceptionState&);
@@ -301,7 +319,11 @@
   // when not interested in style attribute or one of the SVG attributes.
   AttributeCollection AttributesWithoutUpdate() const;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void scrollIntoView(const V8UnionBooleanOrScrollIntoViewOptions* arg);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void scrollIntoView(ScrollIntoViewOptionsOrBoolean);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void scrollIntoView(bool align_to_top = true);
   void scrollIntoViewWithOptions(const ScrollIntoViewOptions*);
   void ScrollIntoViewNoVisualUpdate(const ScrollIntoViewOptions*);
@@ -744,15 +766,16 @@
   //
   // This is appropriate to use if the cached version is invalid in a given
   // situation.
-  ComputedStyle* UncachedStyleForPseudoElement(const StyleRequest&);
+  scoped_refptr<ComputedStyle> UncachedStyleForPseudoElement(
+      const StyleRequest&);
 
   // This is the same as UncachedStyleForPseudoElement, except that the caller
   // must provide an appropriate StyleRecalcContext such that e.g. @container
   // queries are evaluated correctly.
   //
   // See StyleRecalcContext for more information.
-  ComputedStyle* StyleForPseudoElement(const StyleRecalcContext&,
-                                       const StyleRequest&);
+  scoped_refptr<ComputedStyle> StyleForPseudoElement(const StyleRecalcContext&,
+                                                     const StyleRequest&);
 
   virtual bool CanGeneratePseudoElement(PseudoId) const;
 
@@ -858,7 +881,7 @@
   bool IsSpellCheckingEnabled() const;
 
   // FIXME: public for LayoutTreeBuilder, we shouldn't expose this though.
-  ComputedStyle* StyleForLayoutObject(const StyleRecalcContext&);
+  scoped_refptr<ComputedStyle> StyleForLayoutObject(const StyleRecalcContext&);
 
   bool HasID() const;
   bool HasClass() const;
@@ -986,7 +1009,8 @@
 
   virtual void WillRecalcStyle(const StyleRecalcChange);
   virtual void DidRecalcStyle(const StyleRecalcChange);
-  virtual ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&);
+  virtual scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&);
 
   virtual NamedItemType GetNamedItemType() const {
     return NamedItemType::kNone;
@@ -1017,7 +1041,8 @@
 
   static bool AttributeValueIsJavaScriptURL(const Attribute&);
 
-  ComputedStyle* OriginalStyleForLayoutObject(const StyleRecalcContext&);
+  scoped_refptr<ComputedStyle> OriginalStyleForLayoutObject(
+      const StyleRecalcContext&);
 
   // Step 4 of http://domparsing.spec.whatwg.org/#insertadjacenthtml()
   Node* InsertAdjacent(const String& where, Node* new_child, ExceptionState&);
@@ -1078,7 +1103,7 @@
   // these changes can be directly propagated to this element (the child).
   // If these conditions are met, propagates the changes to the current style
   // and returns the new style. Otherwise, returns null.
-  ComputedStyle* PropagateInheritedProperties();
+  scoped_refptr<ComputedStyle> PropagateInheritedProperties();
 
   const ComputedStyle* EnsureOwnComputedStyle(
       const StyleRecalcContext&,
@@ -1180,11 +1205,18 @@
                           WTF::AtomicStringTable::WeakResult hint,
                           const AtomicString& value,
                           ExceptionState& = ASSERT_NO_EXCEPTION);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void SetAttributeHinted(const AtomicString& name,
+                          WTF::AtomicStringTable::WeakResult hint,
+                          const V8TrustedString* trusted_string,
+                          ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void SetAttributeHinted(
       const AtomicString& name,
       WTF::AtomicStringTable::WeakResult hint,
       const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   std::pair<wtf_size_t, const QualifiedName> LookupAttributeQNameHinted(
       const AtomicString& name,
       WTF::AtomicStringTable::WeakResult hint) const;
diff --git a/third_party/blink/renderer/core/dom/events/event_target.cc b/third_party/blink/renderer/core/dom/events/event_target.cc
index 0525bf6b..7c6f851 100644
--- a/third_party/blink/renderer/core/dom/events/event_target.cc
+++ b/third_party/blink/renderer/core/dom/events/event_target.cc
@@ -40,6 +40,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h"
 #include "third_party/blink/renderer/bindings/core/v8/js_event_listener.h"
 #include "third_party/blink/renderer/bindings/core/v8/source_location.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_addeventlisteneroptions_boolean.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_boolean_eventlisteneroptions.h"
 #include "third_party/blink/renderer/core/dom/abort_signal.h"
 #include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
@@ -445,6 +447,41 @@
   return addEventListener(event_type, event_listener);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+bool EventTarget::addEventListener(
+    const AtomicString& event_type,
+    V8EventListener* listener,
+    const V8UnionAddEventListenerOptionsOrBoolean* bool_or_options) {
+  DCHECK(bool_or_options);
+
+  EventListener* event_listener = JSEventListener::CreateOrNull(listener);
+
+  switch (bool_or_options->GetContentType()) {
+    case V8UnionAddEventListenerOptionsOrBoolean::ContentType::kBoolean:
+      return addEventListener(event_type, event_listener,
+                              bool_or_options->GetAsBoolean());
+    case V8UnionAddEventListenerOptionsOrBoolean::ContentType::
+        kAddEventListenerOptions: {
+      auto* options_resolved =
+          MakeGarbageCollected<AddEventListenerOptionsResolved>();
+      AddEventListenerOptions* options =
+          bool_or_options->GetAsAddEventListenerOptions();
+      if (options->hasPassive())
+        options_resolved->setPassive(options->passive());
+      if (options->hasOnce())
+        options_resolved->setOnce(options->once());
+      if (options->hasCapture())
+        options_resolved->setCapture(options->capture());
+      if (options->hasSignal())
+        options_resolved->setSignal(options->signal());
+      return addEventListener(event_type, event_listener, options_resolved);
+    }
+  }
+
+  NOTREACHED();
+  return false;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 bool EventTarget::addEventListener(
     const AtomicString& event_type,
     V8EventListener* listener,
@@ -474,6 +511,7 @@
 
   return addEventListener(event_type, event_listener);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 bool EventTarget::addEventListener(const AtomicString& event_type,
                                    EventListener* listener,
@@ -598,6 +636,31 @@
   return removeEventListener(event_type, event_listener);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+bool EventTarget::removeEventListener(
+    const AtomicString& event_type,
+    V8EventListener* listener,
+    const V8UnionBooleanOrEventListenerOptions* bool_or_options) {
+  DCHECK(bool_or_options);
+
+  EventListener* event_listener = JSEventListener::CreateOrNull(listener);
+
+  switch (bool_or_options->GetContentType()) {
+    case V8UnionBooleanOrEventListenerOptions::ContentType::kBoolean:
+      return removeEventListener(event_type, event_listener,
+                                 bool_or_options->GetAsBoolean());
+    case V8UnionBooleanOrEventListenerOptions::ContentType::
+        kEventListenerOptions: {
+      EventListenerOptions* options =
+          bool_or_options->GetAsEventListenerOptions();
+      return removeEventListener(event_type, event_listener, options);
+    }
+  }
+
+  NOTREACHED();
+  return false;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 bool EventTarget::removeEventListener(
     const AtomicString& event_type,
     V8EventListener* listener,
@@ -616,6 +679,7 @@
 
   return removeEventListener(event_type, event_listener);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 bool EventTarget::removeEventListener(const AtomicString& event_type,
                                       const EventListener* listener,
diff --git a/third_party/blink/renderer/core/dom/events/event_target.h b/third_party/blink/renderer/core/dom/events/event_target.h
index 2cac08c3..08d1ebbd 100644
--- a/third_party/blink/renderer/core/dom/events/event_target.h
+++ b/third_party/blink/renderer/core/dom/events/event_target.h
@@ -61,6 +61,8 @@
 class ScriptState;
 class ServiceWorker;
 class V8EventListener;
+class V8UnionAddEventListenerOptionsOrBoolean;
+class V8UnionBooleanOrEventListenerOptions;
 
 struct FiringEventIterator {
   DISALLOW_NEW();
@@ -134,9 +136,16 @@
   static EventTarget* Create(ScriptState*);
 
   bool addEventListener(const AtomicString& event_type, V8EventListener*);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  bool addEventListener(
+      const AtomicString& event_type,
+      V8EventListener* listener,
+      const V8UnionAddEventListenerOptionsOrBoolean* bool_or_options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool addEventListener(const AtomicString& event_type,
                         V8EventListener*,
                         const AddEventListenerOptionsOrBoolean&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool addEventListener(const AtomicString& event_type,
                         EventListener*,
                         bool use_capture = false);
@@ -145,9 +154,16 @@
                         AddEventListenerOptionsResolved*);
 
   bool removeEventListener(const AtomicString& event_type, V8EventListener*);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  bool removeEventListener(
+      const AtomicString& event_type,
+      V8EventListener* listener,
+      const V8UnionBooleanOrEventListenerOptions* bool_or_options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool removeEventListener(const AtomicString& event_type,
                            V8EventListener*,
                            const EventListenerOptionsOrBoolean&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool removeEventListener(const AtomicString& event_type,
                            const EventListener*,
                            bool use_capture = false);
diff --git a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
index 432eb120..1a429bf8 100644
--- a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
+++ b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
@@ -90,11 +90,6 @@
   return length;
 }
 
-void FirstLetterPseudoElement::Trace(Visitor* visitor) const {
-  visitor->Trace(remaining_text_layout_object_);
-  PseudoElement::Trace(visitor);
-}
-
 // Once we see any of these layoutObjects we can stop looking for first-letter
 // as they signal the end of the first line of text.
 static bool IsInvalidFirstLetterLayoutObject(const LayoutObject* obj) {
@@ -316,7 +311,8 @@
   PseudoElement::DetachLayoutTree(performing_reattach);
 }
 
-ComputedStyle* FirstLetterPseudoElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle>
+FirstLetterPseudoElement::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
   LayoutObject* first_letter_text =
       FirstLetterPseudoElement::FirstLetterTextLayoutObject(*this);
diff --git a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h
index 183117fa..a3d9146 100644
--- a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h
+++ b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.h
@@ -42,7 +42,6 @@
   FirstLetterPseudoElement(const FirstLetterPseudoElement&) = delete;
   FirstLetterPseudoElement& operator=(const FirstLetterPseudoElement&) = delete;
   ~FirstLetterPseudoElement() override;
-  void Trace(Visitor*) const override;
 
   static LayoutText* FirstLetterTextLayoutObject(const Element&);
   static unsigned FirstLetterLength(const String&);
@@ -59,11 +58,12 @@
   Node* InnerNodeForHitTesting() const override;
 
  private:
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) override;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) override;
 
   void AttachFirstLetterTextLayoutObjects(LayoutText* first_letter_text);
 
-  Member<LayoutTextFragment> remaining_text_layout_object_;
+  LayoutTextFragment* remaining_text_layout_object_;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/dom/layout_tree_builder.cc b/third_party/blink/renderer/core/dom/layout_tree_builder.cc
index 754ea04..1c79343 100644
--- a/third_party/blink/renderer/core/dom/layout_tree_builder.cc
+++ b/third_party/blink/renderer/core/dom/layout_tree_builder.cc
@@ -116,7 +116,7 @@
   if (style_ == context_.parent->Style())
     return nullptr;
 
-  ComputedStyle* wrapper_style =
+  scoped_refptr<ComputedStyle> wrapper_style =
       node_->GetDocument()
           .GetStyleResolver()
           .CreateInheritedDisplayContentsStyleIfNeeded(
diff --git a/third_party/blink/renderer/core/dom/layout_tree_builder.h b/third_party/blink/renderer/core/dom/layout_tree_builder.h
index 6ee22cd..f434b5c 100644
--- a/third_party/blink/renderer/core/dom/layout_tree_builder.h
+++ b/third_party/blink/renderer/core/dom/layout_tree_builder.h
@@ -89,7 +89,7 @@
 
   NodeType* node_;
   Node::AttachContext& context_;
-  const ComputedStyle* style_;
+  scoped_refptr<const ComputedStyle> style_;
 };
 
 class LayoutTreeBuilderForElement : public LayoutTreeBuilder<Element> {
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc
index 5025ab75..b5f6dda 100644
--- a/third_party/blink/renderer/core/dom/node.cc
+++ b/third_party/blink/renderer/core/dom/node.cc
@@ -32,6 +32,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/node_or_string_or_trusted_script.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_get_root_node_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_node_string_trustedscript.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_trustedscript.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/animation/scroll_timeline.h"
 #include "third_party/blink/renderer/core/css/css_selector.h"
@@ -764,6 +766,17 @@
   return appendChild(new_child, ASSERT_NO_EXCEPTION);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+static bool IsNodeInNodes(
+    const Node* const node,
+    const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes) {
+  for (const V8UnionNodeOrStringOrTrustedScript* node_or_string : nodes) {
+    if (node_or_string->IsNode() && node_or_string->GetAsNode() == node)
+      return true;
+  }
+  return false;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 static bool IsNodeInNodes(
     const Node* const node,
     const HeapVector<NodeOrStringOrTrustedScript>& nodes) {
@@ -773,10 +786,16 @@
   }
   return false;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 static Node* FindViablePreviousSibling(
     const Node& node,
-    const HeapVector<NodeOrStringOrTrustedScript>& nodes) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<NodeOrStringOrTrustedScript>& nodes
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   for (Node* sibling = node.previousSibling(); sibling;
        sibling = sibling->previousSibling()) {
     if (!IsNodeInNodes(sibling, nodes))
@@ -787,7 +806,12 @@
 
 static Node* FindViableNextSibling(
     const Node& node,
-    const HeapVector<NodeOrStringOrTrustedScript>& nodes) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<NodeOrStringOrTrustedScript>& nodes
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   for (Node* sibling = node.nextSibling(); sibling;
        sibling = sibling->nextSibling()) {
     if (!IsNodeInNodes(sibling, nodes))
@@ -796,6 +820,49 @@
   return nullptr;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+static Node* NodeOrStringToNode(
+    const V8UnionNodeOrStringOrTrustedScript* node_or_string,
+    Document& document,
+    bool needs_trusted_types_check,
+    ExceptionState& exception_state) {
+  if (!needs_trusted_types_check) {
+    // Without trusted type checks, we simply extract the string from whatever
+    // constituent type we find.
+    switch (node_or_string->GetContentType()) {
+      case V8UnionNodeOrStringOrTrustedScript::ContentType::kNode:
+        return node_or_string->GetAsNode();
+      case V8UnionNodeOrStringOrTrustedScript::ContentType::kString:
+        return Text::Create(document, node_or_string->GetAsString());
+      case V8UnionNodeOrStringOrTrustedScript::ContentType::kTrustedScript:
+        return Text::Create(document,
+                            node_or_string->GetAsTrustedScript()->toString());
+    }
+    NOTREACHED();
+    return nullptr;
+  }
+
+  // With trusted type checks, we can process trusted script or non-text nodes
+  // directly. Strings or text nodes need to be checked.
+  if (node_or_string->IsNode() && !node_or_string->GetAsNode()->IsTextNode())
+    return node_or_string->GetAsNode();
+
+  if (node_or_string->IsTrustedScript()) {
+    return Text::Create(document,
+                        node_or_string->GetAsTrustedScript()->toString());
+  }
+
+  String string_value = node_or_string->IsString()
+                            ? node_or_string->GetAsString()
+                            : node_or_string->GetAsNode()->textContent();
+
+  string_value = TrustedTypesCheckForScript(
+      string_value, document.GetExecutionContext(), exception_state);
+  if (exception_state.HadException())
+    return nullptr;
+  return Text::Create(document, string_value);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 static Node* NodeOrStringToNode(
     const NodeOrStringOrTrustedScript& node_or_string,
     Document& document,
@@ -833,11 +900,16 @@
     return nullptr;
   return Text::Create(document, string_value);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 // Returns nullptr if an exception was thrown.
 static Node* ConvertNodesIntoNode(
     const Node* parent,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     Document& document,
     ExceptionState& exception_state) {
   bool needs_check = IsA<HTMLScriptElement>(parent) &&
@@ -848,8 +920,7 @@
     return NodeOrStringToNode(nodes[0], document, needs_check, exception_state);
 
   Node* fragment = DocumentFragment::Create(document);
-  for (const NodeOrStringOrTrustedScript& node_or_string_or_trusted_script :
-       nodes) {
+  for (const auto& node_or_string_or_trusted_script : nodes) {
     Node* node = NodeOrStringToNode(node_or_string_or_trusted_script, document,
                                     needs_check, exception_state);
     if (node)
@@ -860,8 +931,13 @@
   return fragment;
 }
 
-void Node::Prepend(const HeapVector<NodeOrStringOrTrustedScript>& nodes,
-                   ExceptionState& exception_state) {
+void Node::Prepend(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   auto* this_node = DynamicTo<ContainerNode>(this);
   if (!this_node) {
     exception_state.ThrowDOMException(
@@ -875,8 +951,13 @@
     this_node->InsertBefore(node, firstChild(), exception_state);
 }
 
-void Node::Append(const HeapVector<NodeOrStringOrTrustedScript>& nodes,
-                  ExceptionState& exception_state) {
+void Node::Append(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   auto* this_node = DynamicTo<ContainerNode>(this);
   if (!this_node) {
     exception_state.ThrowDOMException(
@@ -890,8 +971,13 @@
     this_node->AppendChild(node, exception_state);
 }
 
-void Node::Before(const HeapVector<NodeOrStringOrTrustedScript>& nodes,
-                  ExceptionState& exception_state) {
+void Node::Before(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   Node* parent = parentNode();
   if (!parent)
     return;
@@ -913,8 +999,13 @@
   }
 }
 
-void Node::After(const HeapVector<NodeOrStringOrTrustedScript>& nodes,
-                 ExceptionState& exception_state) {
+void Node::After(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   Node* parent = parentNode();
   if (!parent)
     return;
@@ -931,8 +1022,13 @@
     parent_node->InsertBefore(node, viable_next_sibling, exception_state);
 }
 
-void Node::ReplaceWith(const HeapVector<NodeOrStringOrTrustedScript>& nodes,
-                       ExceptionState& exception_state) {
+void Node::ReplaceWith(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   Node* parent = parentNode();
   if (!parent)
     return;
@@ -956,8 +1052,13 @@
 }
 
 // https://dom.spec.whatwg.org/#dom-parentnode-replacechildren
-void Node::ReplaceChildren(const HeapVector<NodeOrStringOrTrustedScript>& nodes,
-                           ExceptionState& exception_state) {
+void Node::ReplaceChildren(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   auto* this_node = DynamicTo<ContainerNode>(this);
   if (!this_node) {
     exception_state.ThrowDOMException(
@@ -1075,7 +1176,7 @@
   }
 }
 
-void Node::SetComputedStyle(const ComputedStyle* computed_style) {
+void Node::SetComputedStyle(scoped_refptr<const ComputedStyle> computed_style) {
   // We don't set computed style for text nodes.
   DCHECK(IsElementNode());
 
@@ -2019,8 +2120,41 @@
   return content.ToString();
 }
 
-void Node::setTextContent(const StringOrTrustedScript& string_or_trusted_script,
-                          ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8UnionStringOrTrustedScript* Node::textContentForBinding() const {
+  const String& value = textContent();
+  if (value.IsNull())
+    return nullptr;
+  return MakeGarbageCollected<V8UnionStringOrTrustedScript>(value);
+}
+
+void Node::setTextContentForBinding(const V8UnionStringOrTrustedScript* value,
+                                    ExceptionState& exception_state) {
+  if (!value)
+    return setTextContent(g_empty_string);
+
+  switch (value->GetContentType()) {
+    case V8UnionStringOrTrustedScript::ContentType::kString:
+      return setTextContent(value->GetAsString());
+    case V8UnionStringOrTrustedScript::ContentType::kTrustedScript:
+      return setTextContent(value->GetAsTrustedScript()->toString());
+  }
+
+  NOTREACHED();
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+void Node::textContentForBinding(StringOrTrustedScript& result) {
+  String value = textContent();
+  if (!value.IsNull())
+    result.SetString(value);
+}
+
+void Node::setTextContentForBinding(
+    const StringOrTrustedScript& string_or_trusted_script,
+    ExceptionState& exception_state) {
   String value =
       string_or_trusted_script.IsString()
           ? string_or_trusted_script.GetAsString()
@@ -2030,11 +2164,7 @@
   setTextContent(value);
 }
 
-void Node::textContent(StringOrTrustedScript& result) {
-  String value = textContent();
-  if (!value.IsNull())
-    result.SetString(value);
-}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void Node::setTextContent(const String& text) {
   switch (getNodeType()) {
diff --git a/third_party/blink/renderer/core/dom/node.h b/third_party/blink/renderer/core/dom/node.h
index 7f4b4cd..8fa516f 100644
--- a/third_party/blink/renderer/core/dom/node.h
+++ b/third_party/blink/renderer/core/dom/node.h
@@ -82,6 +82,8 @@
 class StringOrTrustedScript;
 class StyleChangeReasonForTracing;
 class V8ScrollStateCallback;
+class V8UnionNodeOrStringOrTrustedScript;
+class V8UnionStringOrTrustedScript;
 class WebPluginContainerImpl;
 struct PhysicalRect;
 
@@ -238,6 +240,26 @@
   // https://dom.spec.whatwg.org/#concept-closed-shadow-hidden
   bool IsClosedShadowHiddenFrom(const Node&) const;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void Prepend(
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+      ExceptionState& exception_state);
+  void Append(
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+      ExceptionState& exception_state);
+  void Before(
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+      ExceptionState& exception_state);
+  void After(
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+      ExceptionState& exception_state);
+  void ReplaceWith(
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+      ExceptionState& exception_state);
+  void ReplaceChildren(
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void Prepend(const HeapVector<NodeOrStringOrTrustedScript>&, ExceptionState&);
   void Append(const HeapVector<NodeOrStringOrTrustedScript>&, ExceptionState&);
   void Before(const HeapVector<NodeOrStringOrTrustedScript>&, ExceptionState&);
@@ -246,6 +268,7 @@
                    ExceptionState&);
   void ReplaceChildren(const HeapVector<NodeOrStringOrTrustedScript>&,
                        ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void remove(ExceptionState&);
   void remove();
 
@@ -281,12 +304,20 @@
 
   String textContent(bool convert_brs_to_newlines = false) const;
   virtual void setTextContent(const String&);
-  void textContent(StringOrTrustedScript& result);
-  virtual void setTextContent(const StringOrTrustedScript&, ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionStringOrTrustedScript* textContentForBinding() const;
+  virtual void setTextContentForBinding(
+      const V8UnionStringOrTrustedScript* value,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void textContentForBinding(StringOrTrustedScript& result);
+  virtual void setTextContentForBinding(const StringOrTrustedScript&,
+                                        ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   bool SupportsAltText();
 
-  void SetComputedStyle(const ComputedStyle* computed_style);
+  void SetComputedStyle(scoped_refptr<const ComputedStyle> computed_style);
 
   // Other methods (not part of DOM)
   ALWAYS_INLINE bool IsTextNode() const {
diff --git a/third_party/blink/renderer/core/dom/node.idl b/third_party/blink/renderer/core/dom/node.idl
index c5e78d8b..5609ad3 100644
--- a/third_party/blink/renderer/core/dom/node.idl
+++ b/third_party/blink/renderer/core/dom/node.idl
@@ -58,7 +58,7 @@
 
     [Affects=Nothing, CEReactions] attribute DOMString? nodeValue;
 
-    [Affects=Nothing, CEReactions, RaisesException=Setter] attribute (DOMString or TrustedScript)? textContent;
+    [Affects=Nothing, CEReactions, ImplementedAs=textContentForBinding, RaisesException=Setter] attribute (DOMString or TrustedScript)? textContent;
     [CEReactions] void normalize();
 
     [NewObject, DoNotTestNewObject, CEReactions, RaisesException] Node cloneNode(optional boolean deep = false);
diff --git a/third_party/blink/renderer/core/dom/node_rare_data.cc b/third_party/blink/renderer/core/dom/node_rare_data.cc
index 4252c1c03..fed737f 100644
--- a/third_party/blink/renderer/core/dom/node_rare_data.cc
+++ b/third_party/blink/renderer/core/dom/node_rare_data.cc
@@ -37,7 +37,6 @@
 #include "third_party/blink/renderer/core/dom/flat_tree_node_data.h"
 #include "third_party/blink/renderer/core/dom/mutation_observer_registration.h"
 #include "third_party/blink/renderer/core/dom/node_lists_node_data.h"
-#include "third_party/blink/renderer/core/layout/layout_object.h"
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -90,13 +89,15 @@
   }
 }
 
-NodeRenderingData::NodeRenderingData(LayoutObject* layout_object,
-                                     const ComputedStyle* computed_style)
+NodeRenderingData::NodeRenderingData(
+    LayoutObject* layout_object,
+    scoped_refptr<const ComputedStyle> computed_style)
     : NodeData(false, false),
       layout_object_(layout_object),
       computed_style_(computed_style) {}
 
-void NodeRenderingData::SetComputedStyle(const ComputedStyle* computed_style) {
+void NodeRenderingData::SetComputedStyle(
+    scoped_refptr<const ComputedStyle> computed_style) {
   DCHECK_NE(&SharedEmptyData(), this);
   computed_style_ = computed_style;
 }
@@ -107,11 +108,6 @@
       (MakeGarbageCollected<NodeRenderingData>(nullptr, nullptr)));
   return *shared_empty_data;
 }
-void NodeRenderingData::TraceAfterDispatch(Visitor* visitor) const {
-  visitor->Trace(layout_object_);
-  visitor->Trace(computed_style_);
-  NodeData::TraceAfterDispatch(visitor);
-}
 
 void NodeRareData::RegisterScrollTimeline(ScrollTimeline* timeline) {
   if (!scroll_timelines_) {
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 7c89c20..3ea8cc3 100644
--- a/third_party/blink/renderer/core/dom/node_rare_data.h
+++ b/third_party/blink/renderer/core/dom/node_rare_data.h
@@ -107,7 +107,8 @@
 class GC_PLUGIN_IGNORE("Manual dispatch implemented in NodeData.")
     NodeRenderingData final : public NodeData {
  public:
-  NodeRenderingData(LayoutObject*, const ComputedStyle* computed_style);
+  NodeRenderingData(LayoutObject*,
+                    scoped_refptr<const ComputedStyle> computed_style);
   NodeRenderingData(const NodeRenderingData&) = delete;
   NodeRenderingData& operator=(const NodeRenderingData&) = delete;
 
@@ -117,17 +118,21 @@
     layout_object_ = layout_object;
   }
 
-  const ComputedStyle* GetComputedStyle() const { return computed_style_; }
-  void SetComputedStyle(const ComputedStyle* computed_style);
+  const ComputedStyle* GetComputedStyle() const {
+    return computed_style_.get();
+  }
+  void SetComputedStyle(scoped_refptr<const ComputedStyle> computed_style);
 
   static NodeRenderingData& SharedEmptyData();
   bool IsSharedEmptyData() { return this == &SharedEmptyData(); }
 
-  void TraceAfterDispatch(Visitor* visitor) const;
+  void TraceAfterDispatch(Visitor* visitor) const {
+    NodeData::TraceAfterDispatch(visitor);
+  }
 
  private:
-  Member<LayoutObject> layout_object_;
-  Member<const ComputedStyle> computed_style_;
+  LayoutObject* layout_object_;
+  scoped_refptr<const ComputedStyle> computed_style_;
 };
 
 class GC_PLUGIN_IGNORE("Manual dispatch implemented in NodeData.") NodeRareData
diff --git a/third_party/blink/renderer/core/dom/parent_node.h b/third_party/blink/renderer/core/dom/parent_node.h
index 37b8d6a8..f8edef753 100644
--- a/third_party/blink/renderer/core/dom/parent_node.h
+++ b/third_party/blink/renderer/core/dom/parent_node.h
@@ -63,21 +63,35 @@
     return count;
   }
 
-  static void prepend(Node& node,
-                      const HeapVector<NodeOrStringOrTrustedScript>& nodes,
-                      ExceptionState& exception_state) {
+  static void prepend(
+      Node& node,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      ExceptionState& exception_state) {
     return node.Prepend(nodes, exception_state);
   }
 
-  static void append(Node& node,
-                     const HeapVector<NodeOrStringOrTrustedScript>& nodes,
-                     ExceptionState& exception_state) {
+  static void append(
+      Node& node,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      ExceptionState& exception_state) {
     return node.Append(nodes, exception_state);
   }
 
   static void replaceChildren(
       Node& node,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const HeapVector<NodeOrStringOrTrustedScript>& nodes,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       ExceptionState& exception_state) {
     return node.ReplaceChildren(nodes, exception_state);
   }
diff --git a/third_party/blink/renderer/core/dom/pseudo_element.cc b/third_party/blink/renderer/core/dom/pseudo_element.cc
index b45e302..b3d24f0 100644
--- a/third_party/blink/renderer/core/dom/pseudo_element.cc
+++ b/third_party/blink/renderer/core/dom/pseudo_element.cc
@@ -121,7 +121,7 @@
   }
 }
 
-ComputedStyle* PseudoElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> PseudoElement::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
   Element* parent = ParentOrShadowHostElement();
   return parent->StyleForPseudoElement(
@@ -129,12 +129,12 @@
       StyleRequest(pseudo_id_, parent->GetComputedStyle()));
 }
 
-ComputedStyle* PseudoElement::LayoutStyleForDisplayContents(
+scoped_refptr<ComputedStyle> PseudoElement::LayoutStyleForDisplayContents(
     const ComputedStyle& style) {
   // For display:contents we should not generate a box, but we generate a non-
   // observable inline box for pseudo elements to be able to locate the
   // anonymous layout objects for generated content during DetachLayoutTree().
-  ComputedStyle* layout_style =
+  scoped_refptr<ComputedStyle> layout_style =
       GetDocument().GetStyleResolver().CreateComputedStyle();
   layout_style->InheritFrom(style);
   layout_style->SetContent(style.GetContentData());
diff --git a/third_party/blink/renderer/core/dom/pseudo_element.h b/third_party/blink/renderer/core/dom/pseudo_element.h
index f4d27cf..ddd60d4 100644
--- a/third_party/blink/renderer/core/dom/pseudo_element.h
+++ b/third_party/blink/renderer/core/dom/pseudo_element.h
@@ -41,7 +41,8 @@
 
   PseudoElement(Element*, PseudoId);
 
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) override;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) override;
   void AttachLayoutTree(AttachContext&) override;
   bool LayoutObjectIsNeeded(const ComputedStyle&) const override;
   bool CanGeneratePseudoElement(PseudoId) const override;
@@ -49,7 +50,8 @@
   bool CanStartSelection() const override { return false; }
   bool CanContainRangeEndPoint() const override { return false; }
   PseudoId GetPseudoId() const override { return pseudo_id_; }
-  ComputedStyle* LayoutStyleForDisplayContents(const ComputedStyle&);
+  scoped_refptr<ComputedStyle> LayoutStyleForDisplayContents(
+      const ComputedStyle&);
 
   static const AtomicString& PseudoElementNameForEvents(PseudoId);
   static bool IsWebExposed(PseudoId, const Node*);
@@ -70,7 +72,7 @@
 
    private:
     PseudoElement* element_;
-    const ComputedStyle* original_style_ = nullptr;
+    scoped_refptr<const ComputedStyle> original_style_;
   };
 
   PseudoId pseudo_id_;
diff --git a/third_party/blink/renderer/core/dom/text.cc b/third_party/blink/renderer/core/dom/text.cc
index 5c168c71..f665be1 100644
--- a/third_party/blink/renderer/core/dom/text.cc
+++ b/third_party/blink/renderer/core/dom/text.cc
@@ -332,10 +332,10 @@
 LayoutText* Text::CreateTextLayoutObject(const ComputedStyle& style,
                                          LegacyLayout legacy) {
   if (IsSVGText(this))
-    return MakeGarbageCollected<LayoutSVGInlineText>(this, DataImpl());
+    return new LayoutSVGInlineText(this, DataImpl());
 
   if (style.HasTextCombine())
-    return MakeGarbageCollected<LayoutTextCombine>(this, DataImpl());
+    return new LayoutTextCombine(this, DataImpl());
 
   return LayoutObjectFactory::CreateText(this, DataImpl(), legacy);
 }
@@ -389,7 +389,7 @@
 }  // namespace
 
 void Text::RecalcTextStyle(const StyleRecalcChange change) {
-  const ComputedStyle* new_style =
+  scoped_refptr<const ComputedStyle> new_style =
       GetDocument().GetStyleResolver().StyleForText(this);
   if (LayoutText* layout_text = GetLayoutObject()) {
     const ComputedStyle* layout_parent_style =
diff --git a/third_party/blink/renderer/core/editing/caret_display_item_client.cc b/third_party/blink/renderer/core/editing/caret_display_item_client.cc
index fefaae0..faa4373b 100644
--- a/third_party/blink/renderer/core/editing/caret_display_item_client.cc
+++ b/third_party/blink/renderer/core/editing/caret_display_item_client.cc
@@ -143,7 +143,7 @@
   // We don't care about intermediate changes of LayoutBlock because they are
   // not painted.
   if (!previous_layout_block_)
-    previous_layout_block_ = layout_block_.Get();
+    previous_layout_block_ = layout_block_;
 
   CaretRectAndPainterBlock rect_and_block =
       ComputeCaretRectAndPainterBlock(caret_position);
diff --git a/third_party/blink/renderer/core/editing/caret_display_item_client.h b/third_party/blink/renderer/core/editing/caret_display_item_client.h
index c88a64d..274879b 100644
--- a/third_party/blink/renderer/core/editing/caret_display_item_client.h
+++ b/third_party/blink/renderer/core/editing/caret_display_item_client.h
@@ -33,7 +33,6 @@
 #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
 #include "third_party/blink/renderer/platform/graphics/color.h"
 #include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 
 namespace blink {
 
@@ -99,15 +98,15 @@
   // These are updated by updateStyleAndLayoutIfNeeded().
   Color color_;
   PhysicalRect local_rect_;
-  UntracedMember<LayoutBlock> layout_block_;
+  LayoutBlock* layout_block_ = nullptr;
 
   // This is set to the previous value of layout_block_ during
   // UpdateStyleAndLayoutIfNeeded() if it hasn't been set since the last paint
   // invalidation. It is used during InvalidatePaint() to invalidate the caret
   // in the previous layout block.
-  UntracedMember<const LayoutBlock> previous_layout_block_;
+  const LayoutBlock* previous_layout_block_ = nullptr;
 
-  UntracedMember<const NGPhysicalBoxFragment> box_fragment_;
+  const NGPhysicalBoxFragment* box_fragment_ = nullptr;
 
   bool needs_paint_invalidation_ = false;
   bool is_visible_if_active_ = true;
diff --git a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
index 8dfe6a66..b0955da 100644
--- a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
@@ -862,7 +862,7 @@
     return ReplaceTextInNode(text_node, start, end - start, string);
   }
 
-  HeapVector<Member<InlineTextBox>> sorted_text_boxes;
+  Vector<InlineTextBox*> sorted_text_boxes;
   wtf_size_t sorted_text_boxes_position = 0;
 
   for (InlineTextBox* text_box : text_layout_object->TextBoxes())
@@ -874,7 +874,7 @@
     std::sort(sorted_text_boxes.begin(), sorted_text_boxes.end(),
               InlineTextBox::CompareByStart);
   InlineTextBox* box = sorted_text_boxes.IsEmpty()
-                           ? nullptr
+                           ? 0
                            : sorted_text_boxes[sorted_text_boxes_position];
 
   unsigned removed = 0;
diff --git a/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc b/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc
index 19a5876..8f846d3 100644
--- a/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc
+++ b/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc
@@ -88,7 +88,7 @@
   for (LayoutObject* layout_object = document->GetLayoutView(); layout_object;
        layout_object = layout_object->NextInPreOrder()) {
     if (layout_object->Style()) {
-      ComputedStyle* modified_style =
+      scoped_refptr<ComputedStyle> modified_style =
           ComputedStyle::Clone(layout_object->StyleRef());
       modified_style->SetTextAutosizingMultiplier(multiplier);
       EXPECT_EQ(multiplier, modified_style->TextAutosizingMultiplier());
diff --git a/third_party/blink/renderer/core/editing/ime/cached_text_input_info.cc b/third_party/blink/renderer/core/editing/ime/cached_text_input_info.cc
index 358a0de..1d0f2ac 100644
--- a/third_party/blink/renderer/core/editing/ime/cached_text_input_info.cc
+++ b/third_party/blink/renderer/core/editing/ime/cached_text_input_info.cc
@@ -210,7 +210,6 @@
 
 void CachedTextInputInfo::Trace(Visitor* visitor) const {
   visitor->Trace(container_);
-  visitor->Trace(layout_object_);
   visitor->Trace(composition_);
   visitor->Trace(offset_map_);
   visitor->Trace(selection_);
diff --git a/third_party/blink/renderer/core/editing/ime/cached_text_input_info.h b/third_party/blink/renderer/core/editing/ime/cached_text_input_info.h
index c50d91b4..03f7e91b 100644
--- a/third_party/blink/renderer/core/editing/ime/cached_text_input_info.h
+++ b/third_party/blink/renderer/core/editing/ime/cached_text_input_info.h
@@ -73,7 +73,7 @@
   unsigned RangeLength(const EphemeralRange& range) const;
 
   mutable Member<const ContainerNode> container_;
-  mutable WeakMember<const LayoutObject> layout_object_;
+  mutable const LayoutObject* layout_object_ = nullptr;
   // Records offset of text node from start of |container_|.
   mutable HeapHashMap<Member<const Text>, unsigned> offset_map_;
   mutable String text_;
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc
index 5dece0c..3004b87 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc
@@ -317,8 +317,7 @@
     std::sort(sorted_text_boxes_.begin(), sorted_text_boxes_.end(),
               InlineTextBox::CompareByStart);
     sorted_text_boxes_position_ = 0;
-    text_box_ =
-        sorted_text_boxes_.IsEmpty() ? nullptr : sorted_text_boxes_[0].Get();
+    text_box_ = sorted_text_boxes_.IsEmpty() ? 0 : sorted_text_boxes_[0];
   }
 
   HandleTextBox();
@@ -393,8 +392,7 @@
       // Check for collapsed space at the start of this run.
       InlineTextBox* first_text_box =
           layout_object->ContainsReversedText()
-              ? (sorted_text_boxes_.IsEmpty() ? nullptr
-                                              : sorted_text_boxes_[0].Get())
+              ? (sorted_text_boxes_.IsEmpty() ? 0 : sorted_text_boxes_[0])
               : layout_object->FirstTextBox();
       const bool need_space = last_text_node_ended_with_collapsed_space_ ||
                               (text_box_ == first_text_box &&
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h
index 592b9ef..918f263 100644
--- a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h
+++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h
@@ -104,7 +104,7 @@
   bool last_text_node_ended_with_collapsed_space_ = false;
 
   // Used when text boxes are out of order (Hebrew/Arabic w/ embedded LTR text)
-  HeapVector<Member<InlineTextBox>> sorted_text_boxes_;
+  Vector<InlineTextBox*> sorted_text_boxes_;
   wtf_size_t sorted_text_boxes_position_ = 0;
 
   const TextIteratorBehavior behavior_;
diff --git a/third_party/blink/renderer/core/editing/serializers/text_offset.h b/third_party/blink/renderer/core/editing/serializers/text_offset.h
index 27c96b8c..e37a064 100644
--- a/third_party/blink/renderer/core/editing/serializers/text_offset.h
+++ b/third_party/blink/renderer/core/editing/serializers/text_offset.h
@@ -5,7 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_SERIALIZERS_TEXT_OFFSET_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_SERIALIZERS_TEXT_OFFSET_H_
 
-#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/exported/web_v8_features.cc b/third_party/blink/renderer/core/exported/web_v8_features.cc
index 90805b2..c913c51 100644
--- a/third_party/blink/renderer/core/exported/web_v8_features.cc
+++ b/third_party/blink/renderer/core/exported/web_v8_features.cc
@@ -32,14 +32,4 @@
   v8::V8::SetFlagsFromString(kSABFlag, sizeof(kSABFlag));
 }
 
-void WebV8Features::EnableWasmThreads() {
-  static bool wasm_threads_enabled = false;
-  if (wasm_threads_enabled)
-    return;
-
-  wasm_threads_enabled = true;
-  constexpr char kWasmThreadsFlag[] = "--experimental-wasm-threads";
-  v8::V8::SetFlagsFromString(kWasmThreadsFlag, sizeof(kWasmThreadsFlag));
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc
index 16ca9fb1..9261716 100644
--- a/third_party/blink/renderer/core/fetch/fetch_manager.cc
+++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -37,6 +37,7 @@
 #include "third_party/blink/renderer/core/frame/frame.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/inspector/inspector_audits_issue.h"
 #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
 #include "third_party/blink/renderer/core/loader/threadable_loader.h"
 #include "third_party/blink/renderer/core/loader/threadable_loader_client.h"
@@ -62,6 +63,7 @@
 #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
 #include "third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h"
+#include "third_party/blink/renderer/platform/loader/fetch/unique_identifier.h"
 #include "third_party/blink/renderer/platform/loader/subresource_integrity.h"
 #include "third_party/blink/renderer/platform/network/http_names.h"
 #include "third_party/blink/renderer/platform/network/network_utils.h"
@@ -254,6 +256,8 @@
  private:
   void PerformSchemeFetch();
   void PerformNetworkError(const String& message);
+  void FileIssueAndPerformNetworkError(RendererCorsIssueCode,
+                                       int64_t identifier);
   void PerformHTTPFetch();
   void PerformDataFetch();
   // If |dom_exception| is provided, throws the specified DOMException instead
@@ -555,12 +559,9 @@
 
   // "- |request|'s mode is |same-origin|"
   if (fetch_request_data_->Mode() == RequestMode::kSameOrigin) {
-    // "A network error."
-    PerformNetworkError("Fetch API cannot load " +
-                        fetch_request_data_->Url().GetString() +
-                        ". Request mode is \"same-origin\" but the URL\'s "
-                        "origin is not same as the request origin " +
-                        fetch_request_data_->Origin()->ToString() + ".");
+    // This error is so early that there isn't an identifier yet, generate one.
+    FileIssueAndPerformNetworkError(RendererCorsIssueCode::kDisallowedByMode,
+                                    CreateUniqueIdentifier());
     return;
   }
 
@@ -569,10 +570,11 @@
     // "If |request|'s redirect mode is not |follow|, then return a network
     // error.
     if (fetch_request_data_->Redirect() != RedirectMode::kFollow) {
-      PerformNetworkError("Fetch API cannot load " +
-                          fetch_request_data_->Url().GetString() +
-                          ". Request mode is \"no-cors\" but the redirect mode "
-                          "is not \"follow\".");
+      // This error is so early that there isn't an identifier yet, generate
+      // one.
+      FileIssueAndPerformNetworkError(
+          RendererCorsIssueCode::kNoCorsRedirectModeNotFollow,
+          CreateUniqueIdentifier());
       return;
     }
 
@@ -590,10 +592,9 @@
   // to SchemeRegistry::registerURLSchemeAsSupportingFetchAPI.
   if (!SchemeRegistry::ShouldTreatURLSchemeAsSupportingFetchAPI(
           fetch_request_data_->Url().Protocol())) {
-    // "A network error."
-    PerformNetworkError(
-        "Fetch API cannot load " + fetch_request_data_->Url().GetString() +
-        ". URL scheme must be \"http\" or \"https\" for CORS request.");
+    // This error is so early that there isn't an identifier yet, generate one.
+    FileIssueAndPerformNetworkError(RendererCorsIssueCode::kCorsDisabledScheme,
+                                    CreateUniqueIdentifier());
     return;
   }
 
@@ -651,10 +652,49 @@
     PerformDataFetch();
   } else {
     // FIXME: implement other protocols.
-    PerformNetworkError(
-        "Fetch API cannot load " + fetch_request_data_->Url().GetString() +
-        ". URL scheme \"" + fetch_request_data_->Url().Protocol() +
-        "\" is not supported.");
+    // This error is so early that there isn't an identifier yet, generate one.
+    FileIssueAndPerformNetworkError(RendererCorsIssueCode::kCorsDisabledScheme,
+                                    CreateUniqueIdentifier());
+  }
+}
+
+void FetchManager::Loader::FileIssueAndPerformNetworkError(
+    RendererCorsIssueCode network_error,
+    int64_t identifier) {
+  switch (network_error) {
+    case RendererCorsIssueCode::kCorsDisabledScheme:
+      AuditsIssue::ReportCorsIssue(GetExecutionContext(), identifier,
+                                   network_error,
+                                   fetch_request_data_->Url().GetString(),
+                                   fetch_request_data_->Origin()->ToString(),
+                                   fetch_request_data_->Url().Protocol());
+      PerformNetworkError(
+          "Fetch API cannot load " + fetch_request_data_->Url().GetString() +
+          ". URL scheme \"" + fetch_request_data_->Url().Protocol() +
+          "\" is not supported.");
+      break;
+    case RendererCorsIssueCode::kDisallowedByMode:
+      AuditsIssue::ReportCorsIssue(
+          GetExecutionContext(), identifier, network_error,
+          fetch_request_data_->Url().GetString(),
+          fetch_request_data_->Origin()->ToString(), WTF::g_empty_string);
+      PerformNetworkError("Fetch API cannot load " +
+                          fetch_request_data_->Url().GetString() +
+                          ". Request mode is \"same-origin\" but the URL\'s "
+                          "origin is not same as the request origin " +
+                          fetch_request_data_->Origin()->ToString() + ".");
+
+      break;
+    case RendererCorsIssueCode::kNoCorsRedirectModeNotFollow:
+      AuditsIssue::ReportCorsIssue(
+          GetExecutionContext(), identifier, network_error,
+          fetch_request_data_->Url().GetString(),
+          fetch_request_data_->Origin()->ToString(), WTF::g_empty_string);
+      PerformNetworkError("Fetch API cannot load " +
+                          fetch_request_data_->Url().GetString() +
+                          ". Request mode is \"no-cors\" but the redirect mode "
+                          "is not \"follow\".");
+      break;
   }
 }
 
diff --git a/third_party/blink/renderer/core/fetch/global_fetch.cc b/third_party/blink/renderer/core/fetch/global_fetch.cc
index 27cf9c4d..34cb98c 100644
--- a/third_party/blink/renderer/core/fetch/global_fetch.cc
+++ b/third_party/blink/renderer/core/fetch/global_fetch.cc
@@ -56,7 +56,11 @@
         fetch_manager_(MakeGarbageCollected<FetchManager>(execution_context)) {}
 
   ScriptPromise Fetch(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                      const V8RequestInfo* input,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                       const RequestInfo& input,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                       const RequestInit* init,
                       ExceptionState& exception_state) override {
     fetch_count_ += 1;
@@ -123,7 +127,11 @@
 
 ScriptPromise GlobalFetch::fetch(ScriptState* script_state,
                                  LocalDOMWindow& window,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                 const V8RequestInfo* input,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                  const RequestInfo& input,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                  const RequestInit* init,
                                  ExceptionState& exception_state) {
   UseCounter::Count(window.GetExecutionContext(), WebFeature::kFetch);
@@ -137,7 +145,11 @@
 
 ScriptPromise GlobalFetch::fetch(ScriptState* script_state,
                                  WorkerGlobalScope& worker,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                 const V8RequestInfo* input,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                  const RequestInfo& input,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                  const RequestInit* init,
                                  ExceptionState& exception_state) {
   UseCounter::Count(worker.GetExecutionContext(), WebFeature::kFetch);
diff --git a/third_party/blink/renderer/core/fetch/global_fetch.h b/third_party/blink/renderer/core/fetch/global_fetch.h
index 5bffc172..611fcf3 100644
--- a/third_party/blink/renderer/core/fetch/global_fetch.h
+++ b/third_party/blink/renderer/core/fetch/global_fetch.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_GLOBAL_FETCH_H_
 
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/fetch/request.h"
 
@@ -26,7 +27,11 @@
     virtual ~ScopedFetcher();
 
     virtual ScriptPromise Fetch(ScriptState*,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                const V8RequestInfo*,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                 const RequestInfo&,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                 const RequestInit*,
                                 ExceptionState&) = 0;
 
@@ -40,6 +45,18 @@
     void Trace(Visitor*) const override;
   };
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static ScriptPromise fetch(ScriptState* script_state,
+                             LocalDOMWindow& window,
+                             const V8RequestInfo* input,
+                             const RequestInit* init,
+                             ExceptionState& exception_state);
+  static ScriptPromise fetch(ScriptState* script_state,
+                             WorkerGlobalScope& worker,
+                             const V8RequestInfo* input,
+                             const RequestInit* init,
+                             ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static ScriptPromise fetch(ScriptState*,
                              LocalDOMWindow&,
                              const RequestInfo&,
@@ -50,6 +67,7 @@
                              const RequestInfo&,
                              const RequestInit*,
                              ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/fetch/headers.cc b/third_party/blink/renderer/core/fetch/headers.cc
index 81686d6..380a6fdc 100644
--- a/third_party/blink/renderer/core/fetch/headers.cc
+++ b/third_party/blink/renderer/core/fetch/headers.cc
@@ -6,6 +6,7 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/byte_string_sequence_sequence_or_byte_string_byte_string_record.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_bytestringbytestringrecord_bytestringsequencesequence.h"
 #include "third_party/blink/renderer/core/dom/iterator.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/loader/cors/cors.h"
@@ -49,6 +50,18 @@
   return MakeGarbageCollected<Headers>();
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+Headers* Headers::Create(const V8HeadersInit* init,
+                         ExceptionState& exception_state) {
+  // "The Headers(|init|) constructor, when invoked, must run these steps:"
+  // "1. Let |headers| be a new Headers object whose guard is "none".
+  Headers* headers = Create(exception_state);
+  // "2. If |init| is given, fill headers with |init|. Rethrow any exception."
+  headers->FillWith(init, exception_state);
+  // "3. Return |headers|."
+  return headers;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 Headers* Headers::Create(const HeadersInit& init,
                          ExceptionState& exception_state) {
   // "The Headers(|init|) constructor, when invoked, must run these steps:"
@@ -59,6 +72,7 @@
   // "3. Return |headers|."
   return headers;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 Headers* Headers::Create(FetchHeaderList* header_list) {
   return MakeGarbageCollected<Headers>(header_list);
@@ -257,6 +271,26 @@
   }
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void Headers::FillWith(const V8HeadersInit* init,
+                       ExceptionState& exception_state) {
+  DCHECK_EQ(header_list_->size(), 0U);
+
+  if (!init)
+    return;
+
+  switch (init->GetContentType()) {
+    case V8HeadersInit::ContentType::kByteStringByteStringRecord:
+      return FillWith(init->GetAsByteStringByteStringRecord(), exception_state);
+    case V8HeadersInit::ContentType::kByteStringSequenceSequence:
+      return FillWith(init->GetAsByteStringSequenceSequence(), exception_state);
+  }
+
+  NOTREACHED();
+}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+// TODO(crbug.com/1181288): Remove the old IDL union version.
 void Headers::FillWith(const HeadersInit& init,
                        ExceptionState& exception_state) {
   DCHECK_EQ(header_list_->size(), 0U);
diff --git a/third_party/blink/renderer/core/fetch/headers.h b/third_party/blink/renderer/core/fetch/headers.h
index 6a2fa45..c91fb20 100644
--- a/third_party/blink/renderer/core/fetch/headers.h
+++ b/third_party/blink/renderer/core/fetch/headers.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_HEADERS_H_
 
 #include "third_party/blink/renderer/bindings/core/v8/iterable.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/fetch/fetch_header_list.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -33,8 +34,13 @@
     kNoneGuard
   };
 
-  static Headers* Create(ExceptionState&);
+  static Headers* Create(ExceptionState& exception_state);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static Headers* Create(const V8HeadersInit* init,
+                         ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static Headers* Create(const HeadersInit&, ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Shares the FetchHeaderList. Called when creating a Request or Response.
   static Headers* Create(FetchHeaderList*);
@@ -57,6 +63,10 @@
 
   // These methods should only be called when size() would return 0.
   void FillWith(const Headers*, ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void FillWith(const V8HeadersInit* init, ExceptionState& exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  // TODO(crbug.com/1181288): Remove the old IDL union version.
   void FillWith(const HeadersInit&, ExceptionState&);
 
   // https://fetch.spec.whatwg.org/#concept-headers-remove-privileged-no-cors-request-headers
diff --git a/third_party/blink/renderer/core/fetch/request.cc b/third_party/blink/renderer/core/fetch/request.cc
index d49d977..be02f48 100644
--- a/third_party/blink/renderer/core/fetch/request.cc
+++ b/third_party/blink/renderer/core/fetch/request.cc
@@ -24,6 +24,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_request_init.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_trust_token.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_request_usvstring.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_url_search_params.h"
 #include "third_party/blink/renderer/core/dom/abort_signal.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -710,6 +711,25 @@
   return r;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+Request* Request::Create(ScriptState* script_state,
+                         const V8RequestInfo* input,
+                         const RequestInit* init,
+                         ExceptionState& exception_state) {
+  DCHECK(input);
+
+  switch (input->GetContentType()) {
+    case V8RequestInfo::ContentType::kRequest:
+      return Create(script_state, input->GetAsRequest(), init, exception_state);
+    case V8RequestInfo::ContentType::kUSVString:
+      return Create(script_state, input->GetAsUSVString(), init,
+                    exception_state);
+  }
+
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 Request* Request::Create(ScriptState* script_state,
                          const RequestInfo& input,
                          const RequestInit* init,
@@ -719,6 +739,7 @@
     return Create(script_state, input.GetAsUSVString(), init, exception_state);
   return Create(script_state, input.GetAsRequest(), init, exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 Request* Request::Create(ScriptState* script_state,
                          const String& input,
diff --git a/third_party/blink/renderer/core/fetch/request.h b/third_party/blink/renderer/core/fetch/request.h
index ed466ee..693c25c 100644
--- a/third_party/blink/renderer/core/fetch/request.h
+++ b/third_party/blink/renderer/core/fetch/request.h
@@ -11,6 +11,7 @@
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
 #include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/fetch/body.h"
 #include "third_party/blink/renderer/core/fetch/fetch_request_data.h"
@@ -41,10 +42,17 @@
   // These "create" function must be called with entering an appropriate
   // V8 context.
   // From Request.idl:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static Request* Create(ScriptState* script_state,
+                         const V8RequestInfo* input,
+                         const RequestInit* init,
+                         ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static Request* Create(ScriptState*,
                          const RequestInfo&,
                          const RequestInit*,
                          ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   static Request* Create(ScriptState*, const String&, ExceptionState&);
   static Request* Create(ScriptState*,
diff --git a/third_party/blink/renderer/core/fileapi/blob.cc b/third_party/blink/renderer/core/fileapi/blob.cc
index 04f3bc8..a441676 100644
--- a/third_party/blink/renderer/core/fileapi/blob.cc
+++ b/third_party/blink/renderer/core/fileapi/blob.cc
@@ -34,6 +34,7 @@
 #include <utility>
 
 #include "third_party/blink/renderer/bindings/core/v8/v8_blob_property_bag.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview_blob_usvstring.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/fetch/blob_bytes_consumer.h"
 #include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
@@ -112,12 +113,16 @@
 Blob::~Blob() = default;
 
 // static
-Blob* Blob::Create(
-    ExecutionContext* context,
-    const HeapVector<ArrayBufferOrArrayBufferViewOrBlobOrUSVString>& blob_parts,
-    const BlobPropertyBag* options) {
+Blob* Blob::Create(ExecutionContext* context,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                   const HeapVector<Member<V8BlobPart>>& blob_parts,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                   const HeapVector<
+                       ArrayBufferOrArrayBufferViewOrBlobOrUSVString>&
+                       blob_parts,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                   const BlobPropertyBag* options) {
   DCHECK(options->hasType());
-
   DCHECK(options->hasEndings());
   bool normalize_line_endings_to_native = (options->endings() == "native");
   if (normalize_line_endings_to_native)
@@ -149,6 +154,38 @@
       BlobDataHandle::Create(std::move(blob_data), blob_size));
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// static
+void Blob::PopulateBlobData(BlobData* blob_data,
+                            const HeapVector<Member<V8BlobPart>>& parts,
+                            bool normalize_line_endings_to_native) {
+  for (const auto& item : parts) {
+    switch (item->GetContentType()) {
+      case V8BlobPart::ContentType::kArrayBuffer: {
+        DOMArrayBuffer* array_buffer = item->GetAsArrayBuffer();
+        blob_data->AppendBytes(array_buffer->Data(),
+                               array_buffer->ByteLength());
+        break;
+      }
+      case V8BlobPart::ContentType::kArrayBufferView: {
+        auto&& array_buffer_view = item->GetAsArrayBufferView();
+        blob_data->AppendBytes(array_buffer_view->BaseAddress(),
+                               array_buffer_view->byteLength());
+        break;
+      }
+      case V8BlobPart::ContentType::kBlob: {
+        item->GetAsBlob()->AppendTo(*blob_data);
+        break;
+      }
+      case V8BlobPart::ContentType::kUSVString: {
+        blob_data->AppendText(item->GetAsUSVString(),
+                              normalize_line_endings_to_native);
+        break;
+      }
+    }
+  }
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 // static
 void Blob::PopulateBlobData(
     BlobData* blob_data,
@@ -172,6 +209,7 @@
     }
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 // static
 void Blob::ClampSliceOffsets(uint64_t size, int64_t& start, int64_t& end) {
diff --git a/third_party/blink/renderer/core/fileapi/blob.h b/third_party/blink/renderer/core/fileapi/blob.h
index cbcc155..10740b72 100644
--- a/third_party/blink/renderer/core/fileapi/blob.h
+++ b/third_party/blink/renderer/core/fileapi/blob.h
@@ -34,6 +34,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view_or_blob_or_usv_string.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/fileapi/url_registry.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h"
@@ -61,10 +62,16 @@
     return MakeGarbageCollected<Blob>(BlobDataHandle::Create());
   }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static Blob* Create(ExecutionContext* execution_context,
+                      const HeapVector<Member<V8BlobPart>>& blob_parts,
+                      const BlobPropertyBag* options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static Blob* Create(
       ExecutionContext*,
       const HeapVector<ArrayBufferOrArrayBufferViewOrBlobOrUSVString>&,
       const BlobPropertyBag*);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   static Blob* Create(const unsigned char* data,
                       size_t size,
@@ -121,10 +128,16 @@
   bool IsBlob() const override { return true; }
 
  protected:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static void PopulateBlobData(BlobData* blob_data,
+                               const HeapVector<Member<V8BlobPart>>& parts,
+                               bool normalize_line_endings_to_native);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static void PopulateBlobData(
       BlobData*,
       const HeapVector<ArrayBufferOrArrayBufferViewOrBlobOrUSVString>& parts,
       bool normalize_line_endings_to_native);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static void ClampSliceOffsets(uint64_t size, int64_t& start, int64_t& end);
 
   // Called by the Blob and File constructors when processing the 'type'
diff --git a/third_party/blink/renderer/core/fileapi/file.cc b/third_party/blink/renderer/core/fileapi/file.cc
index bd08b09..a812627 100644
--- a/third_party/blink/renderer/core/fileapi/file.cc
+++ b/third_party/blink/renderer/core/fileapi/file.cc
@@ -125,11 +125,16 @@
 }
 
 // static
-File* File::Create(
-    ExecutionContext* context,
-    const HeapVector<ArrayBufferOrArrayBufferViewOrBlobOrUSVString>& file_bits,
-    const String& file_name,
-    const FilePropertyBag* options) {
+File* File::Create(ExecutionContext* context,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                   const HeapVector<Member<V8BlobPart>>& file_bits,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                   const HeapVector<
+                       ArrayBufferOrArrayBufferViewOrBlobOrUSVString>&
+                       file_bits,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                   const String& file_name,
+                   const FilePropertyBag* options) {
   DCHECK(options->hasType());
 
   base::Time last_modified;
diff --git a/third_party/blink/renderer/core/fileapi/file.h b/third_party/blink/renderer/core/fileapi/file.h
index 4be6229d..06e1e1b6 100644
--- a/third_party/blink/renderer/core/fileapi/file.h
+++ b/third_party/blink/renderer/core/fileapi/file.h
@@ -63,11 +63,18 @@
   enum UserVisibility { kIsUserVisible, kIsNotUserVisible };
 
   // Constructor in File.idl
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static File* Create(ExecutionContext*,
+                      const HeapVector<Member<V8BlobPart>>& file_bits,
+                      const String& file_name,
+                      const FilePropertyBag* options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static File* Create(
       ExecutionContext*,
       const HeapVector<ArrayBufferOrArrayBufferViewOrBlobOrUSVString>&,
       const String& file_name,
       const FilePropertyBag*);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // For deserialization.
   static File* CreateFromSerialization(
diff --git a/third_party/blink/renderer/core/fileapi/file_reader.cc b/third_party/blink/renderer/core/fileapi/file_reader.cc
index 93221ba..8a8d09ac 100644
--- a/third_party/blink/renderer/core/fileapi/file_reader.cc
+++ b/third_party/blink/renderer/core/fileapi/file_reader.cc
@@ -34,6 +34,7 @@
 #include "base/timer/elapsed_timer.h"
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_array_buffer.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_string.h"
 #include "third_party/blink/renderer/core/events/progress_event.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/fileapi/file.h"
@@ -358,6 +359,26 @@
   ThrottlingController::FinishReader(GetExecutionContext(), this, final_step);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionArrayBufferOrString* FileReader::result() const {
+  if (error_ || !loader_)
+    return nullptr;
+
+  // Only set the result after |loader_| has finished loading which means that
+  // FileReader::DidFinishLoading() has also been called. This ensures that the
+  // result is not available until just before the kLoad event is fired.
+  if (!loader_->HasFinishedLoading() || state_ != ReadyState::kDone) {
+    return nullptr;
+  }
+
+  if (read_type_ == FileReaderLoader::kReadAsArrayBuffer) {
+    return MakeGarbageCollected<V8UnionArrayBufferOrString>(
+        loader_->ArrayBufferResult());
+  }
+  return MakeGarbageCollected<V8UnionArrayBufferOrString>(
+      loader_->StringResult());
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void FileReader::result(StringOrArrayBuffer& result_attribute) const {
   if (error_ || !loader_)
     return;
@@ -374,6 +395,7 @@
   else
     result_attribute.SetString(loader_->StringResult());
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void FileReader::Terminate() {
   if (loader_) {
diff --git a/third_party/blink/renderer/core/fileapi/file_reader.h b/third_party/blink/renderer/core/fileapi/file_reader.h
index 29b5a9d..fe23742 100644
--- a/third_party/blink/renderer/core/fileapi/file_reader.h
+++ b/third_party/blink/renderer/core/fileapi/file_reader.h
@@ -32,6 +32,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_FILE_READER_H_
 
 #include <memory>
+
 #include "base/timer/elapsed_timer.h"
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/core/core_export.h"
@@ -48,8 +49,9 @@
 class Blob;
 class ExceptionState;
 class ExecutionContext;
-enum class FileErrorCode;
 class StringOrArrayBuffer;
+class V8UnionArrayBufferOrString;
+enum class FileErrorCode;
 
 class CORE_EXPORT FileReader final : public EventTargetWithInlineData,
                                      public ActiveScriptWrappable<FileReader>,
@@ -74,7 +76,11 @@
 
   ReadyState getReadyState() const { return state_; }
   DOMException* error() { return error_; }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionArrayBufferOrString* result() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void result(StringOrArrayBuffer& result_attribute) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   probe::AsyncTaskId* async_task_id() { return &async_task_id_; }
 
   // ExecutionContextLifecycleObserver
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc
index 3870b1c..7e576e4 100644
--- a/third_party/blink/renderer/core/frame/deprecation.cc
+++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -515,7 +515,7 @@
 
     case WebFeature::kV8SharedArrayBufferConstructedWithoutIsolation:
       return {
-          "SharedArrayBufferConstructedWithoutIsolation", kM91,
+          "SharedArrayBufferConstructedWithoutIsolation", kM92,
           String::Format(
               "SharedArrayBuffer will require cross-origin isolation as of "
               "%s. See "
diff --git a/third_party/blink/renderer/core/frame/layout_subtree_root_list.cc b/third_party/blink/renderer/core/frame/layout_subtree_root_list.cc
index 844f746d..b24963fc 100644
--- a/third_party/blink/renderer/core/frame/layout_subtree_root_list.cc
+++ b/third_party/blink/renderer/core/frame/layout_subtree_root_list.cc
@@ -9,7 +9,7 @@
 namespace blink {
 
 void LayoutSubtreeRootList::ClearAndMarkContainingBlocksForLayout() {
-  for (const auto& iter : Unordered())
+  for (auto* const iter : Unordered())
     iter->MarkContainerChainForLayout(false);
   Clear();
 }
@@ -40,7 +40,7 @@
     unsigned& needs_layout_objects,
     unsigned& total_objects) {
   // TODO(leviw): This will double-count nested roots crbug.com/509141
-  for (const auto& root : Unordered())
+  for (auto* const root : Unordered())
     CountObjectsNeedingLayoutInRoot(root, needs_layout_objects, total_objects);
 }
 
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 1aada32..43ff529 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -63,6 +63,7 @@
 #include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom-shared.h"
 #include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
 #include "third_party/blink/public/platform/interface_registry.h"
+#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/scheduler/web_resource_loading_task_runner_handle.h"
 #include "third_party/blink/public/platform/url_conversion.h"
 #include "third_party/blink/public/platform/web_content_settings_client.h"
@@ -76,6 +77,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
 #include "third_party/blink/renderer/bindings/core/v8/source_location.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/core/clipboard/raw_system_clipboard.h"
+#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
 #include "third_party/blink/renderer/core/content_capture/content_capture_manager.h"
 #include "third_party/blink/renderer/core/core_initializer.h"
 #include "third_party/blink/renderer/core/core_probe_sink.h"
@@ -192,6 +195,7 @@
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
 #include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h
index b67f416..03e848a0 100644
--- a/third_party/blink/renderer/core/frame/local_frame.h
+++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -37,11 +37,10 @@
 #include "build/build_config.h"
 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/unique_receiver_set.h"
 #include "third_party/blink/public/common/frame/frame_ad_evidence.h"
 #include "third_party/blink/public/common/frame/payment_request_token.h"
 #include "third_party/blink/public/common/frame/transient_allow_fullscreen.h"
-#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
+#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/devtools/devtools_agent.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom-blink.h"
 #include "third_party/blink/public/mojom/frame/frame.mojom-blink.h"
@@ -50,29 +49,23 @@
 #include "third_party/blink/public/mojom/frame/reporting_observer.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/frame/viewport_intersection_state.mojom-blink.h"
 #include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
-#include "third_party/blink/public/mojom/link_to_text/link_to_text.mojom-blink.h"
+#include "third_party/blink/public/mojom/link_to_text/link_to_text.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/media/fullscreen_video_element.mojom-blink.h"
 #include "third_party/blink/public/mojom/optimization_guide/optimization_guide.mojom-blink.h"
 #include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h"
 #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink-forward.h"
 #include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/public/web/web_history_item.h"
 #include "third_party/blink/public/web/web_script_execution_callback.h"
-#include "third_party/blink/renderer/core/clipboard/raw_system_clipboard.h"
-#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/weak_identifier_map.h"
 #include "third_party/blink/renderer/core/editing/forward.h"
 #include "third_party/blink/renderer/core/frame/frame.h"
 #include "third_party/blink/renderer/core/frame/frame_types.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
-#include "third_party/blink/renderer/core/frame/policy_container.h"
-#include "third_party/blink/renderer/core/geometry/dom_rect.h"
 #include "third_party/blink/renderer/core/loader/frame_loader.h"
 #include "third_party/blink/renderer/platform/graphics/touch_action.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
 #include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h"
 #include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h"
 #include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
@@ -86,7 +79,6 @@
 #if defined(OS_MAC)
 #include "third_party/blink/public/mojom/input/text_input_host.mojom-blink.h"
 #endif
-#include "ui/gfx/range/range.h"
 #include "ui/gfx/transform.h"
 
 namespace base {
@@ -95,13 +87,8 @@
 
 namespace gfx {
 class Point;
-}
-
-#if defined(OS_MAC)
-namespace gfx {
 class Range;
 }
-#endif
 
 namespace blink {
 
@@ -118,7 +105,6 @@
 class FloatSize;
 class FrameConsole;
 class FrameOverlay;
-// class FrameScheduler;
 class FrameSelection;
 class FrameWidget;
 class InputMethodController;
@@ -137,7 +123,10 @@
 class Node;
 class NodeTraversal;
 class PerformanceMonitor;
+class PolicyContainer;
 class PluginData;
+class RawSystemClipboard;
+class SystemClipboard;
 class SmoothScrollSequencer;
 class SpellChecker;
 class TextFragmentHandler;
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 91fddf4..d86aea9 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -291,16 +291,11 @@
 }
 
 void LocalFrameView::Trace(Visitor* visitor) const {
-  visitor->Trace(part_update_set_);
   visitor->Trace(frame_);
   visitor->Trace(update_plugins_timer_);
-  visitor->Trace(layout_subtree_root_list_);
-  visitor->Trace(orthogonal_writing_mode_root_list_);
   visitor->Trace(fragment_anchor_);
   visitor->Trace(scrollable_areas_);
   visitor->Trace(animating_scrollable_areas_);
-  visitor->Trace(viewport_constrained_objects_);
-  visitor->Trace(background_attachment_fixed_objects_);
   visitor->Trace(auto_size_info_);
   visitor->Trace(plugins_);
   visitor->Trace(scrollbars_);
@@ -437,7 +432,7 @@
   // are missed. It would be good to understand how/why that happens, but in the
   // mean time, it's not safe to keep pointers around to defunct LayoutObjects.
   orthogonal_writing_mode_root_list_.Clear();
-  viewport_constrained_objects_.Clear();
+  viewport_constrained_objects_.reset();
   background_attachment_fixed_objects_.clear();
 
   // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing
@@ -789,7 +784,7 @@
         analyzer_->Increment(LayoutAnalyzer::kPerformLayoutRootLayoutObjects,
                              layout_subtree_root_list_.size());
       }
-      HeapHashSet<Member<LayoutBlock>> fragment_tree_spines;
+      HashSet<LayoutBlock*> fragment_tree_spines;
       for (auto& root : layout_subtree_root_list_.Ordered()) {
         if (!LayoutFromRootObject(*root))
           continue;
@@ -812,7 +807,7 @@
       }
       layout_subtree_root_list_.Clear();
       // Ensure fragment-tree consistency after a subtree layout.
-      for (auto cb : fragment_tree_spines)
+      for (auto* cb : fragment_tree_spines)
         cb->RebuildFragmentTreeSpine();
       fragment_tree_spines.clear();
     } else {
@@ -859,7 +854,7 @@
 
   base::Optional<RuntimeCallTimerScope> rcs_scope;
   probe::UpdateLayout probe(GetFrame().GetDocument());
-  HeapVector<LayoutObjectWithDepth> layout_roots;
+  Vector<LayoutObjectWithDepth> layout_roots;
 
   TRACE_EVENT_BEGIN0("blink,benchmark", "LocalFrameView::layout");
   if (UNLIKELY(RuntimeEnabledFeatures::BlinkRuntimeCallStatsEnabled())) {
@@ -1153,8 +1148,8 @@
   if (background_attachment_fixed_objects_.size() > 1)
     return true;
 
-  const auto* object = To<LayoutBoxModelObject>(
-      background_attachment_fixed_objects_.begin()->Get());
+  const auto* object =
+      To<LayoutBoxModelObject>(*background_attachment_fixed_objects_.begin());
   // We should not add such object in the set.
   DCHECK(!object->BackgroundTransfersToView());
   // If the background is viewport background and it paints onto the main
@@ -1169,7 +1164,7 @@
     LayoutObject& object,
     ViewportConstrainedType constrained_reason) {
   if (!viewport_constrained_objects_)
-    viewport_constrained_objects_ = MakeGarbageCollected<ObjectSet>();
+    viewport_constrained_objects_ = std::make_unique<ObjectSet>();
 
   auto result = viewport_constrained_objects_->insert(&object);
   if (constrained_reason == ViewportConstrainedType::kSticky) {
@@ -1243,7 +1238,9 @@
   if (!HasViewportConstrainedObjects() || !(width_changed || height_changed))
     return;
 
-  for (const auto& layout_object : *viewport_constrained_objects_) {
+  for (auto* const viewport_constrained_object :
+       *viewport_constrained_objects_) {
+    LayoutObject* layout_object = viewport_constrained_object;
     const ComputedStyle& style = layout_object->StyleRef();
     if (width_changed) {
       if (style.Width().IsFixed() &&
@@ -1275,7 +1272,7 @@
 
 void LocalFrameView::InvalidateBackgroundAttachmentFixedDescendantsOnScroll(
     const LayoutObject& scrolled_object) {
-  for (const auto& layout_object : background_attachment_fixed_objects_) {
+  for (auto* const layout_object : background_attachment_fixed_objects_) {
     if (scrolled_object != GetLayoutView() &&
         !layout_object->IsDescendantOf(&scrolled_object))
       continue;
@@ -1292,11 +1289,13 @@
 
 bool LocalFrameView::InvalidateViewportConstrainedObjects() {
   bool fast_path_allowed = true;
-  for (const auto& layout_object : *viewport_constrained_objects_) {
+  for (auto* const viewport_constrained_object :
+       *viewport_constrained_objects_) {
+    LayoutObject* layout_object = viewport_constrained_object;
     DCHECK(layout_object->StyleRef().HasViewportConstrainedPosition() ||
            layout_object->StyleRef().HasStickyConstrainedPosition());
     DCHECK(layout_object->HasLayer());
-    PaintLayer* layer = To<LayoutBoxModelObject>(layout_object.Get())->Layer();
+    PaintLayer* layer = To<LayoutBoxModelObject>(layout_object)->Layer();
 
     if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
       DisableCompositingQueryAsserts disabler;
@@ -1818,15 +1817,10 @@
 
   for (const auto& embedded_object : objects) {
     LayoutEmbeddedObject& object = *embedded_object;
-
-#if DCHECK_IS_ON()
-    if (object.is_destroyed_)
-      continue;
-#endif
-
     auto* element = To<HTMLPlugInElement>(object.GetNode());
 
-    // The object may have already been destroyed (thus node cleared).
+    // The object may have already been destroyed (thus node cleared),
+    // but LocalFrameView holds a manual ref, so it won't have been deleted.
     if (!element)
       continue;
 
@@ -1834,7 +1828,7 @@
     if (object.ShowsUnavailablePluginIndicator())
       continue;
 
-    if (element->NeedsPluginUpdate() && element->GetLayoutObject())
+    if (element->NeedsPluginUpdate())
       element->UpdatePlugin();
     if (EmbeddedContentView* view = element->OwnedEmbeddedContentView())
       view->UpdateGeometry();
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h
index f3b2c05..171017d 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.h
+++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -298,11 +298,11 @@
   // or sticky so that we can support HasStickyViewportConstrainedObject().
   enum ViewportConstrainedType { kFixed = 0, kSticky = 1 };
   // Fixed-position and viewport-constrained sticky-position objects.
-  typedef HeapHashSet<Member<LayoutObject>> ObjectSet;
+  typedef HashSet<LayoutObject*> ObjectSet;
   void AddViewportConstrainedObject(LayoutObject&, ViewportConstrainedType);
   void RemoveViewportConstrainedObject(LayoutObject&, ViewportConstrainedType);
   const ObjectSet* ViewportConstrainedObjects() const {
-    return viewport_constrained_objects_;
+    return viewport_constrained_objects_.get();
   }
   bool HasViewportConstrainedObjects() const {
     return viewport_constrained_objects_ &&
@@ -975,7 +975,7 @@
 
   LayoutSize size_;
 
-  typedef HeapHashSet<Member<LayoutEmbeddedObject>> EmbeddedObjectSet;
+  typedef HashSet<scoped_refptr<LayoutEmbeddedObject>> EmbeddedObjectSet;
   EmbeddedObjectSet part_update_set_;
 
   Member<LocalFrame> frame_;
@@ -1014,7 +1014,7 @@
 
   Member<ScrollableAreaSet> scrollable_areas_;
   Member<ScrollableAreaSet> animating_scrollable_areas_;
-  Member<ObjectSet> viewport_constrained_objects_;
+  std::unique_ptr<ObjectSet> viewport_constrained_objects_;
   // Number of entries in viewport_constrained_objects_ that are sticky.
   unsigned sticky_position_object_count_;
   ObjectSet background_attachment_fixed_objects_;
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc
index 20898c7..b89dca41b 100644
--- a/third_party/blink/renderer/core/frame/web_frame_test.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -1314,7 +1314,7 @@
   for (LayoutObject* layout_object = document->GetLayoutView(); layout_object;
        layout_object = layout_object->NextInPreOrder()) {
     if (layout_object->Style()) {
-      ComputedStyle* modified_style =
+      scoped_refptr<ComputedStyle> modified_style =
           ComputedStyle::Clone(layout_object->StyleRef());
       modified_style->SetTextAutosizingMultiplier(multiplier);
       EXPECT_EQ(multiplier, modified_style->TextAutosizingMultiplier());
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index 71fc95c..223c7da 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -146,6 +146,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
 #include "third_party/blink/renderer/core/clipboard/clipboard_utilities.h"
+#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
 #include "third_party/blink/renderer/core/core_initializer.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/icon_url.h"
diff --git a/third_party/blink/renderer/core/geometry/dom_matrix.cc b/third_party/blink/renderer/core/geometry/dom_matrix.cc
index a20e8bda..d89695e 100644
--- a/third_party/blink/renderer/core/geometry/dom_matrix.cc
+++ b/third_party/blink/renderer/core/geometry/dom_matrix.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/geometry/dom_matrix.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unrestricteddoublesequence.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/platform/transforms/affine_transform.h"
 
@@ -19,6 +20,45 @@
   return MakeGarbageCollected<DOMMatrix>(TransformationMatrix());
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+DOMMatrix* DOMMatrix::Create(
+    ExecutionContext* execution_context,
+    const V8UnionStringOrUnrestrictedDoubleSequence* init,
+    ExceptionState& exception_state) {
+  DCHECK(init);
+
+  switch (init->GetContentType()) {
+    case V8UnionStringOrUnrestrictedDoubleSequence::ContentType::kString: {
+      if (!execution_context->IsWindow()) {
+        exception_state.ThrowTypeError(
+            "DOMMatrix can't be constructed with strings on workers.");
+        return nullptr;
+      }
+
+      DOMMatrix* matrix =
+          MakeGarbageCollected<DOMMatrix>(TransformationMatrix());
+      matrix->SetMatrixValueFromString(execution_context, init->GetAsString(),
+                                       exception_state);
+      return matrix;
+    }
+    case V8UnionStringOrUnrestrictedDoubleSequence::ContentType::
+        kUnrestrictedDoubleSequence: {
+      const Vector<double>& sequence = init->GetAsUnrestrictedDoubleSequence();
+      if (sequence.size() != 6 && sequence.size() != 16) {
+        exception_state.ThrowTypeError(
+            "The sequence must contain 6 elements for a 2D matrix or 16 "
+            "elements "
+            "for a 3D matrix.");
+        return nullptr;
+      }
+      return MakeGarbageCollected<DOMMatrix>(sequence, sequence.size());
+    }
+  }
+
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 DOMMatrix* DOMMatrix::Create(ExecutionContext* execution_context,
                              StringOrUnrestrictedDoubleSequence& init,
                              ExceptionState& exception_state) {
@@ -49,6 +89,7 @@
   NOTREACHED();
   return nullptr;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 DOMMatrix* DOMMatrix::Create(DOMMatrixReadOnly* other,
                              ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/core/geometry/dom_matrix.h b/third_party/blink/renderer/core/geometry/dom_matrix.h
index c1f25bf0..168c5e6 100644
--- a/third_party/blink/renderer/core/geometry/dom_matrix.h
+++ b/third_party/blink/renderer/core/geometry/dom_matrix.h
@@ -13,6 +13,7 @@
 namespace blink {
 
 class DOMMatrixInit;
+class V8UnionStringOrUnrestrictedDoubleSequence;
 
 class CORE_EXPORT DOMMatrix : public DOMMatrixReadOnly {
   DEFINE_WRAPPERTYPEINFO();
@@ -20,9 +21,16 @@
  public:
   static DOMMatrix* Create();
   static DOMMatrix* Create(ExecutionContext*, ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static DOMMatrix* Create(
+      ExecutionContext* execution_context,
+      const V8UnionStringOrUnrestrictedDoubleSequence* init,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static DOMMatrix* Create(ExecutionContext*,
                            StringOrUnrestrictedDoubleSequence&,
                            ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // TODO(fserb): double check those two bellow are needed:
   static DOMMatrix* Create(DOMMatrixReadOnly*,
                            ExceptionState& = ASSERT_NO_EXCEPTION);
diff --git a/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc b/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc
index 5bf3eba..084f552 100644
--- a/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc
+++ b/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc
@@ -8,6 +8,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_init.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unrestricteddoublesequence.h"
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
 #include "third_party/blink/renderer/core/css/css_value_list.h"
@@ -106,6 +107,45 @@
   return MakeGarbageCollected<DOMMatrixReadOnly>(TransformationMatrix());
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+DOMMatrixReadOnly* DOMMatrixReadOnly::Create(
+    ExecutionContext* execution_context,
+    const V8UnionStringOrUnrestrictedDoubleSequence* init,
+    ExceptionState& exception_state) {
+  DCHECK(init);
+
+  switch (init->GetContentType()) {
+    case V8UnionStringOrUnrestrictedDoubleSequence::ContentType::kString: {
+      if (!execution_context->IsWindow()) {
+        exception_state.ThrowTypeError(
+            "DOMMatrix can't be constructed with strings on workers.");
+        return nullptr;
+      }
+
+      DOMMatrixReadOnly* matrix =
+          MakeGarbageCollected<DOMMatrixReadOnly>(TransformationMatrix());
+      matrix->SetMatrixValueFromString(execution_context, init->GetAsString(),
+                                       exception_state);
+      return matrix;
+    }
+    case V8UnionStringOrUnrestrictedDoubleSequence::ContentType::
+        kUnrestrictedDoubleSequence: {
+      const Vector<double>& sequence = init->GetAsUnrestrictedDoubleSequence();
+      if (sequence.size() != 6 && sequence.size() != 16) {
+        exception_state.ThrowTypeError(
+            "The sequence must contain 6 elements for a 2D matrix or 16 "
+            "elements "
+            "for a 3D matrix.");
+        return nullptr;
+      }
+      return MakeGarbageCollected<DOMMatrixReadOnly>(sequence, sequence.size());
+    }
+  }
+
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 DOMMatrixReadOnly* DOMMatrixReadOnly::Create(
     ExecutionContext* execution_context,
     const StringOrUnrestrictedDoubleSequence& init,
@@ -138,6 +178,7 @@
   NOTREACHED();
   return nullptr;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 DOMMatrixReadOnly* DOMMatrixReadOnly::CreateForSerialization(double sequence[],
                                                              int size) {
diff --git a/third_party/blink/renderer/core/geometry/dom_matrix_read_only.h b/third_party/blink/renderer/core/geometry/dom_matrix_read_only.h
index 840305a..ec6fd9930 100644
--- a/third_party/blink/renderer/core/geometry/dom_matrix_read_only.h
+++ b/third_party/blink/renderer/core/geometry/dom_matrix_read_only.h
@@ -16,20 +16,28 @@
 
 namespace blink {
 
+class DOMMatrix2DInit;
 class DOMMatrix;
 class DOMMatrixInit;
-class DOMMatrix2DInit;
 class DOMPoint;
 class DOMPointInit;
+class V8UnionStringOrUnrestrictedDoubleSequence;
 
 class CORE_EXPORT DOMMatrixReadOnly : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
   static DOMMatrixReadOnly* Create(ExecutionContext*, ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static DOMMatrixReadOnly* Create(
+      ExecutionContext* execution_context,
+      const V8UnionStringOrUnrestrictedDoubleSequence* init,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static DOMMatrixReadOnly* Create(ExecutionContext*,
                                    const StringOrUnrestrictedDoubleSequence&,
                                    ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static DOMMatrixReadOnly* fromFloat32Array(NotShared<DOMFloat32Array>,
                                              ExceptionState&);
   static DOMMatrixReadOnly* fromFloat64Array(NotShared<DOMFloat64Array>,
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc
index b1a2533b6..76be97de 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc
+++ b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc
@@ -72,8 +72,10 @@
   if (!parsed_style)
     return false;
 
-  ComputedStyle* font_style = ComputedStyle::Clone(*default_font_style_);
-  document_->GetStyleEngine().ComputeFont(element, font_style, *parsed_style);
+  scoped_refptr<ComputedStyle> font_style =
+      ComputedStyle::Clone(*default_font_style_.get());
+  document_->GetStyleEngine().ComputeFont(element, font_style.get(),
+                                          *parsed_style);
   fonts_resolved_using_default_style_.insert(font_string,
                                              font_style->GetFont());
   resolved_font = fonts_resolved_using_default_style_.find(font_string)->value;
@@ -145,7 +147,6 @@
 void CanvasFontCache::Trace(Visitor* visitor) const {
   visitor->Trace(fetched_fonts_);
   visitor->Trace(document_);
-  visitor->Trace(default_font_style_);
 }
 
 void CanvasFontCache::Dispose() {
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h
index c7976af..f277df3 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h
+++ b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h
@@ -64,7 +64,7 @@
   LinkedHashSet<String> font_lru_list_;
   std::unique_ptr<FontCachePurgePreventer> main_cache_purge_preventer_;
   Member<Document> document_;
-  Member<ComputedStyle> default_font_style_;
+  scoped_refptr<ComputedStyle> default_font_style_;
   bool pruning_scheduled_;
 };
 
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
index 4dd9e610..c97fa9a 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
+++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
@@ -45,6 +45,10 @@
 class CanvasImageSource;
 class HTMLCanvasElement;
 class ImageBitmap;
+class
+    V8UnionCanvasRenderingContext2DOrGPUCanvasContextOrImageBitmapRenderingContextOrWebGL2RenderingContextOrWebGLRenderingContext;
+class
+    V8UnionGPUCanvasContextOrImageBitmapRenderingContextOrOffscreenCanvasRenderingContext2DOrWebGL2RenderingContextOrWebGLRenderingContext;
 
 class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable,
                                            public Thread::TaskObserver {
@@ -121,11 +125,25 @@
   // called when the context is first displayed.
   virtual void SetIsBeingDisplayed(bool) = 0;
   virtual bool isContextLost() const { return true; }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  // TODO(fserb): remove AsV8RenderingContext and AsV8OffscreenRenderingContext.
+  virtual V8UnionCanvasRenderingContext2DOrGPUCanvasContextOrImageBitmapRenderingContextOrWebGL2RenderingContextOrWebGLRenderingContext*
+  AsV8RenderingContext() {
+    NOTREACHED();
+    return nullptr;
+  }
+  virtual V8UnionGPUCanvasContextOrImageBitmapRenderingContextOrOffscreenCanvasRenderingContext2DOrWebGL2RenderingContextOrWebGLRenderingContext*
+  AsV8OffscreenRenderingContext() {
+    NOTREACHED();
+    return nullptr;
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // TODO(fserb): remove SetCanvasGetContextResult.
   virtual void SetCanvasGetContextResult(RenderingContext&) { NOTREACHED(); }
   virtual void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) {
     NOTREACHED();
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   virtual bool IsPaintable() const = 0;
   virtual void DidDraw(const SkIRect& dirty_rect);
   virtual void DidDraw();
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index 4e7fc84..25380b4 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -189,10 +189,10 @@
       GetExecutionContext()->CanExecuteScripts(kNotAboutToExecuteScript)) {
     // Allocation of a layout object indicates that the canvas doesn't
     // have display:none set, so is conceptually being displayed.
-    if (context_) {
+    if (context_)
       context_->SetIsBeingDisplayed(GetLayoutObject() && style_is_visible_);
-    }
-    return MakeGarbageCollected<LayoutHTMLCanvas>(this);
+
+    return new LayoutHTMLCanvas(this);
   }
   return HTMLElement::CreateLayoutObject(style, legacy);
 }
diff --git a/third_party/blink/renderer/core/html/canvas/image_data.cc b/third_party/blink/renderer/core/html/canvas/image_data.cc
index 153ad4a..f0b85fc 100644
--- a/third_party/blink/renderer/core/html/canvas/image_data.cc
+++ b/third_party/blink/renderer/core/html/canvas/image_data.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_uint8_clamped_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_float32array_uint16array_uint8clampedarray.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/html/canvas/predefined_color_space.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
@@ -367,6 +368,19 @@
 }
 
 bool ImageData::IsBufferBaseDetached() const {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (data_->GetContentType()) {
+    case V8ImageDataArray::ContentType::kFloat32Array:
+      return data_->GetAsFloat32Array()->BufferBase()->IsDetached();
+    case V8ImageDataArray::ContentType::kUint16Array:
+      return data_->GetAsUint16Array()->BufferBase()->IsDetached();
+    case V8ImageDataArray::ContentType::kUint8ClampedArray:
+      return data_->GetAsUint8ClampedArray()->BufferBase()->IsDetached();
+  }
+
+  NOTREACHED();
+  return false;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (data_.IsUint8ClampedArray())
     return data_.GetAsUint8ClampedArray()->BufferBase()->IsDetached();
   if (data_.IsUint16Array())
@@ -374,12 +388,29 @@
   if (data_.IsFloat32Array())
     return data_.GetAsFloat32Array()->BufferBase()->IsDetached();
   return false;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 SkPixmap ImageData::GetSkPixmap() const {
   CHECK(!IsBufferBaseDetached());
   SkColorType color_type = kRGBA_8888_SkColorType;
   const void* data = nullptr;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (data_->GetContentType()) {
+    case V8ImageDataArray::ContentType::kFloat32Array:
+      color_type = kRGBA_F32_SkColorType;
+      data = data_->GetAsFloat32Array()->Data();
+      break;
+    case V8ImageDataArray::ContentType::kUint16Array:
+      color_type = kR16G16B16A16_unorm_SkColorType;
+      data = data_->GetAsUint16Array()->Data();
+      break;
+    case V8ImageDataArray::ContentType::kUint8ClampedArray:
+      color_type = kRGBA_8888_SkColorType;
+      data = data_->GetAsUint8ClampedArray()->Data();
+      break;
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (data_.IsUint8ClampedArray()) {
     color_type = kRGBA_8888_SkColorType;
     data = data_.GetAsUint8ClampedArray()->Data();
@@ -390,6 +421,7 @@
     color_type = kRGBA_F32_SkColorType;
     data = data_.GetAsFloat32Array()->Data();
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   SkImageInfo info =
       SkImageInfo::Make(width(), height(), color_type, kUnpremul_SkAlphaType,
                         CanvasColorSpaceToSkColorSpace(GetCanvasColorSpace()));
@@ -412,6 +444,30 @@
   wrapper = ScriptWrappable::AssociateWithWrapper(isolate, wrapper_type_info,
                                                   wrapper);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  if (data_->IsUint8ClampedArray()) {
+    // Create a V8 object with |data_| and set the "data" property
+    // of the ImageData object to the created v8 object, eliminating the
+    // C++ callback when accessing the "data" property.
+    //
+    // This is a perf hack breaking the web interop.
+
+    v8::Local<v8::Value> v8_data;
+    ScriptState* script_state = ScriptState::From(wrapper->CreationContext());
+    if (!ToV8Traits<V8ImageDataArray>::ToV8(script_state, data_)
+             .ToLocal(&v8_data)) {
+      return wrapper;
+    }
+    bool defined_property;
+    if (!wrapper
+             ->DefineOwnProperty(isolate->GetCurrentContext(),
+                                 V8AtomicString(isolate, "data"), v8_data,
+                                 v8::ReadOnly)
+             .To(&defined_property)) {
+      return wrapper;
+    }
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (data_.IsUint8ClampedArray()) {
     // Create a V8 object with |data_| and set the "data" property
     // of the ImageData object to the created v8 object, eliminating the
@@ -434,6 +490,7 @@
       return wrapper;
     }
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   return wrapper;
 }
@@ -465,30 +522,42 @@
                 DOMArrayBufferView::ViewType::kTypeUint8Clamped);
       data_u8_ = data;
       DCHECK(data_u8_);
-      data_.SetUint8ClampedArray(data_u8_);
       SECURITY_CHECK(
           (base::CheckedNumeric<size_t>(size.Width()) * size.Height() * 4)
-              .ValueOrDie() <= data_.GetAsUint8ClampedArray()->length());
+              .ValueOrDie() <= data_u8_->length());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      data_ = MakeGarbageCollected<V8ImageDataArray>(data_u8_);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      data_.SetUint8ClampedArray(data_u8_);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       break;
 
     case kUint16ArrayStorageFormat:
       DCHECK_EQ(data->GetType(), DOMArrayBufferView::ViewType::kTypeUint16);
       data_u16_ = data;
       DCHECK(data_u16_);
-      data_.SetUint16Array(data_u16_);
       SECURITY_CHECK(
           (base::CheckedNumeric<size_t>(size.Width()) * size.Height() * 4)
-              .ValueOrDie() <= data_.GetAsUint16Array()->length());
+              .ValueOrDie() <= data_u16_->length());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      data_ = MakeGarbageCollected<V8ImageDataArray>(data_u16_);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      data_.SetUint16Array(data_u16_);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       break;
 
     case kFloat32ArrayStorageFormat:
       DCHECK_EQ(data->GetType(), DOMArrayBufferView::ViewType::kTypeFloat32);
       data_f32_ = data;
       DCHECK(data_f32_);
-      data_.SetFloat32Array(data_f32_);
       SECURITY_CHECK(
           (base::CheckedNumeric<size_t>(size.Width()) * size.Height() * 4)
-              .ValueOrDie() <= data_.GetAsFloat32Array()->length());
+              .ValueOrDie() <= data_f32_->length());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      data_ = MakeGarbageCollected<V8ImageDataArray>(data_f32_);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      data_.SetFloat32Array(data_f32_);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       break;
 
     default:
diff --git a/third_party/blink/renderer/core/html/canvas/image_data.h b/third_party/blink/renderer/core/html/canvas/image_data.h
index 37fb3436..2934dc8 100644
--- a/third_party/blink/renderer/core/html/canvas/image_data.h
+++ b/third_party/blink/renderer/core/html/canvas/image_data.h
@@ -32,6 +32,7 @@
 #include "base/numerics/checked_math.h"
 #include "third_party/blink/renderer/bindings/core/v8/uint8_clamped_array_or_uint16_array_or_float32_array.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_image_data_settings.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h"
@@ -178,9 +179,13 @@
   // TODO(https://crbug.com/1198606): Remove this.
   ImageDataSettings* getSettings() const;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const V8ImageDataArray* data() const { return data_; }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ImageDataArray& data() { return data_; }
   const ImageDataArray& data() const { return data_; }
   void data(ImageDataArray& result) { result = data_; }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   bool IsBufferBaseDetached() const;
   CanvasColorSpace GetCanvasColorSpace() const;
@@ -207,7 +212,11 @@
   IntSize size_;
   // TODO(https://crbug.com/1198606): Remove this.
   Member<ImageDataSettings> settings_;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Member<V8ImageDataArray> data_;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ImageDataArray data_;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   NotShared<DOMUint8ClampedArray> data_u8_;
   NotShared<DOMUint16Array> data_u16_;
   NotShared<DOMFloat32Array> data_f32_;
diff --git a/third_party/blink/renderer/core/html/custom/custom_element.cc b/third_party/blink/renderer/core/html/custom/custom_element.cc
index 0a13fbd..26115f16 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element.cc
+++ b/third_party/blink/renderer/core/html/custom/custom_element.cc
@@ -272,6 +272,17 @@
   }
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void CustomElement::EnqueueFormStateRestoreCallback(Element& element,
+                                                    const V8ControlValue* value,
+                                                    const String& mode) {
+  auto& definition = *DefinitionForElementWithoutCheck(element);
+  if (definition.HasFormStateRestoreCallback()) {
+    Enqueue(element, CustomElementReactionFactory::CreateFormStateRestore(
+                         definition, value, mode));
+  }
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void CustomElement::EnqueueFormStateRestoreCallback(
     Element& element,
     const FileOrUSVStringOrFormData& value,
@@ -282,6 +293,7 @@
                          definition, value, mode));
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void CustomElement::TryToUpgrade(Element& element) {
   // Try to upgrade an element
diff --git a/third_party/blink/renderer/core/html/custom/custom_element.h b/third_party/blink/renderer/core/html/custom/custom_element.h
index e30afccf..d320afe 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element.h
+++ b/third_party/blink/renderer/core/html/custom/custom_element.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_CUSTOM_ELEMENT_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_CUSTOM_ELEMENT_H_
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/create_element_flags.h"
 #include "third_party/blink/renderer/core/dom/element.h"
@@ -111,10 +112,16 @@
                                             HTMLFormElement* nullable_form);
   static void EnqueueFormResetCallback(Element& element);
   static void EnqueueFormDisabledCallback(Element& element, bool is_disabled);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static void EnqueueFormStateRestoreCallback(Element& element,
+                                              const V8ControlValue* value,
+                                              const String& mode);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static void EnqueueFormStateRestoreCallback(
       Element& element,
       const FileOrUSVStringOrFormData& value,
       const String& mode);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   static void TryToUpgrade(Element&);
 
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_definition.h b/third_party/blink/renderer/core/html/custom/custom_element_definition.h
index 26b288b5..2e2e557 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_definition.h
+++ b/third_party/blink/renderer/core/html/custom/custom_element_definition.h
@@ -7,6 +7,7 @@
 
 #include "base/macros.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/css/css_style_sheet.h"
 #include "third_party/blink/renderer/core/dom/create_element_flags.h"
@@ -93,10 +94,16 @@
                                          HTMLFormElement* nullable_form) = 0;
   virtual void RunFormResetCallback(Element& element) = 0;
   virtual void RunFormDisabledCallback(Element& element, bool is_disabled) = 0;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  virtual void RunFormStateRestoreCallback(Element& element,
+                                           const V8ControlValue* value,
+                                           const String& mode) = 0;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   virtual void RunFormStateRestoreCallback(
       Element& element,
       const FileOrUSVStringOrFormData& value,
       const String& mode) = 0;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void EnqueueUpgradeReaction(Element&);
   void EnqueueConnectedCallback(Element&);
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc b/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc
index b0a62d66..5cb60c95 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc
+++ b/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/file_or_usv_string_or_form_data.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_file_formdata_usvstring.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/html/custom/custom_element_definition.h"
 #include "third_party/blink/renderer/core/html/custom/custom_element_reaction.h"
@@ -194,6 +195,35 @@
 
 // ----------------------------------------------------------------
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+class CustomElementFormStateRestoreCallbackReaction final
+    : public CustomElementReaction {
+ public:
+  CustomElementFormStateRestoreCallbackReaction(
+      CustomElementDefinition& definition,
+      const V8ControlValue* value,
+      const String& mode)
+      : CustomElementReaction(definition), value_(value), mode_(mode) {
+    DCHECK(definition.HasFormStateRestoreCallback());
+    DCHECK(mode == "restore" || mode == "autocomplete");
+  }
+
+  void Trace(Visitor* visitor) const override {
+    visitor->Trace(value_);
+    CustomElementReaction::Trace(visitor);
+  }
+
+ private:
+  void Invoke(Element& element) override {
+    definition_->RunFormStateRestoreCallback(element, value_, mode_);
+  }
+
+  Member<const V8ControlValue> value_;
+  String mode_;
+
+  DISALLOW_COPY_AND_ASSIGN(CustomElementFormStateRestoreCallbackReaction);
+};
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 class CustomElementFormStateRestoreCallbackReaction final
     : public CustomElementReaction {
  public:
@@ -221,6 +251,7 @@
 
   DISALLOW_COPY_AND_ASSIGN(CustomElementFormStateRestoreCallbackReaction);
 };
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 // ----------------------------------------------------------------
 
@@ -278,6 +309,15 @@
       definition, is_disabled);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CustomElementReaction& CustomElementReactionFactory::CreateFormStateRestore(
+    CustomElementDefinition& definition,
+    const V8ControlValue* value,
+    const String& mode) {
+  return *MakeGarbageCollected<CustomElementFormStateRestoreCallbackReaction>(
+      definition, value, mode);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CustomElementReaction& CustomElementReactionFactory::CreateFormStateRestore(
     CustomElementDefinition& definition,
     const FileOrUSVStringOrFormData& value,
@@ -285,5 +325,6 @@
   return *MakeGarbageCollected<CustomElementFormStateRestoreCallbackReaction>(
       definition, value, mode);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.h b/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.h
index 1e74d95..479eeb0 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.h
+++ b/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_CUSTOM_ELEMENT_REACTION_FACTORY_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_CUSTOM_ELEMENT_REACTION_FACTORY_H_
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 
@@ -44,10 +45,17 @@
   static CustomElementReaction& CreateFormDisabled(
       CustomElementDefinition& definition,
       bool is_disabled);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CustomElementReaction& CreateFormStateRestore(
+      CustomElementDefinition& definition,
+      const V8ControlValue* value,
+      const String& mode);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CustomElementReaction& CreateFormStateRestore(
       CustomElementDefinition& definition,
       const FileOrUSVStringOrFormData& value,
       const String& mode);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h b/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h
index 03a18e0f..423c9fe 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h
+++ b/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h
@@ -114,11 +114,19 @@
     NOTREACHED() << "definition does not have disabledStateChangedCallback";
   }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void RunFormStateRestoreCallback(Element& element,
+                                   const V8ControlValue* value,
+                                   const String& mode) override {
+    NOTREACHED() << "definition does not have restoreValueCallback";
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void RunFormStateRestoreCallback(Element& element,
                                    const FileOrUSVStringOrFormData& value,
                                    const String& mode) override {
     NOTREACHED() << "definition does not have restoreValueCallback";
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   DISALLOW_COPY_AND_ASSIGN(TestCustomElementDefinition);
 };
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc b/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc
index 924c2b3..b3c9ba9b 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc
+++ b/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc
@@ -27,8 +27,13 @@
 
   Element* CreateElementWithId(const char* local_name, const char* id) {
     NonThrowableExceptionState no_exceptions;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    Element* element = GetDocument().CreateElementForBinding(
+        local_name, nullptr, no_exceptions);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     Element* element = GetDocument().CreateElementForBinding(
         local_name, StringOrElementCreationOptions(), no_exceptions);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     element->setAttribute(html_names::kIdAttr, id);
     return element;
   }
@@ -40,8 +45,13 @@
 
 TEST_F(CustomElementUpgradeSorterTest, inOtherDocument_notInSet) {
   NonThrowableExceptionState no_exceptions;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Element* element =
+      GetDocument().CreateElementForBinding("a-a", nullptr, no_exceptions);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Element* element = GetDocument().CreateElementForBinding(
       "a-a", StringOrElementCreationOptions(), no_exceptions);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   auto* other_document = HTMLDocument::CreateForTest();
   other_document->AppendChild(element);
@@ -59,8 +69,13 @@
 
 TEST_F(CustomElementUpgradeSorterTest, oneCandidate) {
   NonThrowableExceptionState no_exceptions;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Element* element =
+      GetDocument().CreateElementForBinding("a-a", nullptr, no_exceptions);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Element* element = GetDocument().CreateElementForBinding(
       "a-a", StringOrElementCreationOptions(), no_exceptions);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   GetDocument().documentElement()->AppendChild(element);
 
   CustomElementUpgradeSorter sorter;
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.cc b/third_party/blink/renderer/core/html/custom/element_internals.cc
index 8a1cb34..5ed4f406 100644
--- a/third_party/blink/renderer/core/html/custom/element_internals.cc
+++ b/third_party/blink/renderer/core/html/custom/element_internals.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/html/custom/element_internals.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_file_formdata_usvstring.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_validity_state_flags.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/dom/node_lists_node_data.h"
@@ -47,6 +48,43 @@
   ScriptWrappable::Trace(visitor);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+void ElementInternals::setFormValue(const V8ControlValue* value,
+                                    ExceptionState& exception_state) {
+  setFormValue(value, value, exception_state);
+}
+
+void ElementInternals::setFormValue(const V8ControlValue* value,
+                                    const V8ControlValue* state,
+                                    ExceptionState& exception_state) {
+  if (!IsTargetFormAssociated()) {
+    exception_state.ThrowDOMException(
+        DOMExceptionCode::kNotSupportedError,
+        "The target element is not a form-associated custom element.");
+    return;
+  }
+
+  if (value && value->IsFormData()) {
+    value_ = MakeGarbageCollected<V8ControlValue>(
+        MakeGarbageCollected<FormData>(*value->GetAsFormData()));
+  } else {
+    value_ = value;
+  }
+
+  if (value == state) {
+    state_ = value_;
+  } else if (state && state->IsFormData()) {
+    state_ = MakeGarbageCollected<V8ControlValue>(
+        MakeGarbageCollected<FormData>(*state->GetAsFormData()));
+  } else {
+    state_ = state;
+  }
+  NotifyFormStateChanged();
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void ElementInternals::setFormValue(const ControlValue& value,
                                     ExceptionState& exception_state) {
   setFormValue(value, value, exception_state);
@@ -80,6 +118,8 @@
   NotifyFormStateChanged();
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 HTMLFormElement* ElementInternals::form(ExceptionState& exception_state) const {
   if (!IsTargetFormAssociated()) {
     exception_state.ThrowDOMException(
@@ -373,6 +413,39 @@
   return true;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void ElementInternals::AppendToFormData(FormData& form_data) {
+  if (Target().IsDisabledFormControl())
+    return;
+
+  if (!value_)
+    return;
+
+  const AtomicString& name = Target().FastGetAttribute(html_names::kNameAttr);
+  if (!value_->IsFormData() && name.IsEmpty())
+    return;
+
+  switch (value_->GetContentType()) {
+    case V8ControlValue::ContentType::kFile: {
+      form_data.AppendFromElement(name, value_->GetAsFile());
+      break;
+    }
+    case V8ControlValue::ContentType::kUSVString: {
+      form_data.AppendFromElement(name, value_->GetAsUSVString());
+      break;
+    }
+    case V8ControlValue::ContentType::kFormData: {
+      for (const auto& entry : value_->GetAsFormData()->Entries()) {
+        if (entry->isFile())
+          form_data.append(entry->name(), entry->GetFile());
+        else
+          form_data.append(entry->name(), entry->Value());
+      }
+      break;
+    }
+  }
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void ElementInternals::AppendToFormData(FormData& form_data) {
   if (Target().IsDisabledFormControl())
     return;
@@ -394,6 +467,7 @@
       form_data.append(entry->name(), entry->Value());
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void ElementInternals::DidChangeForm() {
   ListedElement::DidChangeForm();
@@ -457,6 +531,33 @@
   return Target().isConnected() && (!Form() || Form()->ShouldAutocomplete());
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+FormControlState ElementInternals::SaveFormControlState() const {
+  FormControlState state;
+
+  if (!value_)
+    return state;
+
+  switch (value_->GetContentType()) {
+    case V8ControlValue::ContentType::kFile: {
+      state.Append("File");
+      value_->GetAsFile()->AppendToControlState(state);
+      break;
+    }
+    case V8ControlValue::ContentType::kFormData: {
+      state.Append("FormData");
+      value_->GetAsFormData()->AppendToControlState(state);
+      break;
+    }
+    case V8ControlValue::ContentType::kUSVString: {
+      state.Append("USVString");
+      state.Append(value_->GetAsUSVString());
+      break;
+    }
+  }
+  return state;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 FormControlState ElementInternals::SaveFormControlState() const {
   FormControlState state;
   if (value_.IsUSVString()) {
@@ -473,7 +574,27 @@
   // Add nothing if value_.IsNull().
   return state;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void ElementInternals::RestoreFormControlState(const FormControlState& state) {
+  if (state.ValueSize() < 2)
+    return;
+  if (state[0] == "USVString") {
+    value_ = MakeGarbageCollected<V8ControlValue>(state[1]);
+  } else if (state[0] == "File") {
+    wtf_size_t i = 1;
+    if (auto* file = File::CreateFromControlState(state, i))
+      value_ = MakeGarbageCollected<V8ControlValue>(file);
+  } else if (state[0] == "FormData") {
+    wtf_size_t i = 1;
+    if (auto* form_data = FormData::CreateFromControlState(state, i))
+      value_ = MakeGarbageCollected<V8ControlValue>(form_data);
+  }
+  if (value_)
+    CustomElement::EnqueueFormStateRestoreCallback(Target(), value_, "restore");
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void ElementInternals::RestoreFormControlState(const FormControlState& state) {
   if (state.ValueSize() < 2)
     return;
@@ -491,5 +612,6 @@
   if (!value_.IsNull())
     CustomElement::EnqueueFormStateRestoreCallback(Target(), value_, "restore");
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.h b/third_party/blink/renderer/core/html/custom/element_internals.h
index f644aaa8..c052763 100644
--- a/third_party/blink/renderer/core/html/custom/element_internals.h
+++ b/third_party/blink/renderer/core/html/custom/element_internals.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_ELEMENT_INTERNALS_H_
 
 #include "third_party/blink/renderer/bindings/core/v8/file_or_usv_string_or_form_data.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/dom/qualified_name.h"
 #include "third_party/blink/renderer/core/html/forms/labels_node_list.h"
 #include "third_party/blink/renderer/core/html/forms/listed_element.h"
@@ -30,12 +31,20 @@
   HTMLElement& Target() const { return *target_; }
   void DidUpgrade();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void setFormValue(const V8ControlValue* value,
+                    ExceptionState& exception_state);
+  void setFormValue(const V8ControlValue* value,
+                    const V8ControlValue* state,
+                    ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   using ControlValue = FileOrUSVStringOrFormData;
   // IDL attributes/operations
   void setFormValue(const ControlValue& value, ExceptionState& exception_state);
   void setFormValue(const ControlValue& value,
                     const ControlValue& state,
                     ExceptionState& exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HTMLFormElement* form(ExceptionState& exception_state) const;
   void setValidity(ValidityStateFlags* flags, ExceptionState& exception_state);
   void setValidity(ValidityStateFlags* flags,
@@ -102,8 +111,13 @@
 
   Member<HTMLElement> target_;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Member<const V8ControlValue> value_;
+  Member<const V8ControlValue> state_;
+#else
   ControlValue value_;
   ControlValue state_;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool is_disabled_ = false;
   Member<ValidityStateFlags> validity_flags_;
   Member<Element> validation_anchor_;
diff --git a/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc b/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
index 0dc41d8..a44a6df 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
+++ b/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc
@@ -571,11 +571,12 @@
     field->blur();
 }
 
-ComputedStyle* DateTimeEditElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> DateTimeEditElement::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
   // TODO(crbug.com/1181868): This is a kind of layout. We might want to
   // introduce new LayoutObject.
-  ComputedStyle* style = OriginalStyleForLayoutObject(style_recalc_context);
+  scoped_refptr<ComputedStyle> style =
+      OriginalStyleForLayoutObject(style_recalc_context);
   float width = 0;
   for (Node* child = FieldsWrapperElement()->firstChild(); child;
        child = child->nextSibling()) {
diff --git a/third_party/blink/renderer/core/html/forms/date_time_edit_element.h b/third_party/blink/renderer/core/html/forms/date_time_edit_element.h
index 9365ffe..5acb2aaf 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_edit_element.h
+++ b/third_party/blink/renderer/core/html/forms/date_time_edit_element.h
@@ -139,7 +139,8 @@
   void UpdateUIState();
 
   // Element function.
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) override;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) override;
   bool IsDateTimeEditElement() const override;
 
   // DateTimeFieldElement::FieldOwner functions.
diff --git a/third_party/blink/renderer/core/html/forms/form_data.cc b/third_party/blink/renderer/core/html/forms/form_data.cc
index 1eb941af..b7f8ab79 100644
--- a/third_party/blink/renderer/core/html/forms/form_data.cc
+++ b/third_party/blink/renderer/core/html/forms/form_data.cc
@@ -30,6 +30,7 @@
 
 #include "third_party/blink/renderer/core/html/forms/form_data.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_file_usvstring.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/fileapi/blob.h"
 #include "third_party/blink/renderer/core/fileapi/file.h"
@@ -142,6 +143,21 @@
   }
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8FormDataEntryValue* FormData::get(const String& name) {
+  for (const auto& entry : Entries()) {
+    if (entry->name() == name) {
+      if (entry->IsString()) {
+        return MakeGarbageCollected<V8FormDataEntryValue>(entry->Value());
+      } else {
+        DCHECK(entry->isFile());
+        return MakeGarbageCollected<V8FormDataEntryValue>(entry->GetFile());
+      }
+    }
+  }
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void FormData::get(const String& name, FormDataEntryValue& result) {
   for (const auto& entry : Entries()) {
     if (entry->name() == name) {
@@ -155,7 +171,27 @@
     }
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+HeapVector<Member<V8FormDataEntryValue>> FormData::getAll(const String& name) {
+  HeapVector<Member<V8FormDataEntryValue>> results;
+
+  for (const auto& entry : Entries()) {
+    if (entry->name() != name)
+      continue;
+    V8FormDataEntryValue* value;
+    if (entry->IsString()) {
+      value = MakeGarbageCollected<V8FormDataEntryValue>(entry->Value());
+    } else {
+      DCHECK(entry->isFile());
+      value = MakeGarbageCollected<V8FormDataEntryValue>(entry->GetFile());
+    }
+    results.push_back(value);
+  }
+  return results;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 HeapVector<FormDataEntryValue> FormData::getAll(const String& name) {
   HeapVector<FormDataEntryValue> results;
 
@@ -173,6 +209,7 @@
   }
   return results;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 bool FormData::has(const String& name) {
   for (const auto& entry : Entries()) {
diff --git a/third_party/blink/renderer/core/html/forms/form_data.h b/third_party/blink/renderer/core/html/forms/form_data.h
index 4325925..b5c6642 100644
--- a/third_party/blink/renderer/core/html/forms/form_data.h
+++ b/third_party/blink/renderer/core/html/forms/form_data.h
@@ -33,6 +33,7 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/file_or_usv_string.h"
 #include "third_party/blink/renderer/bindings/core/v8/iterable.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/network/encoded_form_data.h"
@@ -75,8 +76,13 @@
               Blob*,
               const String& filename = String());
   void deleteEntry(const String& name);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8FormDataEntryValue* get(const String& name);
+  HeapVector<Member<V8FormDataEntryValue>> getAll(const String& name);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void get(const String& name, FormDataEntryValue& result);
   HeapVector<FormDataEntryValue> getAll(const String& name);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool has(const String& name);
   void set(const String& name, const String& value);
   void set(const String& name, Blob*, const String& filename = String());
diff --git a/third_party/blink/renderer/core/html/forms/form_data_test.cc b/third_party/blink/renderer/core/html/forms/form_data_test.cc
index 3a6da9e..09df547b 100644
--- a/third_party/blink/renderer/core/html/forms/form_data_test.cc
+++ b/third_party/blink/renderer/core/html/forms/form_data_test.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/html/forms/form_data.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_file_usvstring.h"
 #include "third_party/blink/renderer/core/fileapi/file.h"
 #include "third_party/blink/renderer/core/html/forms/form_controller.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
@@ -57,10 +58,16 @@
   auto* fd = MakeGarbageCollected<FormData>(UTF8Encoding());
   fd->append("name1", "value1");
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionFileOrUSVString* result = fd->get("name1");
+  EXPECT_TRUE(result->IsUSVString());
+  EXPECT_EQ("value1", result->GetAsUSVString());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   FileOrUSVString result;
   fd->get("name1", result);
   EXPECT_TRUE(result.IsUSVString());
   EXPECT_EQ("value1", result.GetAsUSVString());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   const FormData::Entry& entry = *fd->Entries()[0];
   EXPECT_EQ("name1", entry.name());
@@ -71,10 +78,17 @@
   auto* fd = MakeGarbageCollected<FormData>(UTF8Encoding());
   fd->append("name1", "value1");
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const HeapVector<Member<V8FormDataEntryValue>>& results = fd->getAll("name1");
+  EXPECT_EQ(1u, results.size());
+  EXPECT_TRUE(results[0]->IsUSVString());
+  EXPECT_EQ("value1", results[0]->GetAsUSVString());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<FormDataEntryValue> results = fd->getAll("name1");
   EXPECT_EQ(1u, results.size());
   EXPECT_TRUE(results[0].IsUSVString());
   EXPECT_EQ("value1", results[0].GetAsUSVString());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   EXPECT_EQ(1u, fd->size());
 }
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc b/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc
index dda45d4..fbea38a 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc
+++ b/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc
@@ -87,7 +87,7 @@
   EXPECT_EQ(TextDirection::kRtl, message_dir);
   EXPECT_EQ(TextDirection::kLtr, sub_message_dir);
 
-  ComputedStyle* rtl_style =
+  scoped_refptr<ComputedStyle> rtl_style =
       ComputedStyle::Clone(input->GetLayoutObject()->StyleRef());
   rtl_style->SetDirection(TextDirection::kRtl);
   input->GetLayoutObject()->SetStyle(std::move(rtl_style));
diff --git a/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc b/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc
index 86e78a22..04973ff 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc
+++ b/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc
@@ -25,6 +25,7 @@
 #include "third_party/blink/renderer/core/html/forms/html_form_controls_collection.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/radio_node_list_or_element.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_element_radionodelist.h"
 #include "third_party/blink/renderer/core/html/forms/html_form_element.h"
 #include "third_party/blink/renderer/core/html/html_image_element.h"
 #include "third_party/blink/renderer/core/html_names.h"
@@ -172,6 +173,29 @@
   SetNamedItemCache(cache);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionElementOrRadioNodeList* HTMLFormControlsCollection::namedGetter(
+    const AtomicString& name) {
+  HeapVector<Member<Element>> named_items;
+  NamedItems(name, named_items);
+
+  if (named_items.IsEmpty())
+    return nullptr;
+
+  if (named_items.size() == 1) {
+    if (!IsA<HTMLImageElement>(*named_items[0])) {
+      return MakeGarbageCollected<V8UnionElementOrRadioNodeList>(
+          named_items[0]);
+    }
+    return nullptr;
+  }
+
+  // This path never returns a RadioNodeList for <img> because
+  // onlyMatchingImgElements flag is false by default.
+  return MakeGarbageCollected<V8UnionElementOrRadioNodeList>(
+      ownerNode().GetRadioNodeList(name));
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void HTMLFormControlsCollection::namedGetter(
     const AtomicString& name,
     RadioNodeListOrElement& return_value) {
@@ -191,6 +215,7 @@
   // onlyMatchingImgElements flag is false by default.
   return_value.SetRadioNodeList(ownerNode().GetRadioNodeList(name));
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void HTMLFormControlsCollection::SupportedPropertyNames(Vector<String>& names) {
   // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#htmlformcontrolscollection-0:
diff --git a/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h b/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h
index b85bc92..2306b4d 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h
+++ b/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h
@@ -34,6 +34,7 @@
 
 class HTMLImageElement;
 class RadioNodeListOrElement;
+class V8UnionElementOrRadioNodeList;
 
 // This class is just a big hack to find form elements even in malformed HTML
 // elements.  The famous <table><tr><form><td> problem.
@@ -52,7 +53,11 @@
   }
 
   HTMLElement* namedItem(const AtomicString& name) const override;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionElementOrRadioNodeList* namedGetter(const AtomicString& name);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void namedGetter(const AtomicString& name, RadioNodeListOrElement&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.cc b/third_party/blink/renderer/core/html/forms/html_form_element.cc
index 3978b4d..5a4f06cc 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_form_element.cc
@@ -33,6 +33,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/radio_node_list_or_element.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_submit_event_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_element_radionodelist.h"
 #include "third_party/blink/renderer/core/dom/attribute.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
@@ -875,6 +876,24 @@
   did_finish_parsing_children_ = true;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionElementOrRadioNodeList* HTMLFormElement::AnonymousNamedGetter(
+    const AtomicString& name) {
+  RadioNodeListOrElement return_value;
+  // Delegate to the old IDL union implementation for the time being.
+  AnonymousNamedGetter(name, return_value);
+  if (return_value.IsElement()) {
+    return MakeGarbageCollected<V8UnionElementOrRadioNodeList>(
+        return_value.GetAsElement());
+  }
+  if (return_value.IsRadioNodeList()) {
+    return MakeGarbageCollected<V8UnionElementOrRadioNodeList>(
+        return_value.GetAsRadioNodeList());
+  }
+  return nullptr;
+}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void HTMLFormElement::AnonymousNamedGetter(
     const AtomicString& name,
     RadioNodeListOrElement& return_value) {
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.h b/third_party/blink/renderer/core/html/forms/html_form_element.h
index 44e0c202..7c89b71c 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_form_element.h
@@ -34,11 +34,12 @@
 namespace blink {
 
 class Event;
-class ListedElement;
 class HTMLFormControlElement;
 class HTMLFormControlsCollection;
 class HTMLImageElement;
+class ListedElement;
 class RadioNodeListOrElement;
+class V8UnionElementOrRadioNodeList;
 
 class CORE_EXPORT HTMLFormElement final : public HTMLElement {
   DEFINE_WRAPPERTYPEINFO();
@@ -105,6 +106,9 @@
   const ListedElement::List& ListedElements() const;
   const HeapVector<Member<HTMLImageElement>>& ImageElements();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionElementOrRadioNodeList* AnonymousNamedGetter(const AtomicString& name);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void AnonymousNamedGetter(const AtomicString& name, RadioNodeListOrElement&);
   void InvalidateDefaultButtonStyle() const;
 
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc
index 71188a8..4b01f2c0 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -2060,9 +2060,10 @@
   return input_type_->IsInteractiveContent();
 }
 
-ComputedStyle* HTMLInputElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> HTMLInputElement::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
-  ComputedStyle* style = OriginalStyleForLayoutObject(style_recalc_context);
+  scoped_refptr<ComputedStyle> style =
+      OriginalStyleForLayoutObject(style_recalc_context);
   input_type_view_->CustomStyleForLayoutObject(*style);
   return style;
 }
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.h b/third_party/blink/renderer/core/html/forms/html_input_element.h
index c7781a1..5925fa3 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.h
@@ -448,7 +448,8 @@
 
   void AddToRadioButtonGroup();
   void RemoveFromRadioButtonGroup();
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) override;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) override;
 
   void MaybeReportPiiMetrics();
 
diff --git a/third_party/blink/renderer/core/html/forms/html_options_collection.cc b/third_party/blink/renderer/core/html/forms/html_options_collection.cc
index 569dfb3..09915da 100644
--- a/third_party/blink/renderer/core/html/forms/html_options_collection.cc
+++ b/third_party/blink/renderer/core/html/forms/html_options_collection.cc
@@ -70,12 +70,21 @@
   }
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void HTMLOptionsCollection::add(
+    const V8UnionHTMLOptGroupElementOrHTMLOptionElement* element,
+    const V8UnionHTMLElementOrLong* before,
+    ExceptionState& exception_state) {
+  To<HTMLSelectElement>(ownerNode()).add(element, before, exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void HTMLOptionsCollection::add(
     const HTMLOptionElementOrHTMLOptGroupElement& element,
     const HTMLElementOrLong& before,
     ExceptionState& exception_state) {
   To<HTMLSelectElement>(ownerNode()).add(element, before, exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void HTMLOptionsCollection::remove(int index) {
   To<HTMLSelectElement>(ownerNode()).remove(index);
diff --git a/third_party/blink/renderer/core/html/forms/html_options_collection.h b/third_party/blink/renderer/core/html/forms/html_options_collection.h
index d9e50d9..4c41e48 100644
--- a/third_party/blink/renderer/core/html/forms/html_options_collection.h
+++ b/third_party/blink/renderer/core/html/forms/html_options_collection.h
@@ -32,8 +32,10 @@
 namespace blink {
 
 class ExceptionState;
-class HTMLOptionElementOrHTMLOptGroupElement;
 class HTMLElementOrLong;
+class HTMLOptionElementOrHTMLOptGroupElement;
+class V8UnionHTMLElementOrLong;
+class V8UnionHTMLOptGroupElementOrHTMLOptionElement;
 
 class HTMLOptionsCollection final : public HTMLCollection {
   DEFINE_WRAPPERTYPEINFO();
@@ -46,9 +48,15 @@
     return To<HTMLOptionElement>(HTMLCollection::item(offset));
   }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void add(const V8UnionHTMLOptGroupElementOrHTMLOptionElement* element,
+           const V8UnionHTMLElementOrLong* before,
+           ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void add(const HTMLOptionElementOrHTMLOptGroupElement&,
            const HTMLElementOrLong&,
            ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void remove(int index);
 
   int selectedIndex() const;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc
index 6fed598..88e95ee 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -35,6 +35,8 @@
 #include "third_party/blink/public/strings/grit/blink_strings.h"
 #include "third_party/blink/renderer/bindings/core/v8/html_element_or_long.h"
 #include "third_party/blink/renderer/bindings/core/v8/html_option_element_or_html_opt_group_element.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_htmlelement_long.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_htmloptgroupelement_htmloptionelement.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/css/style_change_reason.h"
 #include "third_party/blink/renderer/core/dom/attribute.h"
@@ -233,6 +235,41 @@
   return select_type_->ActiveSelectionEnd();
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void HTMLSelectElement::add(
+    const V8UnionHTMLOptGroupElementOrHTMLOptionElement* element,
+    const V8UnionHTMLElementOrLong* before,
+    ExceptionState& exception_state) {
+  DCHECK(element);
+
+  HTMLElement* element_to_insert = nullptr;
+  switch (element->GetContentType()) {
+    case V8UnionHTMLOptGroupElementOrHTMLOptionElement::ContentType::
+        kHTMLOptGroupElement:
+      element_to_insert = element->GetAsHTMLOptGroupElement();
+      break;
+    case V8UnionHTMLOptGroupElementOrHTMLOptionElement::ContentType::
+        kHTMLOptionElement:
+      element_to_insert = element->GetAsHTMLOptionElement();
+      break;
+  }
+
+  HTMLElement* before_element = nullptr;
+  if (before) {
+    switch (before->GetContentType()) {
+      case V8UnionHTMLElementOrLong::ContentType::kHTMLElement:
+        before_element = before->GetAsHTMLElement();
+        break;
+      case V8UnionHTMLElementOrLong::ContentType::kLong:
+        before_element = options()->item(before->GetAsLong());
+        break;
+    }
+  }
+
+  InsertBefore(element_to_insert, before_element, exception_state);
+  SetNeedsValidityCheck();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void HTMLSelectElement::add(
     const HTMLOptionElementOrHTMLOptGroupElement& element,
     const HTMLElementOrLong& before,
@@ -255,6 +292,7 @@
   InsertBefore(element_to_insert, before_element, exception_state);
   SetNeedsValidityCheck();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void HTMLSelectElement::remove(int option_index) {
   if (HTMLOptionElement* option = item(option_index))
@@ -422,6 +460,26 @@
                        index, kMaxListItems)));
     return;
   }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* element =
+      MakeGarbageCollected<V8UnionHTMLOptGroupElementOrHTMLOptionElement>(
+          option);
+  V8UnionHTMLElementOrLong* before = nullptr;
+  // Out of array bounds? First insert empty dummies.
+  if (diff > 0) {
+    setLength(index, exception_state);
+    if (exception_state.HadException())
+      return;
+    // Replace an existing entry?
+  } else if (diff < 0) {
+    if (auto* before_element = options()->item(index + 1))
+      before = MakeGarbageCollected<V8UnionHTMLElementOrLong>(before_element);
+    remove(index);
+  }
+  // Finally add the new element.
+  EventQueueScope scope;
+  add(element, before, exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HTMLOptionElementOrHTMLOptGroupElement element;
   element.SetHTMLOptionElement(option);
   HTMLElementOrLong before;
@@ -438,6 +496,7 @@
   // Finally add the new element.
   EventQueueScope scope;
   add(element, before, exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (exception_state.HadException())
     return;
   if (diff >= 0 && option->Selected())
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.h b/third_party/blink/renderer/core/html/forms/html_select_element.h
index 050df67..801db45 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -42,14 +42,16 @@
 class AXObject;
 class AutoscrollController;
 class ExceptionState;
+class HTMLElementOrLong;
 class HTMLHRElement;
 class HTMLOptGroupElement;
 class HTMLOptionElement;
 class HTMLOptionElementOrHTMLOptGroupElement;
-class HTMLElementOrLong;
 class LayoutUnit;
 class PopupMenu;
 class SelectType;
+class V8UnionHTMLElementOrLong;
+class V8UnionHTMLOptGroupElementOrHTMLOptionElement;
 
 class CORE_EXPORT HTMLSelectElement final
     : public HTMLFormControlElementWithState,
@@ -85,9 +87,15 @@
 
   bool UsesMenuList() const { return uses_menu_list_; }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void add(const V8UnionHTMLOptGroupElementOrHTMLOptionElement* element,
+           const V8UnionHTMLElementOrLong* before,
+           ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void add(const HTMLOptionElementOrHTMLOptGroupElement&,
            const HTMLElementOrLong&,
            ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   using Node::remove;
   void remove(int index);
diff --git a/third_party/blink/renderer/core/html/forms/image_input_type.cc b/third_party/blink/renderer/core/html/forms/image_input_type.cc
index 5592beca..f70a84f 100644
--- a/third_party/blink/renderer/core/html/forms/image_input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/image_input_type.cc
@@ -109,11 +109,11 @@
                                                  LegacyLayout legacy) const {
   if (use_fallback_content_) {
     if (style.Display() == EDisplay::kInline)
-      return MakeGarbageCollected<LayoutInline>(&GetElement());
+      return new LayoutInline(&GetElement());
 
     return LayoutObjectFactory::CreateBlockFlow(GetElement(), style, legacy);
   }
-  LayoutImage* image = MakeGarbageCollected<LayoutImage>(&GetElement());
+  LayoutImage* image = new LayoutImage(&GetElement());
   image->SetImageResource(MakeGarbageCollected<LayoutImageResource>());
   return image;
 }
diff --git a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
index 31648ef9..118400626 100644
--- a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
+++ b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
@@ -78,16 +78,18 @@
   return kNoPart;
 }
 
-const ComputedStyle* StyleForHoveredScrollbarPart(HTMLSelectElement& element,
-                                                  const ComputedStyle* style,
-                                                  Scrollbar* scrollbar,
-                                                  PseudoId target_id) {
+scoped_refptr<const ComputedStyle> StyleForHoveredScrollbarPart(
+    HTMLSelectElement& element,
+    const ComputedStyle* style,
+    Scrollbar* scrollbar,
+    PseudoId target_id) {
   ScrollbarPart part = ScrollbarPartFromPseudoId(target_id);
   if (part == kNoPart)
     return nullptr;
   scrollbar->SetHoveredPart(part);
-  const ComputedStyle* part_style = element.UncachedStyleForPseudoElement(
-      StyleRequest(target_id, To<CustomScrollbar>(scrollbar), part, style));
+  scoped_refptr<const ComputedStyle> part_style =
+      element.UncachedStyleForPseudoElement(
+          StyleRequest(target_id, To<CustomScrollbar>(scrollbar), part, style));
   return part_style;
 }
 
@@ -291,9 +293,10 @@
     }
     // For Pseudo-class styles, Style should be calculated via that status.
     if (temp_scrollbar) {
-      const ComputedStyle* part_style = StyleForHoveredScrollbarPart(
-          owner_element, owner_element.GetComputedStyle(), temp_scrollbar,
-          target.first);
+      scoped_refptr<const ComputedStyle> part_style =
+          StyleForHoveredScrollbarPart(owner_element,
+                                       owner_element.GetComputedStyle(),
+                                       temp_scrollbar, target.first);
       if (part_style) {
         AppendOwnerElementPseudoStyles(target.second + ":hover", data,
                                        *part_style);
diff --git a/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc b/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc
index 67978c3..66f27a6e 100644
--- a/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc
+++ b/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc
@@ -17,10 +17,10 @@
   SetHasCustomStyleCallbacks();
 }
 
-ComputedStyle* MenuListInnerElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> MenuListInnerElement::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
   const ComputedStyle& parent_style = OwnerShadowHost()->ComputedStyleRef();
-  ComputedStyle* style =
+  scoped_refptr<ComputedStyle> style =
       GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
           parent_style, EDisplay::kBlock);
   style->SetFlexGrow(1);
diff --git a/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h b/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h
index d05a8ea5..0d8317a 100644
--- a/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h
+++ b/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h
@@ -14,7 +14,8 @@
   explicit MenuListInnerElement(Document& document);
 
  private:
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) override;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) override;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/forms/select_type.cc b/third_party/blink/renderer/core/html/forms/select_type.cc
index d27ca66..53830fb 100644
--- a/third_party/blink/renderer/core/html/forms/select_type.cc
+++ b/third_party/blink/renderer/core/html/forms/select_type.cc
@@ -90,7 +90,9 @@
   void UpdateTextStyle() override { UpdateTextStyleInternal(); }
   void UpdateTextStyleAndContent() override;
   HTMLOptionElement* OptionToBeShown() const override;
-  const ComputedStyle* OptionStyle() const override { return option_style_; }
+  const ComputedStyle* OptionStyle() const override {
+    return option_style_.get();
+  }
   void MaximumOptionWidthMightBeChanged() const override;
 
   void CreateShadowSubtree(ShadowRoot& root) override;
@@ -118,7 +120,7 @@
 
   Member<PopupMenu> popup_;
   Member<PopupUpdater> popup_updater_;
-  Member<const ComputedStyle> option_style_;
+  scoped_refptr<const ComputedStyle> option_style_;
   int ax_menulist_last_active_index_ = -1;
   bool has_updated_menulist_active_option_ = false;
   bool popup_is_visible_ = false;
@@ -128,7 +130,6 @@
 void MenuListSelectType::Trace(Visitor* visitor) const {
   visitor->Trace(popup_);
   visitor->Trace(popup_updater_);
-  visitor->Trace(option_style_);
   SelectType::Trace(visitor);
 }
 
@@ -486,7 +487,8 @@
   if (inner_style && option_style &&
       ((option_style->Direction() != inner_style->Direction() ||
         option_style->GetUnicodeBidi() != inner_style->GetUnicodeBidi()))) {
-    ComputedStyle* cloned_style = ComputedStyle::Clone(*inner_style);
+    scoped_refptr<ComputedStyle> cloned_style =
+        ComputedStyle::Clone(*inner_style);
     cloned_style->SetDirection(option_style->Direction());
     cloned_style->SetUnicodeBidi(option_style->GetUnicodeBidi());
     if (auto* inner_layout = inner_element.GetLayoutObject()) {
diff --git a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
index b8911c85..21676c6 100644
--- a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
+++ b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
@@ -287,12 +287,13 @@
   }
 }
 
-ComputedStyle* SliderThumbElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> SliderThumbElement::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
   Element* host = OwnerShadowHost();
   DCHECK(host);
   const ComputedStyle& host_style = host->ComputedStyleRef();
-  ComputedStyle* style = OriginalStyleForLayoutObject(style_recalc_context);
+  scoped_refptr<ComputedStyle> style =
+      OriginalStyleForLayoutObject(style_recalc_context);
 
   if (host_style.EffectiveAppearance() == kSliderVerticalPart)
     style->SetEffectiveAppearance(kSliderThumbVerticalPart);
diff --git a/third_party/blink/renderer/core/html/forms/slider_thumb_element.h b/third_party/blink/renderer/core/html/forms/slider_thumb_element.h
index 7b0e6e6..a554003a 100644
--- a/third_party/blink/renderer/core/html/forms/slider_thumb_element.h
+++ b/third_party/blink/renderer/core/html/forms/slider_thumb_element.h
@@ -63,7 +63,8 @@
 
  private:
   LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) final;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) final;
   Element& CloneWithoutAttributesAndChildren(Document&) const override;
   bool IsDisabledFormControl() const override;
   bool MatchesReadOnlyPseudoClass() const override;
diff --git a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc
index c3e0166..17ead81c 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc
+++ b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc
@@ -46,11 +46,12 @@
   setAttribute(html_names::kIdAttr, shadow_element_names::kIdEditingViewPort);
 }
 
-ComputedStyle* EditingViewPortElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> EditingViewPortElement::CustomStyleForLayoutObject(
     const StyleRecalcContext&) {
   // FXIME: Move these styles to html.css.
 
-  ComputedStyle* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style =
+      GetDocument().GetStyleResolver().CreateComputedStyle();
   style->InheritFrom(OwnerShadowHost()->ComputedStyleRef());
 
   style->SetFlexGrow(1);
@@ -134,9 +135,10 @@
                                                            legacy);
 }
 
-ComputedStyle* TextControlInnerEditorElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle>
+TextControlInnerEditorElement::CustomStyleForLayoutObject(
     const StyleRecalcContext&) {
-  ComputedStyle* inner_editor_style = CreateInnerEditorStyle();
+  scoped_refptr<ComputedStyle> inner_editor_style = CreateInnerEditorStyle();
   // Using StyleAdjuster::adjustComputedStyle updates unwanted style. We'd like
   // to apply only editing-related and alignment-related.
   StyleAdjuster::AdjustStyleForEditing(*inner_editor_style);
@@ -145,11 +147,12 @@
   return inner_editor_style;
 }
 
-ComputedStyle* TextControlInnerEditorElement::CreateInnerEditorStyle() const {
+scoped_refptr<ComputedStyle>
+TextControlInnerEditorElement::CreateInnerEditorStyle() const {
   Element* host = OwnerShadowHost();
   DCHECK(host);
   const ComputedStyle& start_style = host->ComputedStyleRef();
-  ComputedStyle* text_block_style =
+  scoped_refptr<ComputedStyle> text_block_style =
       GetDocument().GetStyleResolver().CreateComputedStyle();
   text_block_style->InheritFrom(start_style);
   // The inner block, if present, always has its direction set to LTR,
@@ -200,7 +203,7 @@
     text_block_style->SetOverflowX(EOverflow::kScroll);
     // overflow-y:visible doesn't work because overflow-x:scroll makes a layer.
     text_block_style->SetOverflowY(EOverflow::kScroll);
-    ComputedStyle* no_scrollbar_style =
+    scoped_refptr<ComputedStyle> no_scrollbar_style =
         GetDocument().GetStyleResolver().CreateComputedStyle();
     no_scrollbar_style->SetStyleType(kPseudoIdScrollbar);
     no_scrollbar_style->SetDisplay(EDisplay::kNone);
diff --git a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h
index b86546f4..b163e73 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h
+++ b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h
@@ -37,7 +37,8 @@
   explicit EditingViewPortElement(Document&);
 
  protected:
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) override;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) override;
 
  private:
   bool TypeShouldForceLegacyLayout() const final;
@@ -52,12 +53,13 @@
 
   void SetVisibility(bool is_visible);
   void FocusChanged();
-  ComputedStyle* CreateInnerEditorStyle() const;
+  scoped_refptr<ComputedStyle> CreateInnerEditorStyle() const;
 
  private:
   LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
   bool TypeShouldForceLegacyLayout() const final;
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) override;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) override;
   bool SupportsFocus() const override { return false; }
   bool is_visible_ = true;
 };
diff --git a/third_party/blink/renderer/core/html/html_all_collection.cc b/third_party/blink/renderer/core/html/html_all_collection.cc
index bf74ee9..8d105e1 100644
--- a/third_party/blink/renderer/core/html/html_all_collection.cc
+++ b/third_party/blink/renderer/core/html/html_all_collection.cc
@@ -23,10 +23,12 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "third_party/blink/renderer/bindings/core/v8/html_collection_or_element.h"
-#include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/html/html_all_collection.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/html_collection_or_element.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_element_htmlcollection.h"
+#include "third_party/blink/renderer/core/dom/element.h"
+
 namespace blink {
 
 HTMLAllCollection::HTMLAllCollection(ContainerNode& node)
@@ -43,6 +45,21 @@
   return HTMLCollection::item(index);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionElementOrHTMLCollection* HTMLAllCollection::NamedGetter(
+    const AtomicString& name) {
+  HTMLCollection* items = GetDocument().DocumentAllNamedItems(name);
+
+  if (!items->length())
+    return nullptr;
+
+  if (items->length() == 1) {
+    return MakeGarbageCollected<V8UnionElementOrHTMLCollection>(items->item(0));
+  }
+
+  return MakeGarbageCollected<V8UnionElementOrHTMLCollection>(items);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void HTMLAllCollection::NamedGetter(const AtomicString& name,
                                     HTMLCollectionOrElement& return_value) {
   HTMLCollection* items = GetDocument().DocumentAllNamedItems(name);
@@ -57,5 +74,6 @@
 
   return_value.SetHTMLCollection(items);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_all_collection.h b/third_party/blink/renderer/core/html/html_all_collection.h
index f373796..15783e5 100644
--- a/third_party/blink/renderer/core/html/html_all_collection.h
+++ b/third_party/blink/renderer/core/html/html_all_collection.h
@@ -32,6 +32,7 @@
 
 class Element;
 class HTMLCollectionOrElement;
+class V8UnionElementOrHTMLCollection;
 
 class HTMLAllCollection final : public HTMLCollection {
   DEFINE_WRAPPERTYPEINFO();
@@ -42,7 +43,11 @@
   ~HTMLAllCollection() override;
 
   Element* AnonymousIndexedGetter(unsigned index);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionElementOrHTMLCollection* NamedGetter(const AtomicString& name);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void NamedGetter(const AtomicString& name, HTMLCollectionOrElement&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_br_element.cc b/third_party/blink/renderer/core/html/html_br_element.cc
index ea2a2d0a..8320f200 100644
--- a/third_party/blink/renderer/core/html/html_br_element.cc
+++ b/third_party/blink/renderer/core/html/html_br_element.cc
@@ -63,7 +63,7 @@
 LayoutObject* HTMLBRElement::CreateLayoutObject(const ComputedStyle& style,
                                                 LegacyLayout legacy) {
   if (style.ContentBehavesAsNormal())
-    return MakeGarbageCollected<LayoutBR>(this);
+    return new LayoutBR(this);
   return LayoutObject::CreateObject(this, style, legacy);
 }
 
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc
index 9443af5..74a41134 100644
--- a/third_party/blink/renderer/core/html/html_element.cc
+++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -29,6 +29,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_treat_null_as_empty_string_or_trusted_script.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_stringtreatnullasemptystring_trustedscript.h"
 #include "third_party/blink/renderer/core/css/css_color.h"
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_markup.h"
@@ -831,8 +832,38 @@
   return fragment;
 }
 
-void HTMLElement::setInnerText(
-    const StringOrTrustedScript& string_or_trusted_script,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionStringTreatNullAsEmptyStringOrTrustedScript*
+HTMLElement::innerTextForBinding() {
+  return MakeGarbageCollected<
+      V8UnionStringTreatNullAsEmptyStringOrTrustedScript>(innerText());
+}
+
+void HTMLElement::setInnerTextForBinding(
+    const V8UnionStringTreatNullAsEmptyStringOrTrustedScript*
+        string_or_trusted_script,
+    ExceptionState& exception_state) {
+  String value;
+  switch (string_or_trusted_script->GetContentType()) {
+    case V8UnionStringTreatNullAsEmptyStringOrTrustedScript::ContentType::
+        kStringTreatNullAsEmptyString:
+      value = string_or_trusted_script->GetAsStringTreatNullAsEmptyString();
+      break;
+    case V8UnionStringTreatNullAsEmptyStringOrTrustedScript::ContentType::
+        kTrustedScript:
+      value = string_or_trusted_script->GetAsTrustedScript()->toString();
+      break;
+  }
+  setInnerText(value, exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void HTMLElement::innerTextForBinding(
+    StringTreatNullAsEmptyStringOrTrustedScript& result) {
+  result.SetString(innerText());
+}
+
+void HTMLElement::setInnerTextForBinding(
+    const StringTreatNullAsEmptyStringOrTrustedScript& string_or_trusted_script,
     ExceptionState& exception_state) {
   String value;
   if (string_or_trusted_script.IsString())
@@ -841,26 +872,7 @@
     value = string_or_trusted_script.GetAsTrustedScript()->toString();
   setInnerText(value, exception_state);
 }
-
-void HTMLElement::setInnerText(
-    const StringTreatNullAsEmptyStringOrTrustedScript& string_or_trusted_script,
-    ExceptionState& exception_state) {
-  StringOrTrustedScript tmp;
-  if (string_or_trusted_script.IsString())
-    tmp.SetString(string_or_trusted_script.GetAsString());
-  else if (string_or_trusted_script.IsTrustedScript())
-    tmp.SetTrustedScript(string_or_trusted_script.GetAsTrustedScript());
-  setInnerText(tmp, exception_state);
-}
-
-void HTMLElement::innerText(
-    StringTreatNullAsEmptyStringOrTrustedScript& result) {
-  result.SetString(innerText());
-}
-
-void HTMLElement::innerText(StringOrTrustedScript& result) {
-  result.SetString(innerText());
-}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 String HTMLElement::innerText() {
   return Element::innerText();
diff --git a/third_party/blink/renderer/core/html/html_element.h b/third_party/blink/renderer/core/html/html_element.h
index e89fe4e..b3fce1a 100644
--- a/third_party/blink/renderer/core/html/html_element.h
+++ b/third_party/blink/renderer/core/html/html_element.h
@@ -42,6 +42,7 @@
 class KeyboardEvent;
 class StringOrTrustedScript;
 class StringTreatNullAsEmptyStringOrTrustedScript;
+class V8UnionStringTreatNullAsEmptyStringOrTrustedScript;
 
 enum TranslateAttributeMode {
   kTranslateAttributeYes,
@@ -62,13 +63,20 @@
 
   String title() const final;
 
-  void setInnerText(const String&, ExceptionState&);
-  virtual void setInnerText(const StringOrTrustedScript&, ExceptionState&);
-  virtual void setInnerText(const StringTreatNullAsEmptyStringOrTrustedScript&,
-                            ExceptionState&);
   String innerText();
-  void innerText(StringOrTrustedScript& result);
-  void innerText(StringTreatNullAsEmptyStringOrTrustedScript& result);
+  void setInnerText(const String&, ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionStringTreatNullAsEmptyStringOrTrustedScript* innerTextForBinding();
+  virtual void setInnerTextForBinding(
+      const V8UnionStringTreatNullAsEmptyStringOrTrustedScript*
+          string_or_trusted_script,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void innerTextForBinding(StringTreatNullAsEmptyStringOrTrustedScript& result);
+  virtual void setInnerTextForBinding(
+      const StringTreatNullAsEmptyStringOrTrustedScript&,
+      ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void setOuterText(const String&, ExceptionState&);
 
   virtual bool HasCustomFocusLogic() const;
diff --git a/third_party/blink/renderer/core/html/html_element.idl b/third_party/blink/renderer/core/html/html_element.idl
index d231c47..3b14942 100644
--- a/third_party/blink/renderer/core/html/html_element.idl
+++ b/third_party/blink/renderer/core/html/html_element.idl
@@ -65,7 +65,7 @@
     [Affects=Nothing, SameObject, PerWorldBindings, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
 
     // Non-standard APIs
-    [Affects=Nothing, CEReactions, RaisesException=Setter, MeasureAs=HTMLElementInnerText] attribute ([TreatNullAs=EmptyString] DOMString or TrustedScript) innerText;
+    [Affects=Nothing, CEReactions, RaisesException=Setter, MeasureAs=HTMLElementInnerText, ImplementedAs=innerTextForBinding] attribute ([TreatNullAs=EmptyString] DOMString or TrustedScript) innerText;
     [Affects=Nothing, CEReactions, RaisesException=Setter, MeasureAs=HTMLElementOuterText] attribute [TreatNullAs=EmptyString] DOMString outerText;
 };
 
diff --git a/third_party/blink/renderer/core/html/html_embed_element_test.cc b/third_party/blink/renderer/core/html/html_embed_element_test.cc
index 3504900..aac2e17 100644
--- a/third_party/blink/renderer/core/html/html_embed_element_test.cc
+++ b/third_party/blink/renderer/core/html/html_embed_element_test.cc
@@ -49,7 +49,7 @@
 
   UpdateAllLifecyclePhasesForTest();
 
-  ComputedStyle* initial_style =
+  scoped_refptr<ComputedStyle> initial_style =
       GetDocument().GetStyleResolver().InitialStyleForElement();
 
   // We should get |true| as a result and don't trigger a DCHECK.
diff --git a/third_party/blink/renderer/core/html/html_frame_element.cc b/third_party/blink/renderer/core/html/html_frame_element.cc
index 52b8fe1f..6f83a90 100644
--- a/third_party/blink/renderer/core/html/html_frame_element.cc
+++ b/third_party/blink/renderer/core/html/html_frame_element.cc
@@ -44,7 +44,7 @@
 
 LayoutObject* HTMLFrameElement::CreateLayoutObject(const ComputedStyle&,
                                                    LegacyLayout) {
-  return MakeGarbageCollected<LayoutFrame>(this);
+  return new LayoutFrame(this);
 }
 
 bool HTMLFrameElement::NoResize() const {
diff --git a/third_party/blink/renderer/core/html/html_frame_set_element.cc b/third_party/blink/renderer/core/html/html_frame_set_element.cc
index b1b9252..9017e5ff 100644
--- a/third_party/blink/renderer/core/html/html_frame_set_element.cc
+++ b/third_party/blink/renderer/core/html/html_frame_set_element.cc
@@ -234,7 +234,7 @@
     const ComputedStyle& style,
     LegacyLayout legacy) {
   if (style.ContentBehavesAsNormal())
-    return MakeGarbageCollected<LayoutFrameSet>(this);
+    return new LayoutFrameSet(this);
   return LayoutObject::CreateObject(this, style, legacy);
 }
 
diff --git a/third_party/blink/renderer/core/html/html_html_element.cc b/third_party/blink/renderer/core/html/html_html_element.cc
index eae0d41..542fe67 100644
--- a/third_party/blink/renderer/core/html/html_html_element.cc
+++ b/third_party/blink/renderer/core/html/html_html_element.cc
@@ -118,9 +118,10 @@
          layout_style.Direction() != propagated_style.Direction();
 }
 
-ComputedStyle* CreateLayoutStyle(const ComputedStyle& style,
-                                 const ComputedStyle& propagated_style) {
-  ComputedStyle* layout_style = ComputedStyle::Clone(style);
+scoped_refptr<ComputedStyle> CreateLayoutStyle(
+    const ComputedStyle& style,
+    const ComputedStyle& propagated_style) {
+  scoped_refptr<ComputedStyle> layout_style = ComputedStyle::Clone(style);
   layout_style->SetDirection(propagated_style.Direction());
   layout_style->SetWritingMode(propagated_style.GetWritingMode());
   return layout_style;
@@ -128,8 +129,8 @@
 
 }  // namespace
 
-const ComputedStyle* HTMLHtmlElement::LayoutStyleForElement(
-    const ComputedStyle* style) {
+scoped_refptr<const ComputedStyle> HTMLHtmlElement::LayoutStyleForElement(
+    scoped_refptr<const ComputedStyle> style) {
   DCHECK(style);
   DCHECK(GetDocument().InStyleRecalc());
   if (const Element* body_element = GetDocument().body()) {
@@ -164,7 +165,7 @@
 }
 
 void HTMLHtmlElement::AttachLayoutTree(AttachContext& context) {
-  const ComputedStyle* original_style = GetComputedStyle();
+  scoped_refptr<const ComputedStyle> original_style = GetComputedStyle();
   if (original_style)
     SetComputedStyle(LayoutStyleForElement(original_style));
 
diff --git a/third_party/blink/renderer/core/html/html_html_element.h b/third_party/blink/renderer/core/html/html_html_element.h
index 1b2329b..a9054de 100644
--- a/third_party/blink/renderer/core/html/html_html_element.h
+++ b/third_party/blink/renderer/core/html/html_html_element.h
@@ -39,7 +39,8 @@
 
   bool HasNonInBodyInsertionMode() const override { return true; }
   void PropagateWritingModeAndDirectionFromBody();
-  const ComputedStyle* LayoutStyleForElement(const ComputedStyle* style);
+  scoped_refptr<const ComputedStyle> LayoutStyleForElement(
+      scoped_refptr<const ComputedStyle> style);
 
  private:
   void MaybeSetupApplicationCache();
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.cc b/third_party/blink/renderer/core/html/html_iframe_element.cc
index edc2f7b..bc068328 100644
--- a/third_party/blink/renderer/core/html/html_iframe_element.cc
+++ b/third_party/blink/renderer/core/html/html_iframe_element.cc
@@ -373,7 +373,7 @@
 
 LayoutObject* HTMLIFrameElement::CreateLayoutObject(const ComputedStyle&,
                                                     LegacyLayout) {
-  return MakeGarbageCollected<LayoutIFrame>(this);
+  return new LayoutIFrame(this);
 }
 
 Node::InsertionNotificationRequest HTMLIFrameElement::InsertedInto(
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc
index 6b65620..60abecc 100644
--- a/third_party/blink/renderer/core/html/html_image_element.cc
+++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -456,7 +456,7 @@
     case LayoutDisposition::kFallbackContent:
       return LayoutObjectFactory::CreateBlockFlow(*this, style, legacy);
     case LayoutDisposition::kPrimaryContent: {
-      LayoutImage* image = MakeGarbageCollected<LayoutImage>(this);
+      LayoutImage* image = new LayoutImage(this);
       image->SetImageResource(MakeGarbageCollected<LayoutImageResource>());
       image->SetImageDevicePixelRatio(image_device_pixel_ratio_);
       return image;
@@ -890,14 +890,15 @@
   SetForceReattachLayoutTree();
 }
 
-ComputedStyle* HTMLImageElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> HTMLImageElement::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
   switch (layout_disposition_) {
     case LayoutDisposition::kPrimaryContent:  // Fall through.
     case LayoutDisposition::kCollapsed:
       return OriginalStyleForLayoutObject(style_recalc_context);
     case LayoutDisposition::kFallbackContent: {
-      ComputedStyle* style = OriginalStyleForLayoutObject(style_recalc_context);
+      scoped_refptr<ComputedStyle> style =
+          OriginalStyleForLayoutObject(style_recalc_context);
       HTMLImageFallbackHelper::CustomStyleForAltText(*this, *style);
       return style;
     }
diff --git a/third_party/blink/renderer/core/html/html_image_element.h b/third_party/blink/renderer/core/html/html_image_element.h
index e85a774..3d6b773 100644
--- a/third_party/blink/renderer/core/html/html_image_element.h
+++ b/third_party/blink/renderer/core/html/html_image_element.h
@@ -206,7 +206,8 @@
   void DidMoveToNewDocument(Document& old_document) override;
 
   void DidAddUserAgentShadowRoot(ShadowRoot&) override;
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) override;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) override;
 
  private:
   bool AreAuthorShadowsAllowed() const override { return false; }
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.cc b/third_party/blink/renderer/core/html/html_plugin_element.cc
index a328305..afa4f71e 100644
--- a/third_party/blink/renderer/core/html/html_plugin_element.cc
+++ b/third_party/blink/renderer/core/html/html_plugin_element.cc
@@ -345,13 +345,13 @@
     return LayoutObject::CreateObject(this, style, legacy);
 
   if (IsImageType()) {
-    LayoutImage* image = MakeGarbageCollected<LayoutImage>(this);
+    LayoutImage* image = new LayoutImage(this);
     image->SetImageResource(MakeGarbageCollected<LayoutImageResource>());
     return image;
   }
 
   plugin_is_available_ = true;
-  return MakeGarbageCollected<LayoutEmbeddedObject>(this);
+  return new LayoutEmbeddedObject(this);
 }
 
 void HTMLPlugInElement::FinishParsingChildren() {
@@ -672,9 +672,7 @@
         *this, url, plugin_params.Names(), plugin_params.Values(), mime_type,
         load_manually);
     if (!plugin) {
-      layout_object = GetLayoutEmbeddedObject();
-      // LayoutObject can be destroyed between the previous check and here.
-      if (layout_object && !layout_object->ShowsUnavailablePluginIndicator()) {
+      if (!layout_object->ShowsUnavailablePluginIndicator()) {
         plugin_is_available_ = false;
         layout_object->SetPluginAvailability(
             LayoutEmbeddedObject::kPluginMissing);
@@ -803,9 +801,10 @@
   }
 }
 
-ComputedStyle* HTMLPlugInElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> HTMLPlugInElement::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
-  ComputedStyle* style = OriginalStyleForLayoutObject(style_recalc_context);
+  scoped_refptr<ComputedStyle> style =
+      OriginalStyleForLayoutObject(style_recalc_context);
   if (IsImageType() && !GetLayoutObject() && style &&
       LayoutObjectIsNeeded(*style)) {
     if (!image_loader_)
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.h b/third_party/blink/renderer/core/html/html_plugin_element.h
index 9d2632f..b3fb2fe 100644
--- a/third_party/blink/renderer/core/html/html_plugin_element.h
+++ b/third_party/blink/renderer/core/html/html_plugin_element.h
@@ -166,7 +166,8 @@
   bool IsFocusableStyle() const final;
   bool IsKeyboardFocusable() const final;
   void DidAddUserAgentShadowRoot(ShadowRoot&) final;
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) final;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) final;
 
   // HTMLElement overrides:
   bool HasCustomFocusLogic() const override;
diff --git a/third_party/blink/renderer/core/html/html_popup_element.cc b/third_party/blink/renderer/core/html/html_popup_element.cc
index 04b60af..ef3574b 100644
--- a/third_party/blink/renderer/core/html/html_popup_element.cc
+++ b/third_party/blink/renderer/core/html/html_popup_element.cc
@@ -261,9 +261,8 @@
     if (const auto* invoker = popup->invoker_.Get())
       anchors_and_invokers.Set(invoker, popup);
   }
-  // TODO(masonf) Should this be a flat tree parent traversal?
   for (Node* current_node = start_node; current_node;
-       current_node = current_node->ParentOrShadowHostNode()) {
+       current_node = FlatTreeTraversal::Parent(*current_node)) {
     // Parent popup element (or the start_node itself, if <popup>).
     if (auto* popup = DynamicTo<HTMLPopupElement>(current_node)) {
       if (popup->open())
@@ -297,9 +296,15 @@
   auto& document = target_node->GetDocument();
   DCHECK(document.PopupShowing());
   const AtomicString& event_type = event.type();
-  if (event_type == event_type_names::kClick ||
+  if (event_type == event_type_names::kMousedown ||
       event_type == event_type_names::kScroll) {
-    // For click or scroll, hide everything up to the clicked/scrolled element.
+    // - For scroll, hide everything up to the scrolled element, to allow
+    //   scrolling within a popup.
+    // - For mousedown, hide everything up to the clicked element. We do
+    //   this on mousedown, rather than mouseup/click, for two reasons:
+    //    1. This mirrors typical platform popups, which dismiss on mousedown.
+    //    2. This allows a mouse-drag that starts on a popup and finishes off
+    //       the popup, without light-dismissing the popup.
     document.HideAllPopupsUntil(NearestOpenAncestralPopup(target_node));
   } else if (event_type == event_type_names::kKeydown) {
     const KeyboardEvent* key_event = DynamicTo<KeyboardEvent>(event);
@@ -337,9 +342,10 @@
 
 // TODO(crbug.com/1197720): The popup position should be provided by the new
 // anchored positioning scheme.
-ComputedStyle* HTMLPopupElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> HTMLPopupElement::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
-  ComputedStyle* style = OriginalStyleForLayoutObject(style_recalc_context);
+  scoped_refptr<ComputedStyle> style =
+      OriginalStyleForLayoutObject(style_recalc_context);
   if (NeedsRepositioningForSelectMenu())
     AdjustPopupPositionForSelectMenu(*style);
   return style;
diff --git a/third_party/blink/renderer/core/html/html_popup_element.h b/third_party/blink/renderer/core/html/html_popup_element.h
index 779f7fa..74048912f 100644
--- a/third_party/blink/renderer/core/html/html_popup_element.h
+++ b/third_party/blink/renderer/core/html/html_popup_element.h
@@ -43,7 +43,8 @@
   void SetNeedsRepositioningForSelectMenu(bool flag);
   bool NeedsRepositioningForSelectMenu() const;
   void SetOwnerSelectMenuElement(HTMLSelectMenuElement*);
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) final;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) final;
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/core/html/html_ruby_element.cc b/third_party/blink/renderer/core/html/html_ruby_element.cc
index 0fd2921..96c3ae0 100644
--- a/third_party/blink/renderer/core/html/html_ruby_element.cc
+++ b/third_party/blink/renderer/core/html/html_ruby_element.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/html/html_ruby_element.h"
 
+#include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/html_names.h"
 #include "third_party/blink/renderer/core/layout/layout_object_factory.h"
 #include "third_party/blink/renderer/core/layout/layout_ruby.h"
@@ -16,7 +17,7 @@
 LayoutObject* HTMLRubyElement::CreateLayoutObject(const ComputedStyle& style,
                                                   LegacyLayout legacy) {
   if (style.Display() == EDisplay::kInline)
-    return MakeGarbageCollected<LayoutRubyAsInline>(this);
+    return new LayoutRubyAsInline(this);
   if (style.Display() == EDisplay::kBlock) {
     UseCounter::Count(GetDocument(), WebFeature::kRubyElementWithDisplayBlock);
     return LayoutObjectFactory::CreateRubyAsBlock(this, style, legacy);
diff --git a/third_party/blink/renderer/core/html/html_script_element.cc b/third_party/blink/renderer/core/html/html_script_element.cc
index 74d618d..9e8b91e 100644
--- a/third_party/blink/renderer/core/html/html_script_element.cc
+++ b/third_party/blink/renderer/core/html/html_script_element.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/public/mojom/script/script_type.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/html_script_element_or_svg_script_element.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_htmlscriptelement_svgscriptelement.h"
 #include "third_party/blink/renderer/core/dom/attribute.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
@@ -136,8 +137,24 @@
   result.SetString(TextFromChildren());
 }
 
-void HTMLScriptElement::setInnerText(
-    const StringOrTrustedScript& string_or_trusted_script,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void HTMLScriptElement::setInnerTextForBinding(
+    const V8UnionStringTreatNullAsEmptyStringOrTrustedScript*
+        string_or_trusted_script,
+    ExceptionState& exception_state) {
+  const String& value = TrustedTypesCheckForScript(
+      string_or_trusted_script, GetExecutionContext(), exception_state);
+  if (exception_state.HadException())
+    return;
+  // https://w3c.github.io/webappsec-trusted-types/dist/spec/#setting-slot-values
+  // On setting, the innerText [...] perform the regular steps, and then set
+  // content object's [[ScriptText]] internal slot value [...].
+  HTMLElement::setInnerText(value, exception_state);
+  script_text_internal_slot_ = ParkableString(value.Impl());
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void HTMLScriptElement::setInnerTextForBinding(
+    const StringTreatNullAsEmptyStringOrTrustedScript& string_or_trusted_script,
     ExceptionState& exception_state) {
   String value = TrustedTypesCheckForScript(
       string_or_trusted_script, GetExecutionContext(), exception_state);
@@ -149,16 +166,24 @@
     script_text_internal_slot_ = ParkableString(value.Impl());
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
-void HTMLScriptElement::setTextContent(const String& string) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void HTMLScriptElement::setTextContentForBinding(
+    const V8UnionStringOrTrustedScript* value,
+    ExceptionState& exception_state) {
+  const String& string =
+      TrustedTypesCheckForScript(value, GetExecutionContext(), exception_state);
+  if (exception_state.HadException())
+    return;
   // https://w3c.github.io/webappsec-trusted-types/dist/spec/#setting-slot-values
   // On setting, [..] textContent [..] perform the regular steps, and then set
   // content object's [[ScriptText]] internal slot value [...].
   Node::setTextContent(string);
   script_text_internal_slot_ = ParkableString(string.Impl());
 }
-
-void HTMLScriptElement::setTextContent(
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void HTMLScriptElement::setTextContentForBinding(
     const StringOrTrustedScript& string_or_trusted_script,
     ExceptionState& exception_state) {
   String value = TrustedTypesCheckForScript(
@@ -171,6 +196,15 @@
     script_text_internal_slot_ = ParkableString(value.Impl());
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+void HTMLScriptElement::setTextContent(const String& string) {
+  // https://w3c.github.io/webappsec-trusted-types/dist/spec/#setting-slot-values
+  // On setting, [..] textContent [..] perform the regular steps, and then set
+  // content object's [[ScriptText]] internal slot value [...].
+  Node::setTextContent(string);
+  script_text_internal_slot_ = ParkableString(string.Impl());
+}
 
 void HTMLScriptElement::setAsync(bool async) {
   // https://html.spec.whatwg.org/multipage/scripting.html#dom-script-async
@@ -290,6 +324,20 @@
   return Node::GetExecutionContext();
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8HTMLOrSVGScriptElement* HTMLScriptElement::AsV8HTMLOrSVGScriptElement() {
+  if (IsInShadowTree())
+    return nullptr;
+  return MakeGarbageCollected<V8HTMLOrSVGScriptElement>(this);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void HTMLScriptElement::SetScriptElementForBinding(
+    HTMLScriptElementOrSVGScriptElement& element) {
+  if (!IsInShadowTree())
+    element.SetHTMLScriptElement(this);
+}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void HTMLScriptElement::DispatchLoadEvent() {
   DispatchEvent(*Event::Create(event_type_names::kLoad));
 }
@@ -298,12 +346,6 @@
   DispatchEvent(*Event::Create(event_type_names::kError));
 }
 
-void HTMLScriptElement::SetScriptElementForBinding(
-    HTMLScriptElementOrSVGScriptElement& element) {
-  if (!IsInShadowTree())
-    element.SetHTMLScriptElement(this);
-}
-
 ScriptElementBase::Type HTMLScriptElement::GetScriptElementType() {
   return ScriptElementBase::Type::kHTMLScriptElement;
 }
diff --git a/third_party/blink/renderer/core/html/html_script_element.h b/third_party/blink/renderer/core/html/html_script_element.h
index c0c0ed94..31b748a 100644
--- a/third_party/blink/renderer/core/html/html_script_element.h
+++ b/third_party/blink/renderer/core/html/html_script_element.h
@@ -31,6 +31,7 @@
 #include "third_party/blink/renderer/core/script/script_element_base.h"
 #include "third_party/blink/renderer/core/script/script_loader.h"
 #include "third_party/blink/renderer/platform/bindings/parkable_string.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 
@@ -50,8 +51,20 @@
   void text(StringOrTrustedScript& result);
   String text() { return TextFromChildren(); }
   void setText(const String&);
-  void setInnerText(const StringOrTrustedScript&, ExceptionState&) override;
-  void setTextContent(const StringOrTrustedScript&, ExceptionState&) override;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void setInnerTextForBinding(
+      const V8UnionStringTreatNullAsEmptyStringOrTrustedScript*
+          string_or_trusted_script,
+      ExceptionState& exception_state) override;
+  void setTextContentForBinding(const V8UnionStringOrTrustedScript* value,
+                                ExceptionState& exception_state) override;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void setInnerTextForBinding(
+      const StringTreatNullAsEmptyStringOrTrustedScript&,
+      ExceptionState&) override;
+  void setTextContentForBinding(const StringOrTrustedScript&,
+                                ExceptionState&) override;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void setTextContent(const String&) override;
 
   void setAsync(bool);
@@ -63,6 +76,13 @@
   Document& GetDocument() const override;
   ExecutionContext* GetExecutionContext() const override;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8HTMLOrSVGScriptElement* AsV8HTMLOrSVGScriptElement() override;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void SetScriptElementForBinding(
+      HTMLScriptElementOrSVGScriptElement&) override;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
   void Trace(Visitor*) const override;
 
   void FinishParsingChildren() override;
@@ -106,8 +126,6 @@
                                const String& script_content) override;
   void DispatchLoadEvent() override;
   void DispatchErrorEvent() override;
-  void SetScriptElementForBinding(
-      HTMLScriptElementOrSVGScriptElement&) override;
 
   Type GetScriptElementType() override;
 
diff --git a/third_party/blink/renderer/core/html/html_wbr_element.cc b/third_party/blink/renderer/core/html/html_wbr_element.cc
index 77caad3..e09ec10 100644
--- a/third_party/blink/renderer/core/html/html_wbr_element.cc
+++ b/third_party/blink/renderer/core/html/html_wbr_element.cc
@@ -40,7 +40,7 @@
 
 LayoutObject* HTMLWBRElement::CreateLayoutObject(const ComputedStyle& style,
                                                  LegacyLayout) {
-  return MakeGarbageCollected<LayoutWordBreak>(this);
+  return new LayoutWordBreak(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc
index 6cf53eb0..4b8e576 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -745,7 +745,7 @@
 
 LayoutObject* HTMLMediaElement::CreateLayoutObject(const ComputedStyle&,
                                                    LegacyLayout) {
-  return MakeGarbageCollected<LayoutMedia>(this);
+  return new LayoutMedia(this);
 }
 
 Node::InsertionNotificationRequest HTMLMediaElement::InsertedInto(
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.cc b/third_party/blink/renderer/core/html/media/html_video_element.cc
index 58c6c87..7b7bcea 100644
--- a/third_party/blink/renderer/core/html/media/html_video_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -148,7 +148,7 @@
 
 LayoutObject* HTMLVideoElement::CreateLayoutObject(const ComputedStyle&,
                                                    LegacyLayout) {
-  return MakeGarbageCollected<LayoutVideo>(this);
+  return new LayoutVideo(this);
 }
 
 void HTMLVideoElement::AttachLayoutTree(AttachContext& context) {
diff --git a/third_party/blink/renderer/core/html/media/media_source_registry.h b/third_party/blink/renderer/core/html/media/media_source_registry.h
index 528131e..1de8fb0 100644
--- a/third_party/blink/renderer/core/html/media/media_source_registry.h
+++ b/third_party/blink/renderer/core/html/media/media_source_registry.h
@@ -6,7 +6,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_SOURCE_REGISTRY_H_
 
 #include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/fileapi/url_registry.h"
 #include "third_party/blink/renderer/core/html/media/media_source_attachment.h"
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.cc b/third_party/blink/renderer/core/html/portal/html_portal_element.cc
index b26ced87..b554a4c 100644
--- a/third_party/blink/renderer/core/html/portal/html_portal_element.cc
+++ b/third_party/blink/renderer/core/html/portal/html_portal_element.cc
@@ -518,7 +518,7 @@
 
 LayoutObject* HTMLPortalElement::CreateLayoutObject(const ComputedStyle& style,
                                                     LegacyLayout) {
-  return MakeGarbageCollected<LayoutIFrame>(this);
+  return new LayoutIFrame(this);
 }
 
 bool HTMLPortalElement::SupportsFocus() const {
diff --git a/third_party/blink/renderer/core/html/shadow/progress_shadow_element.cc b/third_party/blink/renderer/core/html/shadow/progress_shadow_element.cc
index 8122e1051..7cd7a66 100644
--- a/third_party/blink/renderer/core/html/shadow/progress_shadow_element.cc
+++ b/third_party/blink/renderer/core/html/shadow/progress_shadow_element.cc
@@ -44,9 +44,10 @@
   return To<HTMLProgressElement>(OwnerShadowHost());
 }
 
-ComputedStyle* ProgressShadowElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> ProgressShadowElement::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
-  ComputedStyle* style = OriginalStyleForLayoutObject(style_recalc_context);
+  scoped_refptr<ComputedStyle> style =
+      OriginalStyleForLayoutObject(style_recalc_context);
   const ComputedStyle* progress_style = ProgressElement()->GetComputedStyle();
   DCHECK(progress_style);
   if (progress_style->HasEffectiveAppearance())
diff --git a/third_party/blink/renderer/core/html/shadow/progress_shadow_element.h b/third_party/blink/renderer/core/html/shadow/progress_shadow_element.h
index fc08697..3f5c1f9 100644
--- a/third_party/blink/renderer/core/html/shadow/progress_shadow_element.h
+++ b/third_party/blink/renderer/core/html/shadow/progress_shadow_element.h
@@ -45,7 +45,8 @@
 
  private:
   HTMLProgressElement* ProgressElement() const;
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) override;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) override;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc b/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc
index 895eaf9..4e8c0ec 100644
--- a/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc
+++ b/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc
@@ -44,7 +44,7 @@
   GetDocument().GetStyleEngine().RecalcStyle();
   EXPECT_TRUE(shadow_element->GetComputedStyle());
 
-  ComputedStyle* style =
+  scoped_refptr<ComputedStyle> style =
       shadow_element->StyleForLayoutObject(StyleRecalcContext());
   EXPECT_TRUE(shadow_element->LayoutObjectIsNeeded(*style));
 }
diff --git a/third_party/blink/renderer/core/html/track/text_track_container.cc b/third_party/blink/renderer/core/html/track/text_track_container.cc
index 5ee2ab31..d020de4 100644
--- a/third_party/blink/renderer/core/html/track/text_track_container.cc
+++ b/third_party/blink/renderer/core/html/track/text_track_container.cc
@@ -109,7 +109,7 @@
   // typically be a child of LayoutVideo (a legacy type), and we'll typically
   // also insert a LayoutVTTCue (a LayoutBlockFlow type) child, which also isn't
   // implemented in NG.
-  return MakeGarbageCollected<LayoutBlockFlow>(this);
+  return new LayoutBlockFlow(this);
 }
 
 void TextTrackContainer::ObserveSizeChanges(Element& element) {
diff --git a/third_party/blink/renderer/core/html/track/track_event.cc b/third_party/blink/renderer/core/html/track/track_event.cc
index e875488a..fb1f252 100644
--- a/third_party/blink/renderer/core/html/track/track_event.cc
+++ b/third_party/blink/renderer/core/html/track/track_event.cc
@@ -27,6 +27,7 @@
 
 #include "third_party/blink/public/platform/web_media_player.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_track_event_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_audiotrack_texttrack_videotrack.h"
 #include "third_party/blink/renderer/bindings/core/v8/video_track_or_audio_track_or_text_track.h"
 #include "third_party/blink/renderer/core/event_interface_names.h"
 #include "third_party/blink/renderer/core/html/track/audio_track.h"
@@ -60,6 +61,27 @@
   return event_interface_names::kTrackEvent;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionAudioTrackOrTextTrackOrVideoTrack* TrackEvent::track() {
+  if (!track_)
+    return nullptr;
+
+  switch (track_->GetType()) {
+    case WebMediaPlayer::kTextTrack:
+      return MakeGarbageCollected<V8UnionAudioTrackOrTextTrackOrVideoTrack>(
+          To<TextTrack>(track_.Get()));
+    case WebMediaPlayer::kAudioTrack:
+      return MakeGarbageCollected<V8UnionAudioTrackOrTextTrackOrVideoTrack>(
+          To<AudioTrack>(track_.Get()));
+    case WebMediaPlayer::kVideoTrack:
+      return MakeGarbageCollected<V8UnionAudioTrackOrTextTrackOrVideoTrack>(
+          To<VideoTrack>(track_.Get()));
+  }
+
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void TrackEvent::track(VideoTrackOrAudioTrackOrTextTrack& return_value) {
   if (!track_)
     return;
@@ -78,6 +100,7 @@
       NOTREACHED();
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void TrackEvent::Trace(Visitor* visitor) const {
   visitor->Trace(track_);
diff --git a/third_party/blink/renderer/core/html/track/track_event.h b/third_party/blink/renderer/core/html/track/track_event.h
index af6a98f9..69e7ae7 100644
--- a/third_party/blink/renderer/core/html/track/track_event.h
+++ b/third_party/blink/renderer/core/html/track/track_event.h
@@ -32,6 +32,7 @@
 namespace blink {
 
 class TrackEventInit;
+class V8UnionAudioTrackOrTextTrackOrVideoTrack;
 class VideoTrackOrAudioTrackOrTextTrack;
 
 class CORE_EXPORT TrackEvent final : public Event {
@@ -57,7 +58,11 @@
 
   const AtomicString& InterfaceName() const override;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionAudioTrackOrTextTrackOrVideoTrack* track();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void track(VideoTrackOrAudioTrackOrTextTrack&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
index 87e896ea..3fe8c385 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
@@ -31,6 +31,7 @@
 
 #include "base/stl_util.h"
 #include "third_party/blink/renderer/bindings/core/v8/double_or_auto_keyword.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_autokeyword_double.h"
 #include "third_party/blink/renderer/core/css/css_property_names.h"
 #include "third_party/blink/renderer/core/css_value_keywords.h"
 #include "third_party/blink/renderer/core/dom/document_fragment.h"
@@ -73,10 +74,12 @@
               "displayAlignmentMap should have the same number of elements as "
               "VTTCue::NumberOfAlignments");
 
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 static const String& AutoKeyword() {
   DEFINE_STATIC_LOCAL(const String, auto_string, ("auto"));
   return auto_string;
 }
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 static const String& StartKeyword() {
   DEFINE_STATIC_LOCAL(const String, start, ("start"));
@@ -238,7 +241,7 @@
     return HTMLDivElement::CreateLayoutObject(style, legacy);
 
   UseCounter::Count(GetDocument(), WebFeature::kLegacyLayoutByVTTCue);
-  return MakeGarbageCollected<LayoutVTTCue>(this, snap_to_lines_position_);
+  return new LayoutVTTCue(this, snap_to_lines_position_);
 }
 
 VTTCue::VTTCue(Document& document,
@@ -320,6 +323,44 @@
   return std::isnan(line_position_);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8UnionAutoKeywordOrDouble* VTTCue::line() const {
+  if (LineIsAuto()) {
+    return MakeGarbageCollected<V8UnionAutoKeywordOrDouble>(
+        V8AutoKeyword(V8AutoKeyword::Enum::kAuto));
+  }
+  return MakeGarbageCollected<V8UnionAutoKeywordOrDouble>(line_position_);
+}
+
+void VTTCue::setLine(const V8UnionAutoKeywordOrDouble* position) {
+  // http://dev.w3.org/html5/webvtt/#dfn-vttcue-line
+  // On setting, the WebVTT cue line must be set to the new value; if the new
+  // value is the string "auto", then it must be interpreted as the special
+  // value auto.  ("auto" is translated to NaN.)
+  double line_position = 0;
+  switch (position->GetContentType()) {
+    case V8UnionAutoKeywordOrDouble::ContentType::kAutoKeyword: {
+      if (LineIsAuto())
+        return;
+      line_position = std::numeric_limits<double>::quiet_NaN();
+      break;
+    }
+    case V8UnionAutoKeywordOrDouble::ContentType::kDouble: {
+      line_position = position->GetAsDouble();
+      if (line_position_ == line_position)
+        return;
+      break;
+    }
+  }
+
+  CueWillChange();
+  line_position_ = line_position;
+  CueDidChange();
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void VTTCue::line(DoubleOrAutoKeyword& result) const {
   if (LineIsAuto())
     result.SetAutoKeyword(AutoKeyword());
@@ -348,10 +389,54 @@
   CueDidChange();
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 bool VTTCue::TextPositionIsAuto() const {
   return std::isnan(text_position_);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8UnionAutoKeywordOrDouble* VTTCue::position() const {
+  if (TextPositionIsAuto()) {
+    return MakeGarbageCollected<V8UnionAutoKeywordOrDouble>(
+        V8AutoKeyword(V8AutoKeyword::Enum::kAuto));
+  }
+  return MakeGarbageCollected<V8UnionAutoKeywordOrDouble>(text_position_);
+}
+
+void VTTCue::setPosition(const V8UnionAutoKeywordOrDouble* position,
+                         ExceptionState& exception_state) {
+  // http://dev.w3.org/html5/webvtt/#dfn-vttcue-position
+  // On setting, if the new value is negative or greater than 100, then an
+  // IndexSizeError exception must be thrown. Otherwise, the WebVTT cue
+  // position must be set to the new value; if the new value is the string
+  // "auto", then it must be interpreted as the special value auto.
+  double text_position = 0;
+  switch (position->GetContentType()) {
+    case V8UnionAutoKeywordOrDouble::ContentType::kAutoKeyword: {
+      if (TextPositionIsAuto())
+        return;
+      text_position = std::numeric_limits<double>::quiet_NaN();
+      break;
+    }
+    case V8UnionAutoKeywordOrDouble::ContentType::kDouble: {
+      text_position = position->GetAsDouble();
+      if (IsInvalidPercentage(text_position, exception_state))
+        return;
+      if (text_position_ == text_position)
+        return;
+      break;
+    }
+  }
+
+  CueWillChange();
+  text_position_ = text_position;
+  CueDidChange();
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void VTTCue::position(DoubleOrAutoKeyword& result) const {
   if (TextPositionIsAuto())
     result.SetAutoKeyword(AutoKeyword());
@@ -385,6 +470,8 @@
   CueDidChange();
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void VTTCue::setSize(double size, ExceptionState& exception_state) {
   // http://dev.w3.org/html5/webvtt/#dfn-vttcue-size
   // On setting, if the new value is negative or greater than 100, then throw
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
index 76b9ce8..076aa1e 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
@@ -40,6 +40,7 @@
 class Document;
 class DoubleOrAutoKeyword;
 class ExecutionContext;
+class V8UnionAutoKeywordOrDouble;
 class VTTCue;
 class VTTRegion;
 class VTTScanner;
@@ -118,11 +119,22 @@
   bool snapToLines() const { return snap_to_lines_; }
   void setSnapToLines(bool);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionAutoKeywordOrDouble* line() const;
+  void setLine(const V8UnionAutoKeywordOrDouble* position);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void line(DoubleOrAutoKeyword&) const;
   void setLine(const DoubleOrAutoKeyword&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionAutoKeywordOrDouble* position() const;
+  void setPosition(const V8UnionAutoKeywordOrDouble* position,
+                   ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void position(DoubleOrAutoKeyword&) const;
   void setPosition(const DoubleOrAutoKeyword&, ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   double size() const { return cue_size_; }
   void setSize(double, ExceptionState&);
diff --git a/third_party/blink/renderer/core/input/overscroll_behavior_test.cc b/third_party/blink/renderer/core/input/overscroll_behavior_test.cc
index e72311d..98fbfd6 100644
--- a/third_party/blink/renderer/core/input/overscroll_behavior_test.cc
+++ b/third_party/blink/renderer/core/input/overscroll_behavior_test.cc
@@ -62,7 +62,7 @@
 void OverscrollBehaviorTest::SetInnerOverscrollBehavior(EOverscrollBehavior x,
                                                         EOverscrollBehavior y) {
   Element* inner = GetDocument().getElementById("inner");
-  ComputedStyle* modified_style =
+  scoped_refptr<ComputedStyle> modified_style =
       ComputedStyle::Clone(*inner->GetComputedStyle());
   modified_style->SetOverscrollBehaviorX(x);
   modified_style->SetOverscrollBehaviorY(y);
diff --git a/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc b/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc
index ed385497..f1265cf 100644
--- a/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc
@@ -331,9 +331,13 @@
     id_to_animation_clone_.Set(id, clone);
     id_to_animation_.Set(String::Number(clone->SequenceNumber()), clone);
     clone->play();
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    clone->setStartTime(animation->startTime(), ASSERT_NO_EXCEPTION);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     CSSNumberish start_time;
     animation->startTime(start_time);
     clone->setStartTime(start_time);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
     animation->SetEffectSuppressed(true);
   }
diff --git a/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc b/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc
index e0f8306..d9d3c04 100644
--- a/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc
@@ -4,9 +4,12 @@
 
 #include "third_party/blink/renderer/core/inspector/inspector_audits_issue.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
 #include "third_party/blink/renderer/core/dom/dom_node_ids.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/inspector/identifiers_factory.h"
 #include "third_party/blink/renderer/core/inspector/protocol/Audits.h"
+#include "third_party/blink/renderer/core/inspector/protocol/Network.h"
 
 namespace blink {
 
@@ -50,4 +53,66 @@
   execution_context->AddInspectorIssue(AuditsIssue(std::move(issue)));
 }
 
+protocol::Network::CorsError RendererCorsIssueCodeToProtocol(
+    RendererCorsIssueCode code) {
+  switch (code) {
+    case RendererCorsIssueCode::kCorsDisabledScheme:
+      return protocol::Network::CorsErrorEnum::CorsDisabledScheme;
+    case RendererCorsIssueCode::kNoCorsRedirectModeNotFollow:
+      return protocol::Network::CorsErrorEnum::NoCorsRedirectModeNotFollow;
+    case RendererCorsIssueCode::kDisallowedByMode:
+      return protocol::Network::CorsErrorEnum::DisallowedByMode;
+  }
+}
+
+std::unique_ptr<protocol::Audits::SourceCodeLocation> CreateProtocolLocation(
+    const SourceLocation& location) {
+  auto protocol_location = protocol::Audits::SourceCodeLocation::create()
+                               .setUrl(location.Url())
+                               .setLineNumber(location.LineNumber() - 1)
+                               .setColumnNumber(location.ColumnNumber())
+                               .build();
+  protocol_location->setScriptId(WTF::String::Number(location.ScriptId()));
+  return protocol_location;
+}
+
+void AuditsIssue::ReportCorsIssue(ExecutionContext* execution_context,
+                                  int64_t identifier,
+                                  RendererCorsIssueCode code,
+                                  String url,
+                                  String initiator_origin,
+                                  String failedParameter) {
+  String devtools_request_id =
+      IdentifiersFactory::SubresourceRequestId(identifier);
+  std::unique_ptr<protocol::Audits::AffectedRequest> affected_request =
+      protocol::Audits::AffectedRequest::create()
+          .setRequestId(devtools_request_id)
+          .setUrl(url)
+          .build();
+  auto protocol_cors_error_status =
+      protocol::Network::CorsErrorStatus::create()
+          .setCorsError(RendererCorsIssueCodeToProtocol(code))
+          .setFailedParameter(failedParameter)
+          .build();
+  auto cors_issue_details =
+      protocol::Audits::CorsIssueDetails::create()
+          .setIsWarning(false)
+          .setRequest(std::move(affected_request))
+          .setCorsErrorStatus(std::move(protocol_cors_error_status))
+          .build();
+  cors_issue_details->setInitiatorOrigin(initiator_origin);
+  auto location = SourceLocation::Capture(execution_context);
+  if (location) {
+    cors_issue_details->setLocation(CreateProtocolLocation(*location));
+  }
+  auto details = protocol::Audits::InspectorIssueDetails::create()
+                     .setCorsIssueDetails(std::move(cors_issue_details))
+                     .build();
+  auto issue = protocol::Audits::InspectorIssue::create()
+                   .setCode(protocol::Audits::InspectorIssueCodeEnum::CorsIssue)
+                   .setDetails(std::move(details))
+                   .build();
+  execution_context->AddInspectorIssue(AuditsIssue(std::move(issue)));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/inspector_audits_issue.h b/third_party/blink/renderer/core/inspector/inspector_audits_issue.h
index fea2f22..c563921 100644
--- a/third_party/blink/renderer/core/inspector/inspector_audits_issue.h
+++ b/third_party/blink/renderer/core/inspector/inspector_audits_issue.h
@@ -9,6 +9,10 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/dom_node_ids.h"
 
+namespace WTF {
+class String;
+}
+
 namespace blink {
 
 class ExecutionContext;
@@ -19,6 +23,12 @@
 }
 }  // namespace protocol
 
+enum class RendererCorsIssueCode {
+  kDisallowedByMode,
+  kCorsDisabledScheme,
+  kNoCorsRedirectModeNotFollow,
+};
+
 // |AuditsIssue| is a thin wrapper around the Audits::InspectorIssue
 // protocol class.
 //
@@ -52,6 +62,13 @@
                                     String frame_id,
                                     String loader_id);
 
+  static void ReportCorsIssue(ExecutionContext* execution_context,
+                              int64_t identifier,
+                              RendererCorsIssueCode code,
+                              WTF::String url,
+                              WTF::String initiator_origin,
+                              WTF::String failedParameter);
+
  private:
   explicit AuditsIssue(std::unique_ptr<protocol::Audits::InspectorIssue> issue);
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_contrast.cc b/third_party/blink/renderer/core/inspector/inspector_contrast.cc
index ce6ae59..2c67724 100644
--- a/third_party/blink/renderer/core/inspector/inspector_contrast.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_contrast.cc
@@ -380,7 +380,7 @@
 void InspectorContrast::SortElementsByPaintOrder(
     HeapVector<Member<Node>>& unsorted_elements,
     Document* document) {
-  InspectorDOMSnapshotAgent::PaintOrderMap* paint_layer_tree =
+  std::unique_ptr<InspectorDOMSnapshotAgent::PaintOrderMap> paint_layer_tree =
       InspectorDOMSnapshotAgent::BuildPaintLayerTree(document);
 
   std::stable_sort(
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
index 559f977..e6b149c3 100644
--- a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc
@@ -330,7 +330,7 @@
   *documents = std::move(documents_);
   *strings = std::move(strings_);
   css_property_filter_.reset();
-  paint_order_map_.Clear();
+  paint_order_map_.reset();
   string_table_.clear();
   document_order_map_.clear();
   documents_.reset();
@@ -743,10 +743,10 @@
 }
 
 // static
-InspectorDOMSnapshotAgent::PaintOrderMap*
+std::unique_ptr<InspectorDOMSnapshotAgent::PaintOrderMap>
 InspectorDOMSnapshotAgent::BuildPaintLayerTree(Document* document) {
-  auto* result = MakeGarbageCollected<PaintOrderMap>();
-  TraversePaintLayerTree(document, result);
+  auto result = std::make_unique<PaintOrderMap>();
+  TraversePaintLayerTree(document, result.get());
   return result;
 }
 
@@ -777,7 +777,7 @@
     return;
   }
 
-  PaintLayerPaintOrderIterator iterator(layer, kAllChildren);
+  PaintLayerPaintOrderIterator iterator(*layer, kAllChildren);
   while (PaintLayer* child_layer = iterator.Next())
     VisitPaintLayer(child_layer, paint_order_map);
 }
@@ -785,10 +785,8 @@
 void InspectorDOMSnapshotAgent::Trace(Visitor* visitor) const {
   visitor->Trace(inspected_frames_);
   visitor->Trace(dom_debugger_agent_);
-  visitor->Trace(paint_order_map_);
   visitor->Trace(document_order_map_);
   visitor->Trace(css_value_cache_);
-  visitor->Trace(style_cache_);
   InspectorBaseAgent::Trace(visitor);
 }
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h
index 19a0275f..6bc2083 100644
--- a/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h
@@ -67,8 +67,8 @@
       const LayoutObject* layout_object,
       const LayoutText::TextBoxInfo& text_box);
 
-  using PaintOrderMap = HeapHashMap<Member<PaintLayer>, int>;
-  static PaintOrderMap* BuildPaintLayerTree(Document*);
+  using PaintOrderMap = WTF::HashMap<PaintLayer*, int>;
+  static std::unique_ptr<PaintOrderMap> BuildPaintLayerTree(Document*);
 
  private:
   // Unconditionally enables the agent, even if |enabled_.Get()==true|.
@@ -114,7 +114,8 @@
   WTF::HashMap<String, int> string_table_;
 
   HeapHashMap<Member<const CSSValue>, int> css_value_cache_;
-  HeapHashMap<Member<const ComputedStyle>, protocol::Array<int>*> style_cache_;
+  HashMap<scoped_refptr<const ComputedStyle>, protocol::Array<int>*>
+      style_cache_;
 
   std::unique_ptr<protocol::Array<protocol::DOMSnapshot::DocumentSnapshot>>
       documents_;
@@ -125,7 +126,7 @@
   bool include_text_color_opacities_ = false;
   std::unique_ptr<CSSPropertyFilter> css_property_filter_;
   // Maps a PaintLayer to its paint order index.
-  Member<PaintOrderMap> paint_order_map_;
+  std::unique_ptr<PaintOrderMap> paint_order_map_;
   // Maps a backend node id to the url of the script (if any) that generates
   // the corresponding node.
   std::unique_ptr<OriginUrlMap> origin_url_map_;
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
index 828dc818f..1d340d7 100644
--- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -709,7 +709,7 @@
 
 void inspector_layout_event::EndData(
     perfetto::TracedValue context,
-    const HeapVector<LayoutObjectWithDepth>& layout_roots) {
+    const Vector<LayoutObjectWithDepth>& layout_roots) {
   auto dict = std::move(context).WriteDictionary();
   {
     auto array = dict.AddArray("layoutRoots");
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.h b/third_party/blink/renderer/core/inspector/inspector_trace_events.h
index a465144..485c451 100644
--- a/third_party/blink/renderer/core/inspector/inspector_trace_events.h
+++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.h
@@ -169,7 +169,7 @@
 namespace inspector_layout_event {
 void BeginData(perfetto::TracedValue context, LocalFrameView*);
 void EndData(perfetto::TracedValue context,
-             const HeapVector<LayoutObjectWithDepth>&);
+             const Vector<LayoutObjectWithDepth>&);
 }  // namespace inspector_layout_event
 
 namespace inspector_schedule_style_invalidation_tracking_event {
diff --git a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
index e99d87f51..28f0fe6 100644
--- a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
+++ b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
@@ -147,7 +147,7 @@
   *computed_styles = std::move(computed_styles_);
   computed_styles_map_.reset();
   css_property_filter_.reset();
-  paint_order_map_ = nullptr;
+  paint_order_map_.reset();
   return Response::Success();
 }
 
diff --git a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h
index 29634f1..245b7845 100644
--- a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h
+++ b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h
@@ -79,7 +79,7 @@
                                          VectorStringHashTraits,
                                          VectorStringHashTraits>;
   using CSSPropertyFilter = Vector<std::pair<String, CSSPropertyID>>;
-  using PaintOrderMap = HeapHashMap<Member<PaintLayer>, int>;
+  using PaintOrderMap = WTF::HashMap<PaintLayer*, int>;
 
   // State of current snapshot.
   std::unique_ptr<protocol::Array<protocol::DOMSnapshot::DOMNode>> dom_nodes_;
@@ -93,7 +93,7 @@
   std::unique_ptr<ComputedStylesMap> computed_styles_map_;
   std::unique_ptr<CSSPropertyFilter> css_property_filter_;
   // Maps a PaintLayer to its paint order index.
-  PaintOrderMap* paint_order_map_ = nullptr;
+  std::unique_ptr<PaintOrderMap> paint_order_map_;
   // Maps a backend node id to the url of the script (if any) that generates
   // the corresponding node.
   OriginUrlMap* origin_url_map_;
diff --git a/third_party/blink/renderer/core/layout/api/line_layout_item.h b/third_party/blink/renderer/core/layout/api/line_layout_item.h
index 78d3143..07fb907 100644
--- a/third_party/blink/renderer/core/layout/api/line_layout_item.h
+++ b/third_party/blink/renderer/core/layout/api/line_layout_item.h
@@ -66,8 +66,7 @@
   Node* NonPseudoNode() const { return layout_object_->NonPseudoNode(); }
 
   Node* GetNodeForOwnerNodeId() const {
-    auto* layout_text_fragment =
-        DynamicTo<LayoutTextFragment>(layout_object_.Get());
+    auto* layout_text_fragment = DynamicTo<LayoutTextFragment>(layout_object_);
     if (layout_text_fragment)
       return layout_text_fragment->AssociatedTextNode();
     return layout_object_->GetNode();
@@ -214,8 +213,7 @@
   bool IsText() const { return layout_object_->IsText(); }
 
   bool IsEmptyText() const {
-    return IsText() &&
-           To<LayoutText>(layout_object_.Get())->GetText().IsEmpty();
+    return IsText() && To<LayoutText>(layout_object_)->GetText().IsEmpty();
   }
 
   bool HasLayer() const { return layout_object_->HasLayer(); }
@@ -354,7 +352,7 @@
   const LayoutObject* GetLayoutObject() const { return layout_object_; }
 
  private:
-  UntracedMember<LayoutObject> layout_object_;
+  LayoutObject* layout_object_;
 
   friend class LayoutBlockFlow;
   friend class LineLayoutAPIShim;
diff --git a/third_party/blink/renderer/core/layout/bidi_run.h b/third_party/blink/renderer/core/layout/bidi_run.h
index 1d5c73779..1bd5a1b8 100644
--- a/third_party/blink/renderer/core/layout/bidi_run.h
+++ b/third_party/blink/renderer/core/layout/bidi_run.h
@@ -57,16 +57,11 @@
     has_hyphen_ = false;
   }
 
-  BidiRun* Next() { return static_cast<BidiRun*>(next_.Get()); }
-
-  void Trace(Visitor* visitor) const final {
-    visitor->Trace(box_);
-    BidiCharacterRun::Trace(visitor);
-  }
+  BidiRun* Next() { return static_cast<BidiRun*>(next_); }
 
  public:
   LineLayoutItem line_layout_item_;
-  Member<InlineBox> box_;
+  InlineBox* box_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/bidi_run_for_line.cc b/third_party/blink/renderer/core/layout/bidi_run_for_line.cc
index 9060aef34..d304a550 100644
--- a/third_party/blink/renderer/core/layout/bidi_run_for_line.cc
+++ b/third_party/blink/renderer/core/layout/bidi_run_for_line.cc
@@ -137,7 +137,7 @@
     LineMidpointState& isolated_line_midpoint_state =
         isolated_resolver.GetMidpointState();
     isolated_line_midpoint_state =
-        top_resolver.MidpointStateForIsolatedRun(*isolated_run.run_to_replace);
+        top_resolver.MidpointStateForIsolatedRun(isolated_run.run_to_replace);
     UnicodeBidi unicode_bidi = isolated_inline.StyleRef().GetUnicodeBidi();
     TextDirection direction;
     if (unicode_bidi == UnicodeBidi::kPlaintext) {
@@ -172,7 +172,7 @@
 
     DCHECK(isolated_resolver.Runs().RunCount());
     if (isolated_resolver.Runs().RunCount())
-      bidi_runs.ReplaceRunWithRuns(isolated_run.run_to_replace,
+      bidi_runs.ReplaceRunWithRuns(&isolated_run.run_to_replace,
                                    isolated_resolver.Runs());
 
     // If we encountered any nested isolate runs, save them for later
@@ -182,9 +182,9 @@
           isolated_resolver.IsolatedRuns().back();
       isolated_resolver.IsolatedRuns().pop_back();
       top_resolver.SetMidpointStateForIsolatedRun(
-          *run_with_context.run_to_replace,
+          run_with_context.run_to_replace,
           isolated_resolver.MidpointStateForIsolatedRun(
-              *run_with_context.run_to_replace));
+              run_with_context.run_to_replace));
       top_resolver.IsolatedRuns().push_back(run_with_context);
     }
   }
diff --git a/third_party/blink/renderer/core/layout/box_layout_extra_input.h b/third_party/blink/renderer/core/layout/box_layout_extra_input.h
index 074a667..d3ad120b 100644
--- a/third_party/blink/renderer/core/layout/box_layout_extra_input.h
+++ b/third_party/blink/renderer/core/layout/box_layout_extra_input.h
@@ -19,7 +19,7 @@
   BoxLayoutExtraInput(LayoutBox&);
   ~BoxLayoutExtraInput();
 
-  UntracedMember<LayoutBox> box;
+  LayoutBox& box;
 
   // When set, no attempt should be be made to resolve the inline size. Use this
   // one instead.
diff --git a/third_party/blink/renderer/core/layout/build.gni b/third_party/blink/renderer/core/layout/build.gni
index a4bad28d..3dbe5db 100644
--- a/third_party/blink/renderer/core/layout/build.gni
+++ b/third_party/blink/renderer/core/layout/build.gni
@@ -79,7 +79,6 @@
   "hit_test_canvas_result.h",
   "hit_test_location.cc",
   "hit_test_location.h",
-  "hit_test_request.cc",
   "hit_test_request.h",
   "hit_test_result.cc",
   "hit_test_result.h",
@@ -364,14 +363,12 @@
   "ng/inline/ng_inline_item_result.h",
   "ng/inline/ng_inline_item_segment.cc",
   "ng/inline/ng_inline_item_segment.h",
-  "ng/inline/ng_inline_item_span.h",
   "ng/inline/ng_inline_items_builder.cc",
   "ng/inline/ng_inline_items_builder.h",
   "ng/inline/ng_inline_layout_algorithm.cc",
   "ng/inline/ng_inline_layout_algorithm.h",
   "ng/inline/ng_inline_node.cc",
   "ng/inline/ng_inline_node.h",
-  "ng/inline/ng_inline_node_data.cc",
   "ng/inline/ng_inline_node_data.h",
   "ng/inline/ng_line_box_fragment_builder.cc",
   "ng/inline/ng_line_box_fragment_builder.h",
@@ -511,7 +508,6 @@
   "ng/ng_link.h",
   "ng/ng_out_of_flow_layout_part.cc",
   "ng/ng_out_of_flow_layout_part.h",
-  "ng/ng_out_of_flow_positioned_node.cc",
   "ng/ng_out_of_flow_positioned_node.h",
   "ng/ng_outline_type.h",
   "ng/ng_outline_utils.cc",
@@ -522,7 +518,6 @@
   "ng/ng_physical_box_fragment.h",
   "ng/ng_physical_fragment.cc",
   "ng/ng_physical_fragment.h",
-  "ng/ng_positioned_float.cc",
   "ng/ng_positioned_float.h",
   "ng/ng_relative_utils.cc",
   "ng/ng_relative_utils.h",
diff --git a/third_party/blink/renderer/core/layout/collapsed_border_value_test.cc b/third_party/blink/renderer/core/layout/collapsed_border_value_test.cc
index 47ec7389..4b5c15a 100644
--- a/third_party/blink/renderer/core/layout/collapsed_border_value_test.cc
+++ b/third_party/blink/renderer/core/layout/collapsed_border_value_test.cc
@@ -38,7 +38,7 @@
       EBorderStyle border_style,
       const Color& color = Color::kBlack,
       EBorderPrecedence precedence = kBorderPrecedenceCell) {
-    auto* style = ComputedStyle::Clone(*initial_style_);
+    auto style = ComputedStyle::Clone(*initial_style_);
     style->SetBorderLeftWidth(width);
     style->SetBorderLeftStyle(border_style);
     CollapsedBorderValue v(style->BorderLeft(), color, precedence);
@@ -55,7 +55,7 @@
   }
 
  private:
-  Persistent<const ComputedStyle> initial_style_;
+  scoped_refptr<const ComputedStyle> initial_style_;
 };
 
 TEST_F(CollapsedBorderValueTest, Default) {
diff --git a/third_party/blink/renderer/core/layout/counter_node.cc b/third_party/blink/renderer/core/layout/counter_node.cc
index 55344a1f5..c4317c31 100644
--- a/third_party/blink/renderer/core/layout/counter_node.cc
+++ b/third_party/blink/renderer/core/layout/counter_node.cc
@@ -181,7 +181,7 @@
       return;
     }
   }
-  value->next_for_same_counter_ = root_layout_object_.Get();
+  value->next_for_same_counter_ = root_layout_object_;
   root_layout_object_ = value;
   if (value->counter_node_ != this) {
     if (value->counter_node_) {
diff --git a/third_party/blink/renderer/core/layout/counter_node.h b/third_party/blink/renderer/core/layout/counter_node.h
index f2bb9a9..ad48695c 100644
--- a/third_party/blink/renderer/core/layout/counter_node.h
+++ b/third_party/blink/renderer/core/layout/counter_node.h
@@ -23,7 +23,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_COUNTER_NODE_H_
 
 #include "base/dcheck_is_on.h"
-#include "third_party/blink/renderer/platform/heap/handle.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/ref_counted.h"
@@ -118,8 +117,8 @@
   unsigned type_mask_;
   int value_;
   int count_in_parent_;
-  const UntracedMember<LayoutObject> owner_;
-  UntracedMember<LayoutCounter> root_layout_object_;
+  LayoutObject* const owner_;
+  LayoutCounter* root_layout_object_;
 
   CounterNode* parent_;
   CounterNode* previous_sibling_;
diff --git a/third_party/blink/renderer/core/layout/custom_scrollbar.cc b/third_party/blink/renderer/core/layout/custom_scrollbar.cc
index 5388913..1a16d62 100644
--- a/third_party/blink/renderer/core/layout/custom_scrollbar.cc
+++ b/third_party/blink/renderer/core/layout/custom_scrollbar.cc
@@ -67,7 +67,6 @@
 }
 
 void CustomScrollbar::Trace(Visitor* visitor) const {
-  visitor->Trace(parts_);
   Scrollbar::Trace(visitor);
 }
 
@@ -127,9 +126,9 @@
   PositionScrollbarParts();
 }
 
-const ComputedStyle* CustomScrollbar::GetScrollbarPseudoElementStyle(
-    ScrollbarPart part_type,
-    PseudoId pseudo_id) {
+scoped_refptr<const ComputedStyle>
+CustomScrollbar::GetScrollbarPseudoElementStyle(ScrollbarPart part_type,
+                                                PseudoId pseudo_id) {
   Element* element = StyleSource();
   DCHECK(element);
   Document& document = element->GetDocument();
@@ -146,8 +145,9 @@
   if (!element->GetLayoutObject())
     return nullptr;
   const ComputedStyle* source_style = element->GetLayoutObject()->Style();
-  const ComputedStyle* part_style = element->UncachedStyleForPseudoElement(
-      StyleRequest(pseudo_id, this, part_type, source_style));
+  scoped_refptr<const ComputedStyle> part_style =
+      element->UncachedStyleForPseudoElement(
+          StyleRequest(pseudo_id, this, part_type, source_style));
   if (!part_style)
     return nullptr;
   return source_style->AddCachedPseudoElementStyle(std::move(part_style));
@@ -233,8 +233,9 @@
   if (part_type == kNoPart)
     return;
 
-  const ComputedStyle* part_style = GetScrollbarPseudoElementStyle(
-      part_type, PseudoForScrollbarPart(part_type));
+  scoped_refptr<const ComputedStyle> part_style =
+      GetScrollbarPseudoElementStyle(part_type,
+                                     PseudoForScrollbarPart(part_type));
   bool need_layout_object =
       part_style && part_style->Display() != EDisplay::kNone;
 
diff --git a/third_party/blink/renderer/core/layout/custom_scrollbar.h b/third_party/blink/renderer/core/layout/custom_scrollbar.h
index 47830bf0..3bc6d30 100644
--- a/third_party/blink/renderer/core/layout/custom_scrollbar.h
+++ b/third_party/blink/renderer/core/layout/custom_scrollbar.h
@@ -91,10 +91,12 @@
 
   void DestroyScrollbarParts();
   void UpdateScrollbarParts();
-  const ComputedStyle* GetScrollbarPseudoElementStyle(ScrollbarPart, PseudoId);
+  scoped_refptr<const ComputedStyle> GetScrollbarPseudoElementStyle(
+      ScrollbarPart,
+      PseudoId);
   void UpdateScrollbarPart(ScrollbarPart);
 
-  HeapHashMap<ScrollbarPart, Member<LayoutCustomScrollbarPart>> parts_;
+  HashMap<ScrollbarPart, LayoutCustomScrollbarPart*> parts_;
   bool needs_position_scrollbar_parts_ = true;
 };
 
diff --git a/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.cc b/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.cc
index 1c57758..049cc50a 100644
--- a/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.cc
+++ b/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.cc
@@ -12,41 +12,33 @@
 
 namespace blink {
 
-class DepthOrderedLayoutObjectListData
-    : public GarbageCollected<DepthOrderedLayoutObjectListData> {
- public:
-  DepthOrderedLayoutObjectListData() = default;
-  void Trace(Visitor* visitor) const {
-    visitor->Trace(ordered_objects_);
-    visitor->Trace(objects_);
-  }
-
-  HeapVector<LayoutObjectWithDepth>& ordered_objects() {
-    return ordered_objects_;
-  }
-  HeapHashSet<Member<LayoutObject>>& objects() { return objects_; }
+struct DepthOrderedLayoutObjectListData {
+  Vector<LayoutObjectWithDepth>& ordered_objects() { return ordered_objects_; }
+  HashSet<LayoutObject*>& objects() { return objects_; }
 
   // LayoutObjects sorted by depth (deepest first). This structure is only
   // populated at the beginning of enumerations. See ordered().
-  HeapVector<LayoutObjectWithDepth> ordered_objects_;
+  Vector<LayoutObjectWithDepth> ordered_objects_;
 
   // Outside of layout, LayoutObjects can be added and removed as needed such
   // as when style was changed or destroyed. They're kept in this hashset to
   // keep those operations fast.
-  HeapHashSet<Member<LayoutObject>> objects_;
+  HashSet<LayoutObject*> objects_;
 };
 
 DepthOrderedLayoutObjectList::DepthOrderedLayoutObjectList()
-    : data_(MakeGarbageCollected<DepthOrderedLayoutObjectListData>()) {}
+    : data_(new DepthOrderedLayoutObjectListData) {}
 
-DepthOrderedLayoutObjectList::~DepthOrderedLayoutObjectList() = default;
+DepthOrderedLayoutObjectList::~DepthOrderedLayoutObjectList() {
+  delete data_;
+}
 
 int DepthOrderedLayoutObjectList::size() const {
-  return data_->objects().size();
+  return data_->objects_.size();
 }
 
 bool DepthOrderedLayoutObjectList::IsEmpty() const {
-  return data_->objects().IsEmpty();
+  return data_->objects_.IsEmpty();
 }
 
 namespace {
@@ -70,8 +62,8 @@
 }
 
 void DepthOrderedLayoutObjectList::Remove(LayoutObject& object) {
-  auto it = data_->objects().find(&object);
-  if (it == data_->objects().end())
+  auto it = data_->objects_.find(&object);
+  if (it == data_->objects_.end())
     return;
   DCHECK(ListModificationAllowedFor(object));
   data_->objects().erase(it);
@@ -79,12 +71,8 @@
 }
 
 void DepthOrderedLayoutObjectList::Clear() {
-  data_->objects().clear();
-  data_->ordered_objects().clear();
-}
-
-void LayoutObjectWithDepth::Trace(Visitor* visitor) const {
-  visitor->Trace(object);
+  data_->objects_.clear();
+  data_->ordered_objects_.clear();
 }
 
 unsigned LayoutObjectWithDepth::DetermineDepth(LayoutObject* object) {
@@ -95,13 +83,11 @@
   return depth;
 }
 
-const HeapHashSet<Member<LayoutObject>>&
-DepthOrderedLayoutObjectList::Unordered() const {
-  return data_->objects();
+const HashSet<LayoutObject*>& DepthOrderedLayoutObjectList::Unordered() const {
+  return data_->objects_;
 }
 
-const HeapVector<LayoutObjectWithDepth>&
-DepthOrderedLayoutObjectList::Ordered() {
+const Vector<LayoutObjectWithDepth>& DepthOrderedLayoutObjectList::Ordered() {
   if (data_->objects_.IsEmpty() || !data_->ordered_objects_.IsEmpty())
     return data_->ordered_objects_;
 
@@ -110,8 +96,4 @@
   return data_->ordered_objects_;
 }
 
-void DepthOrderedLayoutObjectList::Trace(Visitor* visitor) const {
-  visitor->Trace(data_);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.h b/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.h
index 377eb689..2fe4921a 100644
--- a/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.h
+++ b/third_party/blink/renderer/core/layout/depth_ordered_layout_object_list.h
@@ -5,18 +5,16 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_DEPTH_ORDERED_LAYOUT_OBJECT_LIST_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_DEPTH_ORDERED_LAYOUT_OBJECT_LIST_H_
 
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
-#include "third_party/blink/renderer/platform/wtf/vector_traits.h"
 
 namespace blink {
 
 class LayoutObject;
 
 // Put data inside a forward-declared struct, to avoid including LayoutObject.h.
-class DepthOrderedLayoutObjectListData;
+struct DepthOrderedLayoutObjectListData;
 
 struct LayoutObjectWithDepth {
   DISALLOW_NEW();
@@ -24,10 +22,10 @@
  public:
   explicit LayoutObjectWithDepth(LayoutObject* in_object)
       : object(in_object), depth(DetermineDepth(in_object)) {}
-  LayoutObjectWithDepth() = default;
-  void Trace(Visitor*) const;
 
-  Member<LayoutObject> object = nullptr;
+  LayoutObjectWithDepth() = default;
+
+  LayoutObject* object = nullptr;
   unsigned depth = 0u;
 
   LayoutObject& operator*() const { return *object; }
@@ -52,7 +50,6 @@
  public:
   DepthOrderedLayoutObjectList();
   ~DepthOrderedLayoutObjectList();
-  void Trace(Visitor*) const;
 
   void Add(LayoutObject&);
   void Remove(LayoutObject&);
@@ -61,15 +58,13 @@
   int size() const;
   bool IsEmpty() const;
 
-  const HeapHashSet<Member<LayoutObject>>& Unordered() const;
-  const HeapVector<LayoutObjectWithDepth>& Ordered();
+  const HashSet<LayoutObject*>& Unordered() const;
+  const Vector<LayoutObjectWithDepth>& Ordered();
 
  private:
-  Member<DepthOrderedLayoutObjectListData> data_;
+  DepthOrderedLayoutObjectListData* data_;
 };
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::LayoutObjectWithDepth)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_DEPTH_ORDERED_LAYOUT_OBJECT_LIST_H_
diff --git a/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc b/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc
index 83977c6..2e28feb3 100644
--- a/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc
@@ -30,6 +30,7 @@
 
 #include "third_party/blink/renderer/core/layout/flexible_box_algorithm.h"
 
+#include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/layout/layout_box.h"
 #include "third_party/blink/renderer/core/layout/layout_flexible_box.h"
 #include "third_party/blink/renderer/core/layout/min_max_sizes.h"
@@ -106,7 +107,7 @@
 }
 
 bool FlexItem::MainAxisIsInlineAxis() const {
-  return algorithm_->IsHorizontalFlow() == style_->IsHorizontalWritingMode();
+  return algorithm_->IsHorizontalFlow() == style_.IsHorizontalWritingMode();
 }
 
 LayoutUnit FlexItem::FlowAwareMarginStart() const {
@@ -175,27 +176,27 @@
 
 bool FlexItem::HasAutoMarginsInCrossAxis() const {
   if (algorithm_->IsHorizontalFlow()) {
-    return style_->MarginTop().IsAuto() || style_->MarginBottom().IsAuto();
+    return style_.MarginTop().IsAuto() || style_.MarginBottom().IsAuto();
   }
-  return style_->MarginLeft().IsAuto() || style_->MarginRight().IsAuto();
+  return style_.MarginLeft().IsAuto() || style_.MarginRight().IsAuto();
 }
 
 ItemPosition FlexItem::Alignment() const {
-  return FlexLayoutAlgorithm::AlignmentForChild(*algorithm_->Style(), *style_);
+  return FlexLayoutAlgorithm::AlignmentForChild(*algorithm_->Style(), style_);
 }
 
 void FlexItem::UpdateAutoMarginsInMainAxis(LayoutUnit auto_margin_offset) {
   DCHECK_GE(auto_margin_offset, LayoutUnit());
 
   if (algorithm_->IsHorizontalFlow()) {
-    if (style_->MarginLeft().IsAuto())
+    if (style_.MarginLeft().IsAuto())
       physical_margins_.left = auto_margin_offset;
-    if (style_->MarginRight().IsAuto())
+    if (style_.MarginRight().IsAuto())
       physical_margins_.right = auto_margin_offset;
   } else {
-    if (style_->MarginTop().IsAuto())
+    if (style_.MarginTop().IsAuto())
       physical_margins_.top = auto_margin_offset;
-    if (style_->MarginBottom().IsAuto())
+    if (style_.MarginBottom().IsAuto())
       physical_margins_.bottom = auto_margin_offset;
   }
 }
@@ -206,9 +207,9 @@
 
   bool is_horizontal = algorithm_->IsHorizontalFlow();
   const Length& top_or_left =
-      is_horizontal ? style_->MarginTop() : style_->MarginLeft();
+      is_horizontal ? style_.MarginTop() : style_.MarginLeft();
   const Length& bottom_or_right =
-      is_horizontal ? style_->MarginBottom() : style_->MarginRight();
+      is_horizontal ? style_.MarginBottom() : style_.MarginRight();
   if (top_or_left.IsAuto() && bottom_or_right.IsAuto()) {
     desired_location_.Move(LayoutUnit(), available_alignment_space / 2);
     if (is_horizontal) {
@@ -221,13 +222,13 @@
     return true;
   }
   bool should_adjust_top_or_left = true;
-  if (algorithm_->IsColumnFlow() && !style_->IsLeftToRightDirection()) {
+  if (algorithm_->IsColumnFlow() && !style_.IsLeftToRightDirection()) {
     // For column flows, only make this adjustment if topOrLeft corresponds to
     // the "before" margin, so that flipForRightToLeftColumn will do the right
     // thing.
     should_adjust_top_or_left = false;
   }
-  if (!algorithm_->IsColumnFlow() && style_->IsFlippedBlocksWritingMode()) {
+  if (!algorithm_->IsColumnFlow() && style_.IsFlippedBlocksWritingMode()) {
     // If we are a flipped writing mode, we need to adjust the opposite side.
     // This is only needed for row flows because this only affects the
     // block-direction axis.
@@ -263,10 +264,10 @@
       std::max(cross_axis_border_padding_,
                Line()->cross_axis_extent_ - CrossAxisMarginExtent());
   if (box_) {
-    if (MainAxisIsInlineAxis() && style_->LogicalHeight().IsAuto()) {
+    if (MainAxisIsInlineAxis() && style_.LogicalHeight().IsAuto()) {
       cross_axis_size_ = box_->ConstrainLogicalHeightByMinMax(
           stretched_size, box_->IntrinsicContentLogicalHeight());
-    } else if (!MainAxisIsInlineAxis() && style_->LogicalWidth().IsAuto()) {
+    } else if (!MainAxisIsInlineAxis() && style_.LogicalWidth().IsAuto()) {
       const auto* flexbox = To<LayoutFlexibleBox>(box_->Parent());
       cross_axis_size_ = box_->ConstrainLogicalWidthByMinMax(
           stretched_size, flexbox->CrossAxisContentExtent(), flexbox);
@@ -274,17 +275,11 @@
     return;
   }
 
-  if ((MainAxisIsInlineAxis() && style_->LogicalHeight().IsAuto()) ||
-      (!MainAxisIsInlineAxis() && style_->LogicalWidth().IsAuto()))
+  if ((MainAxisIsInlineAxis() && style_.LogicalHeight().IsAuto()) ||
+      (!MainAxisIsInlineAxis() && style_.LogicalWidth().IsAuto())) {
     cross_axis_size_ =
         min_max_cross_sizes_->ClampSizeToMinAndMax(stretched_size);
-}
-
-void FlexItem::Trace(Visitor* visitor) const {
-  visitor->Trace(box_);
-  visitor->Trace(style_);
-  visitor->Trace(ng_input_node_);
-  visitor->Trace(layout_result_);
+  }
 }
 
 // static
@@ -335,12 +330,11 @@
   }
   return LayoutUnit();
 }
-
 void FlexLine::FreezeViolations(ViolationsVector& violations) {
   const ComputedStyle& flex_box_style = algorithm_->StyleRef();
   for (size_t i = 0; i < violations.size(); ++i) {
     DCHECK(!violations[i]->frozen_) << i;
-    const ComputedStyle& child_style = *violations[i]->style_;
+    const ComputedStyle& child_style = violations[i]->style_;
     LayoutUnit child_size = violations[i]->flexed_content_size_;
     remaining_free_space_ -=
         child_size - violations[i]->flex_base_content_size_;
@@ -373,8 +367,8 @@
     DCHECK(!flex_item.frozen_) << i;
     float flex_factor =
         (flex_sign == kPositiveFlexibility)
-            ? flex_item.style_->ResolvedFlexGrow(flex_box_style)
-            : flex_item.style_->ResolvedFlexShrink(flex_box_style);
+            ? flex_item.style_.ResolvedFlexGrow(flex_box_style)
+            : flex_item.style_.ResolvedFlexShrink(flex_box_style);
     if (flex_factor == 0 ||
         (flex_sign == kPositiveFlexibility &&
          flex_item.flex_base_content_size_ >
@@ -420,14 +414,14 @@
     if (remaining_free_space_ > 0 && total_flex_grow_ > 0 &&
         flex_sign == kPositiveFlexibility && std::isfinite(total_flex_grow_)) {
       extra_space = remaining_free_space_ *
-                    flex_item.style_->ResolvedFlexGrow(flex_box_style) /
+                    flex_item.style_.ResolvedFlexGrow(flex_box_style) /
                     total_flex_grow_;
     } else if (remaining_free_space_ < 0 && total_weighted_flex_shrink_ > 0 &&
                flex_sign == kNegativeFlexibility &&
                std::isfinite(total_weighted_flex_shrink_) &&
-               flex_item.style_->ResolvedFlexShrink(flex_box_style)) {
+               flex_item.style_.ResolvedFlexShrink(flex_box_style)) {
       extra_space = remaining_free_space_ *
-                    flex_item.style_->ResolvedFlexShrink(flex_box_style) *
+                    flex_item.style_.ResolvedFlexShrink(flex_box_style) *
                     flex_item.flex_base_content_size_ /
                     total_weighted_flex_shrink_;
     }
@@ -463,16 +457,16 @@
   int number_of_auto_margins = 0;
   bool is_horizontal = algorithm_->IsHorizontalFlow();
   for (size_t i = 0; i < line_items_.size(); ++i) {
-    const ComputedStyle* style = line_items_[i].style_;
+    const ComputedStyle& style = line_items_[i].style_;
     if (is_horizontal) {
-      if (style->MarginLeft().IsAuto())
+      if (style.MarginLeft().IsAuto())
         ++number_of_auto_margins;
-      if (style->MarginRight().IsAuto())
+      if (style.MarginRight().IsAuto())
         ++number_of_auto_margins;
     } else {
-      if (style->MarginTop().IsAuto())
+      if (style.MarginTop().IsAuto())
         ++number_of_auto_margins;
-      if (style->MarginBottom().IsAuto())
+      if (style.MarginBottom().IsAuto())
         ++number_of_auto_margins;
     }
   }
@@ -681,8 +675,8 @@
     line_has_in_flow_item = true;
     sum_flex_base_size +=
         flex_item.FlexBaseMarginBoxSize() + gap_between_items_;
-    total_flex_grow += flex_item.style_->ResolvedFlexGrow(StyleRef());
-    const float flex_shrink = flex_item.style_->ResolvedFlexShrink(StyleRef());
+    total_flex_grow += flex_item.style_.ResolvedFlexGrow(StyleRef());
+    const float flex_shrink = flex_item.style_.ResolvedFlexShrink(StyleRef());
     total_flex_shrink += flex_shrink;
     total_weighted_flex_shrink +=
         flex_shrink * flex_item.flex_base_content_size_;
@@ -1103,9 +1097,4 @@
   return all_items_.at(0).ng_input_node_.GetLayoutBox();
 }
 
-void FlexLayoutAlgorithm::Trace(Visitor* visitor) const {
-  visitor->Trace(style_);
-  visitor->Trace(all_items_);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/flexible_box_algorithm.h b/third_party/blink/renderer/core/layout/flexible_box_algorithm.h
index 5c72b1f0..c4ec449 100644
--- a/third_party/blink/renderer/core/layout/flexible_box_algorithm.h
+++ b/third_party/blink/renderer/core/layout/flexible_box_algorithm.h
@@ -62,7 +62,7 @@
   kBottomToTopWritingMode
 };
 
-typedef HeapVector<FlexItem, 8> FlexItemVector;
+typedef Vector<FlexItem, 8> FlexItemVector;
 
 class AutoClearOverrideLogicalHeight {
   STACK_ALLOCATED();
@@ -191,12 +191,10 @@
                                     bool is_wrap_reverse,
                                     bool is_deprecated_webkit_box);
 
-  void Trace(Visitor*) const;
-
   const FlexLayoutAlgorithm* algorithm_;
   wtf_size_t line_number_;
-  Member<LayoutBox> box_;
-  Member<const ComputedStyle> style_;
+  LayoutBox* box_;
+  const ComputedStyle& style_;
   const LayoutUnit flex_base_content_size_;
   const MinMaxSizes min_max_main_sizes_;
   const base::Optional<MinMaxSizes> min_max_cross_sizes_;
@@ -222,7 +220,7 @@
   bool needs_relayout_for_stretch_;
 
   NGBlockNode ng_input_node_;
-  Member<const NGLayoutResult> layout_result_;
+  scoped_refptr<const NGLayoutResult> layout_result_;
 };
 
 class FlexItemVectorView {
@@ -449,16 +447,13 @@
                                     LogicalSize percent_resolution_sizes);
   static LayoutUnit GapBetweenLines(const ComputedStyle& style,
                                     LogicalSize percent_resolution_sizes);
-
-  void Trace(Visitor*) const;
-
   const LayoutUnit gap_between_items_;
   const LayoutUnit gap_between_lines_;
 
  private:
   EOverflow MainAxisOverflowForChild(const LayoutBox& child) const;
 
-  Member<const ComputedStyle> style_;
+  const ComputedStyle* style_;
   const LayoutUnit line_break_length_;
   FlexItemVector all_items_;
   Vector<FlexLine> flex_lines_;
@@ -471,6 +466,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::FlexItem)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_FLEXIBLE_BOX_ALGORITHM_H_
diff --git a/third_party/blink/renderer/core/layout/floating_objects.cc b/third_party/blink/renderer/core/layout/floating_objects.cc
index e0e2821..968952b1 100644
--- a/third_party/blink/renderer/core/layout/floating_objects.cc
+++ b/third_party/blink/renderer/core/layout/floating_objects.cc
@@ -40,7 +40,7 @@
 namespace blink {
 
 struct SameSizeAsFloatingObject {
-  Member<void*> members[2];
+  void* pointers[2];
   LayoutRect rect;
   uint32_t bitfields : 8;
 };
@@ -87,14 +87,10 @@
 {
 }
 
-void FloatingObject::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_object_);
-  visitor->Trace(originating_line_);
-}
-
-FloatingObject* FloatingObject::Create(LayoutBox* layout_object, Type type) {
-  FloatingObject* new_obj =
-      MakeGarbageCollected<FloatingObject>(PassKey(), layout_object, type);
+std::unique_ptr<FloatingObject> FloatingObject::Create(LayoutBox* layout_object,
+                                                       Type type) {
+  std::unique_ptr<FloatingObject> new_obj =
+      base::WrapUnique(new FloatingObject(PassKey(), layout_object, type));
 
   // If a layer exists, the float will paint itself. Otherwise someone else
   // will.
@@ -114,19 +110,20 @@
   return new_obj;
 }
 
-FloatingObject* FloatingObject::CopyToNewContainer(LayoutSize offset,
-                                                   bool should_paint,
-                                                   bool is_descendant) const {
-  return MakeGarbageCollected<FloatingObject>(
+std::unique_ptr<FloatingObject> FloatingObject::CopyToNewContainer(
+    LayoutSize offset,
+    bool should_paint,
+    bool is_descendant) const {
+  return base::WrapUnique(new FloatingObject(
       PassKey(), GetLayoutObject(), GetType(),
       LayoutRect(FrameRect().Location() - offset, FrameRect().Size()),
-      should_paint, is_descendant, IsLowestNonOverhangingFloatInChild());
+      should_paint, is_descendant, IsLowestNonOverhangingFloatInChild()));
 }
 
-FloatingObject* FloatingObject::UnsafeClone() const {
-  FloatingObject* clone_object = MakeGarbageCollected<FloatingObject>(
-      PassKey(), GetLayoutObject(), GetType(), frame_rect_, should_paint_,
-      is_descendant_, false);
+std::unique_ptr<FloatingObject> FloatingObject::UnsafeClone() const {
+  std::unique_ptr<FloatingObject> clone_object = base::WrapUnique(
+      new FloatingObject(PassKey(), GetLayoutObject(), GetType(), frame_rect_,
+                         should_paint_, is_descendant_, false));
   clone_object->is_placed_ = is_placed_;
 #if DCHECK_IS_ON()
   clone_object->has_geometry_ = has_geometry_;
@@ -162,7 +159,7 @@
  protected:
   virtual bool UpdateOffsetIfNeeded(const FloatingObject&) = 0;
 
-  const LayoutBlockFlow* layout_object_;
+  const LayoutBlockFlow* layout_object_ = nullptr;
   LayoutUnit line_top_;
   LayoutUnit line_bottom_;
   LayoutUnit offset_;
@@ -231,7 +228,7 @@
   LayoutUnit NextShapeLogicalBottom() { return next_shape_logical_bottom_; }
 
  private:
-  const LayoutBlockFlow* layout_object_;
+  const LayoutBlockFlow* layout_object_ = nullptr;
   LayoutUnit below_logical_height_;
   LayoutUnit above_logical_height_;
   LayoutUnit next_logical_bottom_;
@@ -338,13 +335,6 @@
       layout_object_(layout_object),
       cached_horizontal_writing_mode_(false) {}
 
-void FloatingObjects::Trace(Visitor* visitor) const {
-  visitor->Trace(set_);
-  visitor->Trace(layout_object_);
-  visitor->Trace(lowest_float_bottom_cache_[0]);
-  visitor->Trace(lowest_float_bottom_cache_[1]);
-}
-
 void FloatingObjects::Clear() {
   set_.clear();
   placed_floats_tree_.Clear();
@@ -381,7 +371,7 @@
     LayoutUnit lowest_float_bottom_right;
     for (FloatingObjectSetIterator it = floating_object_set.begin(); it != end;
          ++it) {
-      FloatingObject& floating_object = *it->Get();
+      FloatingObject& floating_object = *it->get();
       if (floating_object.IsPlaced()) {
         FloatingObject::Type cur_type = floating_object.GetType();
         LayoutUnit cur_float_logical_bottom =
@@ -410,7 +400,7 @@
     FloatingObject* lowest_floating_object = nullptr;
     for (FloatingObjectSetIterator it = floating_object_set.begin(); it != end;
          ++it) {
-      FloatingObject& floating_object = *it->Get();
+      FloatingObject& floating_object = *it->get();
       if (floating_object.IsPlaced() &&
           floating_object.GetType() == float_type) {
         if (layout_object_->LogicalBottomForFloat(floating_object) >
@@ -501,8 +491,7 @@
 
 void FloatingObjects::MoveAllToFloatInfoMap(LayoutBoxToFloatInfoMap& map) {
   while (!set_.IsEmpty()) {
-    FloatingObject* floating_object = set_.front();
-    set_.RemoveFirst();
+    std::unique_ptr<FloatingObject> floating_object = set_.TakeFirst();
     LayoutBox* layout_object = floating_object->GetLayoutObject();
     map.insert(layout_object, std::move(floating_object));
   }
@@ -566,22 +555,20 @@
   MarkLowestFloatLogicalBottomCacheAsDirty();
 }
 
-FloatingObject* FloatingObjects::Add(FloatingObject* floating_object) {
-  IncreaseObjectsCount(floating_object->GetType());
-  set_.insert(floating_object);
-  if (floating_object->IsPlaced())
-    AddPlacedObject(*floating_object);
+FloatingObject* FloatingObjects::Add(
+    std::unique_ptr<FloatingObject> floating_object) {
+  FloatingObject* new_object = floating_object.release();
+  IncreaseObjectsCount(new_object->GetType());
+  set_.insert(base::WrapUnique(new_object));
+  if (new_object->IsPlaced())
+    AddPlacedObject(*new_object);
   MarkLowestFloatLogicalBottomCacheAsDirty();
-  return floating_object;
+  return new_object;
 }
 
 void FloatingObjects::Remove(FloatingObject* to_be_removed) {
   DecreaseObjectsCount(to_be_removed->GetType());
-  auto it = set_.find(to_be_removed);
-  FloatingObject* floating_object = *it;
-  if (it != set_.end()) {
-    set_.erase(it);
-  }
+  std::unique_ptr<FloatingObject> floating_object = set_.Take(to_be_removed);
   DCHECK(floating_object->IsPlaced() || !floating_object->IsInPlacedTree());
   if (floating_object->IsPlaced())
     RemovePlacedObject(*floating_object);
@@ -597,7 +584,7 @@
   FloatingObjectSetIterator it = set_.begin();
   FloatingObjectSetIterator end = set_.end();
   for (; it != end; ++it) {
-    FloatingObject& floating_object = *it->Get();
+    FloatingObject& floating_object = *it->get();
     if (floating_object.IsPlaced())
       placed_floats_tree_.Add(IntervalForFloatingObject(floating_object));
   }
@@ -673,7 +660,8 @@
   return std::min(fixed_offset, adapter.Offset());
 }
 
-FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue() = default;
+FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue()
+    : floating_object(nullptr), dirty(true) {}
 
 template <>
 inline bool ComputeFloatOffsetForFloatLayoutAdapter<
@@ -688,10 +676,6 @@
   return false;
 }
 
-void FloatingObjects::FloatBottomCachedValue::Trace(Visitor* visitor) const {
-  visitor->Trace(floating_object);
-}
-
 template <>
 inline bool ComputeFloatOffsetForFloatLayoutAdapter<
     FloatingObject::kFloatRight>::UpdateOffsetIfNeeded(const FloatingObject&
diff --git a/third_party/blink/renderer/core/layout/floating_objects.h b/third_party/blink/renderer/core/layout/floating_objects.h
index f3e320b..25a96654 100644
--- a/third_party/blink/renderer/core/layout/floating_objects.h
+++ b/third_party/blink/renderer/core/layout/floating_objects.h
@@ -28,7 +28,6 @@
 #include "base/dcheck_is_on.h"
 #include "base/types/pass_key.h"
 #include "third_party/blink/renderer/platform/geometry/layout_rect.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/blink/renderer/platform/wtf/list_hash_set.h"
 #include "third_party/blink/renderer/platform/wtf/pod_free_list_arena.h"
@@ -40,7 +39,9 @@
 class LayoutBox;
 class RootInlineBox;
 
-class FloatingObject : public GarbageCollected<FloatingObject> {
+class FloatingObject {
+  USING_FAST_MALLOC(FloatingObject);
+
  public:
 #ifndef NDEBUG
   // Used by the PODIntervalTree for debugging the FloatingObject.
@@ -52,13 +53,14 @@
   // for both left and right.
   enum Type { kFloatLeft = 1, kFloatRight = 2, kFloatLeftRight = 3 };
 
-  static FloatingObject* Create(LayoutBox*, Type);
+  static std::unique_ptr<FloatingObject> Create(LayoutBox*, Type);
 
-  FloatingObject* CopyToNewContainer(LayoutSize,
-                                     bool should_paint = false,
-                                     bool is_descendant = false) const;
+  std::unique_ptr<FloatingObject> CopyToNewContainer(
+      LayoutSize,
+      bool should_paint = false,
+      bool is_descendant = false) const;
 
-  FloatingObject* UnsafeClone() const;
+  std::unique_ptr<FloatingObject> UnsafeClone() const;
 
   Type GetType() const { return static_cast<Type>(type_); }
   LayoutBox* GetLayoutObject() const { return layout_object_; }
@@ -155,11 +157,10 @@
                  bool is_lowest_non_overhanging_float_in_child);
   FloatingObject(const FloatingObject&) = delete;
   FloatingObject& operator=(const FloatingObject&) = delete;
-  void Trace(Visitor*) const;
 
  private:
-  Member<LayoutBox> layout_object_;
-  Member<RootInlineBox> originating_line_;
+  LayoutBox* layout_object_;
+  RootInlineBox* originating_line_;
   LayoutRect frame_rect_;
 
   unsigned type_ : 2;  // Type (left or right aligned)
@@ -182,15 +183,15 @@
   static unsigned GetHash(FloatingObject* key) {
     return DefaultHash<LayoutBox*>::Hash::GetHash(key->GetLayoutObject());
   }
-  static unsigned GetHash(const Member<FloatingObject>& key) {
-    return GetHash(key.Get());
+  static unsigned GetHash(const std::unique_ptr<FloatingObject>& key) {
+    return GetHash(key.get());
   }
-  static bool Equal(const Member<FloatingObject>& a, FloatingObject* b) {
+  static bool Equal(std::unique_ptr<FloatingObject>& a, FloatingObject* b) {
     return a->GetLayoutObject() == b->GetLayoutObject();
   }
-  static bool Equal(const Member<FloatingObject>& a,
-                    const Member<FloatingObject>& b) {
-    return Equal(a, b.Get());
+  static bool Equal(std::unique_ptr<FloatingObject>& a,
+                    const std::unique_ptr<FloatingObject>& b) {
+    return Equal(a, b.get());
   }
 
   static const bool safe_to_compare_to_empty_or_deleted = true;
@@ -203,13 +204,13 @@
   static bool Equal(FloatingObject* a, LayoutBox* b) {
     return a->GetLayoutObject() == b;
   }
-  static bool Equal(const Member<FloatingObject>& a, LayoutBox* b) {
+  static bool Equal(const std::unique_ptr<FloatingObject>& a, LayoutBox* b) {
     return a->GetLayoutObject() == b;
   }
 };
-
-// TODO(yukiy): Use HeapLinkedHashSet here once it supports HashTranslator
-typedef HeapListHashSet<Member<FloatingObject>, 4, FloatingObjectHashFunctions>
+typedef ListHashSet<std::unique_ptr<FloatingObject>,
+                    4,
+                    FloatingObjectHashFunctions>
     FloatingObjectSet;
 typedef FloatingObjectSet::const_iterator FloatingObjectSetIterator;
 typedef WTF::PODInterval<LayoutUnit, FloatingObject*> FloatingObjectInterval;
@@ -217,20 +218,21 @@
 typedef WTF::PODFreeListArena<
     WTF::PODRedBlackTree<FloatingObjectInterval>::Node>
     IntervalArena;
-typedef HeapHashMap<Member<LayoutBox>, Member<FloatingObject>>
+typedef HashMap<LayoutBox*, std::unique_ptr<FloatingObject>>
     LayoutBoxToFloatInfoMap;
 
-class FloatingObjects final : public GarbageCollected<FloatingObjects> {
+class FloatingObjects {
+  USING_FAST_MALLOC(FloatingObjects);
+
  public:
   FloatingObjects(const LayoutBlockFlow*, bool horizontal_writing_mode);
   FloatingObjects(const FloatingObjects&) = delete;
   FloatingObjects& operator=(const FloatingObjects&) = delete;
   ~FloatingObjects();
-  void Trace(Visitor*) const;
 
   void Clear();
   void MoveAllToFloatInfoMap(LayoutBoxToFloatInfoMap&);
-  FloatingObject* Add(FloatingObject*);
+  FloatingObject* Add(std::unique_ptr<FloatingObject>);
   void Remove(FloatingObject*);
   void AddPlacedObject(FloatingObject&);
   void RemovePlacedObject(FloatingObject&);
@@ -295,13 +297,11 @@
   unsigned left_objects_count_;
   unsigned right_objects_count_;
   bool horizontal_writing_mode_;
-  Member<const LayoutBlockFlow> layout_object_;
+  const LayoutBlockFlow* layout_object_;
 
   struct FloatBottomCachedValue {
-    DISALLOW_NEW();
     FloatBottomCachedValue();
-    void Trace(Visitor*) const;
-    Member<FloatingObject> floating_object;
+    FloatingObject* floating_object = nullptr;
     bool dirty = true;
   };
   FloatBottomCachedValue lowest_float_bottom_cache_[2];
diff --git a/third_party/blink/renderer/core/layout/grid.h b/third_party/blink/renderer/core/layout/grid.h
index 44b18e2..d902a63a 100644
--- a/third_party/blink/renderer/core/layout/grid.h
+++ b/third_party/blink/renderer/core/layout/grid.h
@@ -28,7 +28,7 @@
 };
 
 // TODO(svillar): Perhaps we should use references here.
-typedef Vector<UntracedMember<LayoutBox>, 1> GridItemList;
+typedef Vector<LayoutBox*, 1> GridItemList;
 typedef LinkedHashSet<size_t, OrderedTrackIndexSetHashTraits>
     OrderedTrackIndexSet;
 
@@ -142,8 +142,8 @@
 
   bool needs_items_placement_{true};
 
-  HashMap<UntracedMember<const LayoutBox>, GridArea> grid_item_area_;
-  HashMap<UntracedMember<const LayoutBox>, size_t> grid_items_indexes_map_;
+  HashMap<const LayoutBox*, GridArea> grid_item_area_;
+  HashMap<const LayoutBox*, size_t> grid_items_indexes_map_;
 
   std::unique_ptr<OrderedTrackIndexSet> auto_repeat_empty_columns_{nullptr};
   std::unique_ptr<OrderedTrackIndexSet> auto_repeat_empty_rows_{nullptr};
diff --git a/third_party/blink/renderer/core/layout/grid_baseline_alignment.h b/third_party/blink/renderer/core/layout/grid_baseline_alignment.h
index d59db7e..c95b5174 100644
--- a/third_party/blink/renderer/core/layout/grid_baseline_alignment.h
+++ b/third_party/blink/renderer/core/layout/grid_baseline_alignment.h
@@ -62,7 +62,7 @@
   ItemPosition preference_;
   LayoutUnit max_ascent_;
   LayoutUnit max_descent_;
-  HashSet<UntracedMember<const LayoutBox>> items_;
+  HashSet<const LayoutBox*> items_;
 };
 
 // Boxes share an alignment context along a particular axis when they
diff --git a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
index 6fe99bf..0c5eb2e 100644
--- a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
@@ -96,7 +96,7 @@
                                            Vector<size_t>& track_indices,
                                            F callback) {
 #if DCHECK_IS_ON()
-  HeapHashSet<Member<LayoutBox>> items_set;
+  HashSet<LayoutBox*> items_set;
 #endif
   for (size_t i = 0; i < track_indices.size(); ++i) {
     auto iterator = grid.CreateIterator(direction, track_indices[i]);
@@ -1147,7 +1147,7 @@
   }
 
  private:
-  UntracedMember<LayoutBox> grid_item_;
+  LayoutBox* grid_item_;
   GridSpan grid_span_;
 };
 
@@ -1759,7 +1759,7 @@
   BaselineItemsCache& baseline_items_cache = axis == kGridColumnAxis
                                                  ? column_baseline_items_map_
                                                  : row_baseline_items_map_;
-  for (auto& child : baseline_items_cache.Keys()) {
+  for (auto* child : baseline_items_cache.Keys()) {
     // TODO (jfernandez): We may have to get rid of the baseline participation
     // flag (hence just using a HashSet) depending on the CSS WG resolution on
     // https://github.com/w3c/csswg-drafts/issues/3046
diff --git a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h
index 6ea0572..512e3975 100644
--- a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h
+++ b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h
@@ -235,7 +235,7 @@
 
   Grid& grid_;
 
-  UntracedMember<const LayoutGrid> layout_grid_;
+  const LayoutGrid* layout_grid_;
   std::unique_ptr<GridTrackSizingAlgorithmStrategy> strategy_;
 
   // The track sizing algorithm is used for both layout and intrinsic size
@@ -255,7 +255,7 @@
   SizingState sizing_state_;
 
   GridBaselineAlignment baseline_alignment_;
-  using BaselineItemsCache = HashMap<UntracedMember<const LayoutBox>, bool>;
+  using BaselineItemsCache = HashMap<const LayoutBox*, bool>;
   BaselineItemsCache column_baseline_items_map_;
   BaselineItemsCache row_baseline_items_map_;
 
diff --git a/third_party/blink/renderer/core/layout/hit_test_request.cc b/third_party/blink/renderer/core/layout/hit_test_request.cc
deleted file mode 100644
index b7115ba1..0000000
--- a/third_party/blink/renderer/core/layout/hit_test_request.cc
+++ /dev/null
@@ -1,14 +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/core/layout/hit_test_request.h"
-#include "third_party/blink/renderer/core/layout/layout_object.h"
-
-namespace blink {
-
-void HitTestRequest::Trace(Visitor* visitor) const {
-  visitor->Trace(stop_node_);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/hit_test_request.h b/third_party/blink/renderer/core/layout/hit_test_request.h
index 7759233..315a8c11 100644
--- a/third_party/blink/renderer/core/layout/hit_test_request.h
+++ b/third_party/blink/renderer/core/layout/hit_test_request.h
@@ -23,7 +23,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_HIT_TEST_REQUEST_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_HIT_TEST_REQUEST_H_
 
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 namespace blink {
@@ -105,12 +104,10 @@
            stop_node_ == value.stop_node_;
   }
 
-  void Trace(Visitor*) const;
-
  private:
   HitTestRequestType request_type_;
   // If non-null, do not hit test the children of this object.
-  Member<const LayoutObject> stop_node_;
+  const LayoutObject* stop_node_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/hit_test_result.cc b/third_party/blink/renderer/core/layout/hit_test_result.cc
index 0bb6cf2..1a8f35d 100644
--- a/third_party/blink/renderer/core/layout/hit_test_result.cc
+++ b/third_party/blink/renderer/core/layout/hit_test_result.cc
@@ -133,7 +133,6 @@
 }
 
 void HitTestResult::Trace(Visitor* visitor) const {
-  visitor->Trace(hit_test_request_);
   visitor->Trace(inner_node_);
   visitor->Trace(inert_node_);
   visitor->Trace(inner_element_);
@@ -145,7 +144,7 @@
 
 void HitTestResult::SetNodeAndPosition(
     Node* node,
-    const NGPhysicalBoxFragment* box_fragment,
+    scoped_refptr<const NGPhysicalBoxFragment> box_fragment,
     const PhysicalOffset& position) {
   if (box_fragment) {
     local_point_ = position + box_fragment->OffsetFromOwnerLayoutBox();
diff --git a/third_party/blink/renderer/core/layout/hit_test_result.h b/third_party/blink/renderer/core/layout/hit_test_result.h
index 6efd8fc6..4a61ec2 100644
--- a/third_party/blink/renderer/core/layout/hit_test_result.h
+++ b/third_party/blink/renderer/core/layout/hit_test_result.h
@@ -121,7 +121,7 @@
     SetInnerNode(node);
   }
   void SetNodeAndPosition(Node*,
-                          const NGPhysicalBoxFragment*,
+                          scoped_refptr<const NGPhysicalBoxFragment>,
                           const PhysicalOffset&);
 
   // Override an inner node previously set. The new node needs to be monolithic
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc
index f4807d0..d825332 100644
--- a/third_party/blink/renderer/core/layout/layout_block.cc
+++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -97,24 +97,21 @@
 // the middle of recomputing the style so we can't rely on any of its
 // information), which is why it's easier to just update it for every layout.
 TrackedDescendantsMap& GetPositionedDescendantsMap() {
-  DEFINE_STATIC_LOCAL(Persistent<TrackedDescendantsMap>, map,
-                      (MakeGarbageCollected<TrackedDescendantsMap>()));
-  return *map;
+  DEFINE_STATIC_LOCAL(TrackedDescendantsMap, map, ());
+  return map;
 }
 
 TrackedContainerMap& GetPositionedContainerMap() {
-  DEFINE_STATIC_LOCAL(Persistent<TrackedContainerMap>, map,
-                      (MakeGarbageCollected<TrackedContainerMap>()));
-  return *map;
+  DEFINE_STATIC_LOCAL(TrackedContainerMap, map, ());
+  return map;
 }
 
 // This map keeps track of the descendants whose 'height' is percentage
 // associated with a containing block. Like |gPositionedDescendantsMap|, it is
 // also recomputed for every layout (see the comment above about why).
 static TrackedDescendantsMap& GetPercentHeightDescendantsMap() {
-  DEFINE_STATIC_LOCAL(Persistent<TrackedDescendantsMap>, map,
-                      (MakeGarbageCollected<TrackedDescendantsMap>()));
-  return *map;
+  DEFINE_STATIC_LOCAL(TrackedDescendantsMap, map, ());
+  return map;
 }
 
 LayoutBlock::LayoutBlock(ContainerNode* node)
@@ -137,15 +134,10 @@
   // By default, subclasses do not have inline children.
 }
 
-void LayoutBlock::Trace(Visitor* visitor) const {
-  visitor->Trace(children_);
-  LayoutBox::Trace(visitor);
-}
-
 void LayoutBlock::RemoveFromGlobalMaps() {
   NOT_DESTROYED();
   if (HasPositionedObjects()) {
-    TrackedLayoutBoxListHashSet* descendants =
+    std::unique_ptr<TrackedLayoutBoxListHashSet> descendants =
         GetPositionedDescendantsMap().Take(this);
     DCHECK(!descendants->IsEmpty());
     for (LayoutBox* descendant : *descendants) {
@@ -154,7 +146,7 @@
     }
   }
   if (HasPercentHeightDescendants()) {
-    TrackedLayoutBoxListHashSet* descendants =
+    std::unique_ptr<TrackedLayoutBoxListHashSet> descendants =
         GetPercentHeightDescendantsMap().Take(this);
     DCHECK(!descendants->IsEmpty());
     for (LayoutBox* descendant : *descendants) {
@@ -164,6 +156,10 @@
   }
 }
 
+LayoutBlock::~LayoutBlock() {
+  RemoveFromGlobalMaps();
+}
+
 void LayoutBlock::WillBeDestroyed() {
   NOT_DESTROYED();
   if (!DocumentBeingDestroyed() && Parent())
@@ -177,8 +173,6 @@
   if (TextAutosizer* text_autosizer = GetDocument().GetTextAutosizer())
     text_autosizer->Destroy(this);
 
-  RemoveFromGlobalMaps();
-
   LayoutBox::WillBeDestroyed();
 }
 
@@ -632,7 +626,7 @@
   if (!positioned_descendants)
     return;
 
-  for (const auto& positioned_object : *positioned_descendants) {
+  for (auto* positioned_object : *positioned_descendants) {
     // Fixed positioned elements whose containing block is the LayoutView
     // don't contribute to layout overflow, since they don't scroll with the
     // content.
@@ -882,7 +876,7 @@
   if (!positioned_descendants)
     return;
 
-  for (const auto& positioned_object : *positioned_descendants) {
+  for (auto* positioned_object : *positioned_descendants) {
     LayoutPositionedObject(positioned_object, relayout_children, info);
   }
 }
@@ -1002,7 +996,7 @@
   NOT_DESTROYED();
   if (TrackedLayoutBoxListHashSet* positioned_descendants =
           PositionedObjects()) {
-    for (const auto& descendant : *positioned_descendants)
+    for (auto* descendant : *positioned_descendants)
       descendant->SetChildNeedsLayout();
   }
 }
@@ -1051,8 +1045,8 @@
   TrackedLayoutBoxListHashSet* descendant_set =
       GetPositionedDescendantsMap().at(this);
   if (!descendant_set) {
-    descendant_set = MakeGarbageCollected<TrackedLayoutBoxListHashSet>();
-    GetPositionedDescendantsMap().Set(this, descendant_set);
+    descendant_set = new TrackedLayoutBoxListHashSet;
+    GetPositionedDescendantsMap().Set(this, base::WrapUnique(descendant_set));
   }
   descendant_set->insert(o);
 
@@ -1117,8 +1111,8 @@
   if (!positioned_descendants)
     return;
 
-  HeapVector<Member<LayoutBox>, 16> dead_objects;
-  for (const auto& positioned_object : *positioned_descendants) {
+  Vector<LayoutBox*, 16> dead_objects;
+  for (auto* positioned_object : *positioned_descendants) {
     if (!o ||
         (positioned_object->IsDescendantOf(o) && o != positioned_object)) {
       if (containing_block_state == kNewContainingBlock) {
@@ -1155,7 +1149,7 @@
       containing_block->SetChildNeedsLayout(kMarkContainerChain);
   }
 
-  for (const auto& object : dead_objects) {
+  for (auto* object : dead_objects) {
     DCHECK_EQ(GetPositionedContainerMap().at(object), this);
     positioned_descendants->erase(object);
     GetPositionedContainerMap().erase(object);
@@ -1199,8 +1193,9 @@
   TrackedLayoutBoxListHashSet* descendant_set =
       GetPercentHeightDescendantsMap().at(this);
   if (!descendant_set) {
-    descendant_set = MakeGarbageCollected<TrackedLayoutBoxListHashSet>();
-    GetPercentHeightDescendantsMap().Set(this, descendant_set);
+    descendant_set = new TrackedLayoutBoxListHashSet;
+    GetPercentHeightDescendantsMap().Set(this,
+                                         base::WrapUnique(descendant_set));
   }
   descendant_set->insert(descendant);
 
@@ -1232,8 +1227,7 @@
   if (!descendants)
     return;
 
-  for (const auto& it : *descendants) {
-    LayoutBox* box = it;
+  for (auto* box : *descendants) {
     DCHECK(box->IsDescendantOf(this));
     while (box != this) {
       if (box->NormalChildNeedsLayout())
@@ -1674,7 +1668,7 @@
       child->SetIntrinsicLogicalWidthsDirty();
     }
 
-    const ComputedStyle* child_style = child->Style();
+    scoped_refptr<const ComputedStyle> child_style = child->Style();
     if (child->IsFloating() ||
         (child->IsBox() &&
          To<LayoutBox>(child)->CreatesNewFormattingContext())) {
@@ -2131,7 +2125,7 @@
     AddOutlineRectsForNormalChildren(rects, additional_offset,
                                      include_block_overflows);
     if (TrackedLayoutBoxListHashSet* positioned_objects = PositionedObjects()) {
-      for (const auto& box : *positioned_objects)
+      for (auto* box : *positioned_objects)
         AddOutlineRectsForDescendant(*box, rects, additional_offset,
                                      include_block_overflows);
     }
@@ -2266,7 +2260,7 @@
       new_display = EDisplay::kBlock;
       break;
   }
-  ComputedStyle* new_style =
+  scoped_refptr<ComputedStyle> new_style =
       parent->GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
           parent->StyleRef(), new_display);
 
@@ -2360,7 +2354,7 @@
   if (!positioned_descendants)
     return result;
 
-  for (auto& box : *positioned_descendants)
+  for (auto* box : *positioned_descendants)
     result.Unite(box->RecalcLayoutOverflow());
 
   return result;
diff --git a/third_party/blink/renderer/core/layout/layout_block.h b/third_party/blink/renderer/core/layout/layout_block.h
index db299f2a..8cf3e7c 100644
--- a/third_party/blink/renderer/core/layout/layout_block.h
+++ b/third_party/blink/renderer/core/layout/layout_block.h
@@ -37,12 +37,11 @@
 class NGBlockNode;
 class WordMeasurement;
 
-typedef HeapListHashSet<Member<LayoutBox>, 16> TrackedLayoutBoxListHashSet;
-typedef HeapHashMap<WeakMember<const LayoutBlock>,
-                    Member<TrackedLayoutBoxListHashSet>>
+typedef WTF::ListHashSet<LayoutBox*, 16> TrackedLayoutBoxListHashSet;
+typedef WTF::HashMap<const LayoutBlock*,
+                     std::unique_ptr<TrackedLayoutBoxListHashSet>>
     TrackedDescendantsMap;
-typedef HeapHashMap<WeakMember<const LayoutBox>, Member<LayoutBlock>>
-    TrackedContainerMap;
+typedef WTF::HashMap<const LayoutBox*, LayoutBlock*> TrackedContainerMap;
 typedef Vector<WordMeasurement, 64> WordMeasurements;
 
 enum ContainingBlockState { kNewContainingBlock, kSameContainingBlock };
@@ -107,10 +106,9 @@
 class CORE_EXPORT LayoutBlock : public LayoutBox {
  protected:
   explicit LayoutBlock(ContainerNode*);
+  ~LayoutBlock() override;
 
  public:
-  void Trace(Visitor*) const override;
-
   LayoutObject* FirstChild() const {
     NOT_DESTROYED();
     DCHECK_EQ(Children(), VirtualChildren());
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc
index 09ebc4ed..d015481 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow.cc
+++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -77,7 +77,8 @@
 
 struct SameSizeAsLayoutBlockFlow : public LayoutBlock {
   LineBoxList line_boxes;
-  Member<void*> members[2];
+  void* pointers[1];
+  Persistent<void*> persistent[1];
 };
 
 ASSERT_SIZE(LayoutBlockFlow, SameSizeAsLayoutBlockFlow);
@@ -269,16 +270,10 @@
 LayoutBlockFlow::~LayoutBlockFlow() = default;
 #endif
 
-void LayoutBlockFlow::Trace(Visitor* visitor) const {
-  visitor->Trace(line_boxes_);
-  visitor->Trace(rare_data_);
-  visitor->Trace(floating_objects_);
-  LayoutBlock::Trace(visitor);
-}
-
-LayoutBlockFlow* LayoutBlockFlow::CreateAnonymous(Document* document,
-                                                  ComputedStyle* style,
-                                                  LegacyLayout legacy) {
+LayoutBlockFlow* LayoutBlockFlow::CreateAnonymous(
+    Document* document,
+    scoped_refptr<ComputedStyle> style,
+    LegacyLayout legacy) {
   LayoutBlockFlow* layout_block_flow =
       LayoutObjectFactory::CreateBlockFlow(*document, *style, legacy);
   layout_block_flow->SetDocumentForAnonymous(document);
@@ -1396,13 +1391,13 @@
   if (floating_objects_)
     floating_objects_->SetHorizontalWritingMode(IsHorizontalWritingMode());
 
-  HeapHashSet<Member<LayoutBox>> old_intruding_float_set;
+  HashSet<LayoutBox*> old_intruding_float_set;
   if (!ChildrenInline() && floating_objects_) {
     const FloatingObjectSet& floating_object_set = floating_objects_->Set();
     FloatingObjectSetIterator end = floating_object_set.end();
     for (FloatingObjectSetIterator it = floating_object_set.begin(); it != end;
          ++it) {
-      const FloatingObject& floating_object = *it->Get();
+      const FloatingObject& floating_object = *it->get();
       if (!floating_object.IsDescendant())
         old_intruding_float_set.insert(floating_object.GetLayoutObject());
     }
@@ -1486,7 +1481,7 @@
       FloatingObjectSetIterator end = floating_object_set.end();
       for (FloatingObjectSetIterator it = floating_object_set.begin();
            it != end; ++it) {
-        const FloatingObject& floating_object = *it->Get();
+        const FloatingObject& floating_object = *it->get();
         FloatingObject* old_floating_object =
             float_map.at(floating_object.GetLayoutObject());
         LayoutUnit logical_bottom = LogicalBottomForFloat(floating_object);
@@ -1541,7 +1536,7 @@
     LayoutBoxToFloatInfoMap::iterator end = float_map.end();
     for (LayoutBoxToFloatInfoMap::iterator it = float_map.begin(); it != end;
          ++it) {
-      Member<FloatingObject>& floating_object = it->value;
+      std::unique_ptr<FloatingObject>& floating_object = it->value;
       if (!floating_object->IsDescendant()) {
         change_logical_top = LayoutUnit();
         change_logical_bottom = std::max(
@@ -2782,7 +2777,7 @@
 void LayoutBlockFlow::CreateFloatingObjects() {
   NOT_DESTROYED();
   floating_objects_ =
-      MakeGarbageCollected<FloatingObjects>(this, IsHorizontalWritingMode());
+      std::make_unique<FloatingObjects>(this, IsHorizontalWritingMode());
 }
 
 void LayoutBlockFlow::WillBeDestroyed() {
@@ -3173,7 +3168,7 @@
 
     for (FloatingObjectSetIterator it = from_floating_object_set.begin();
          it != end; ++it) {
-      const FloatingObject& floating_object = *it->Get();
+      const FloatingObject& floating_object = *it->get();
 
       // Don't insert the object again if it's already in the list
       if (to_block_flow->ContainsFloat(floating_object.GetLayoutObject()))
@@ -3327,7 +3322,7 @@
   if (!AllowsInlineChildren(*this))
     return;
 
-  HeapVector<Member<LayoutBlockFlow>, 3> blocks_to_remove;
+  Vector<LayoutBlockFlow*, 3> blocks_to_remove;
   for (LayoutObject* child = FirstChild(); child;
        child = child->NextSibling()) {
     if (child->IsFloating())
@@ -3635,7 +3630,7 @@
     FloatingObjectSetIterator it =
         floating_object_set.Find<FloatingObjectHashTranslator>(&float_box);
     if (it != floating_object_set.end())
-      return it->Get();
+      return it->get();
   }
 
   // Create the special object entry & append it to the list
@@ -3643,7 +3638,8 @@
   DCHECK(f == EFloat::kLeft || f == EFloat::kRight);
   FloatingObject::Type type = f == EFloat::kLeft ? FloatingObject::kFloatLeft
                                                  : FloatingObject::kFloatRight;
-  FloatingObject* new_obj = FloatingObject::Create(&float_box, type);
+  std::unique_ptr<FloatingObject> new_obj =
+      FloatingObject::Create(&float_box, type);
   return floating_objects_->Add(std::move(new_obj));
 }
 
@@ -3654,7 +3650,7 @@
     FloatingObjectSetIterator it =
         floating_object_set.Find<FloatingObjectHashTranslator>(float_box);
     if (it != floating_object_set.end()) {
-      FloatingObject& floating_object = *it->Get();
+      FloatingObject& floating_object = *it->get();
       if (ChildrenInline()) {
         LayoutUnit logical_top = LogicalTopForFloat(floating_object);
         LayoutUnit logical_bottom = LogicalBottomForFloat(floating_object);
@@ -3694,13 +3690,13 @@
     return;
 
   const FloatingObjectSet& floating_object_set = floating_objects_->Set();
-  FloatingObject* curr = floating_object_set.back().Get();
+  FloatingObject* curr = floating_object_set.back().get();
   while (curr != last_float &&
          (!curr->IsPlaced() || LogicalTopForFloat(*curr) >= logical_offset)) {
     floating_objects_->Remove(curr);
     if (floating_object_set.IsEmpty())
       break;
-    curr = floating_object_set.back().Get();
+    curr = floating_object_set.back().get();
   }
 }
 
@@ -3715,7 +3711,7 @@
   while (it != begin) {
     --it;
     if ((*it)->IsPlaced()) {
-      last_placed_floating_object = it->Get();
+      last_placed_floating_object = it->get();
       ++it;
       break;
     }
@@ -3743,6 +3739,7 @@
   // has already been positioned. Then we'll be able to move forward,
   // positioning all of the new floats that need it.
   FloatingObjectSetIterator it = floating_object_set.begin();
+  ;
   FloatingObject* last_placed_floating_object = LastPlacedFloat(&it);
 
   // The float cannot start above the top position of the last positioned float.
@@ -3755,7 +3752,7 @@
   FloatingObjectSetIterator end = floating_object_set.end();
   // Now walk through the set of unpositioned floats and place them.
   for (; it != end; ++it) {
-    FloatingObject& floating_object = *it->Get();
+    FloatingObject& floating_object = *it->get();
     // The containing block is responsible for positioning floats, so if we have
     // unplaced floats in our list that come from somewhere else, we have a bug.
     DCHECK_EQ(floating_object.GetLayoutObject()->ContainingBlock(), this);
@@ -3939,7 +3936,7 @@
   FloatingObjectSetIterator prev_end = prev_set.end();
   for (FloatingObjectSetIterator prev_it = prev_set.begin();
        prev_it != prev_end; ++prev_it) {
-    FloatingObject& floating_object = *prev_it->Get();
+    FloatingObject& floating_object = *prev_it->get();
     if (LogicalBottomForFloat(floating_object) > logical_top_offset) {
       if (!floating_objects_ ||
           !floating_objects_->Set().Contains(&floating_object)) {
@@ -3987,7 +3984,7 @@
   for (FloatingObjectSetIterator child_it =
            child->floating_objects_->Set().begin();
        child_it != child_end; ++child_it) {
-    FloatingObject& floating_object = *child_it->Get();
+    FloatingObject& floating_object = *child_it->get();
     LayoutUnit logical_bottom_for_float =
         std::min(LogicalBottomForFloat(floating_object),
                  LayoutUnit::Max() - child_logical_top);
@@ -4144,7 +4141,7 @@
   FloatingObjectSetIterator begin = floating_object_set.begin();
   for (FloatingObjectSetIterator it = floating_object_set.end(); it != begin;) {
     --it;
-    const FloatingObject& floating_object = *it->Get();
+    const FloatingObject& floating_object = *it->get();
     if (floating_object.ShouldPaint() &&
         // TODO(wangxianzhu): Should this be a DCHECK?
         !floating_object.GetLayoutObject()->HasSelfPaintingLayer()) {
@@ -4250,7 +4247,7 @@
 
     auto* ancestor_block = To<LayoutBlockFlow>(ancestor);
     FloatingObjects* ancestor_floating_objects =
-        ancestor_block->floating_objects_;
+        ancestor_block->floating_objects_.get();
     if (!ancestor_floating_objects)
       break;
     FloatingObjectSet::iterator it =
@@ -4438,7 +4435,7 @@
 
 RootInlineBox* LayoutBlockFlow::CreateRootInlineBox() {
   NOT_DESTROYED();
-  return MakeGarbageCollected<RootInlineBox>(LineLayoutItem(this));
+  return new RootInlineBox(LineLayoutItem(this));
 }
 
 void LayoutBlockFlow::CreateOrDestroyMultiColumnFlowThreadIfNeeded(
@@ -4529,7 +4526,7 @@
 void LayoutBlockFlow::SimplifiedNormalFlowInlineLayout() {
   NOT_DESTROYED();
   DCHECK(ChildrenInline());
-  HeapLinkedHashSet<Member<RootInlineBox>> line_boxes;
+  LinkedHashSet<RootInlineBox*> line_boxes;
   for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.AtEnd();
        walker.Advance()) {
     LayoutObject* o = walker.Current().GetLayoutObject();
@@ -4549,7 +4546,7 @@
   // FIXME: Glyph overflow will get lost in this case, but not really a big
   // deal.
   GlyphOverflowAndFallbackFontsMap text_box_data_map;
-  for (auto box : line_boxes) {
+  for (auto* box : line_boxes) {
     box->ComputeOverflow(box->LineTop(), box->LineBottom(), text_box_data_map);
   }
 }
@@ -4559,7 +4556,7 @@
   NOT_DESTROYED();
   DCHECK(ChildrenInline());
   RecalcLayoutOverflowResult result;
-  HeapHashSet<Member<RootInlineBox>> line_boxes;
+  HashSet<RootInlineBox*> line_boxes;
   for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.AtEnd();
        walker.Advance()) {
     LayoutObject* layout_object = walker.Current().GetLayoutObject();
@@ -4580,7 +4577,7 @@
   // FIXME: Glyph overflow will get lost in this case, but not really a big
   // deal.
   GlyphOverflowAndFallbackFontsMap text_box_data_map;
-  for (auto box : line_boxes) {
+  for (auto* box : line_boxes) {
     box->ClearKnownToHaveNoOverflow();
     box->ComputeOverflow(box->LineTop(), box->LineBottom(), text_box_data_map);
   }
@@ -4904,17 +4901,12 @@
 
 LayoutBlockFlow::LayoutBlockFlowRareData::~LayoutBlockFlowRareData() = default;
 
-void LayoutBlockFlow::LayoutBlockFlowRareData::Trace(Visitor* visitor) const {
-  visitor->Trace(multi_column_flow_thread_);
-  visitor->Trace(offset_mapping_);
-}
-
 void LayoutBlockFlow::ClearOffsetMappingIfNeeded() {
   NOT_DESTROYED();
   DCHECK(!IsLayoutNGObject());
   if (!rare_data_)
     return;
-  rare_data_->offset_mapping_.Clear();
+  rare_data_->offset_mapping_.reset();
 }
 
 const NGOffsetMapping* LayoutBlockFlow::GetOffsetMapping() const {
@@ -4922,14 +4914,15 @@
   DCHECK(!IsLayoutNGObject());
   CHECK(!SelfNeedsLayout());
   CHECK(!NeedsLayout() || ChildLayoutBlockedByDisplayLock());
-  return rare_data_ ? rare_data_->offset_mapping_ : nullptr;
+  return rare_data_ ? rare_data_->offset_mapping_.get() : nullptr;
 }
 
-void LayoutBlockFlow::SetOffsetMapping(NGOffsetMapping* offset_mapping) {
+void LayoutBlockFlow::SetOffsetMapping(
+    std::unique_ptr<NGOffsetMapping> offset_mapping) {
   NOT_DESTROYED();
   DCHECK(!IsLayoutNGObject());
   DCHECK(offset_mapping);
-  EnsureRareData().offset_mapping_ = offset_mapping;
+  EnsureRareData().offset_mapping_ = std::move(offset_mapping);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.h b/third_party/blink/renderer/core/layout/layout_block_flow.h
index 949f4a9..0b1b8643 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow.h
+++ b/third_party/blink/renderer/core/layout/layout_block_flow.h
@@ -97,10 +97,9 @@
  public:
   explicit LayoutBlockFlow(ContainerNode*);
   ~LayoutBlockFlow() override;
-  void Trace(Visitor*) const override;
 
   static LayoutBlockFlow* CreateAnonymous(Document*,
-                                          ComputedStyle*,
+                                          scoped_refptr<ComputedStyle>,
                                           LegacyLayout);
 
   bool IsLayoutBlockFlow() const final {
@@ -469,7 +468,7 @@
 
   FloatingObject* LastFloatFromPreviousLine() const {
     NOT_DESTROYED();
-    return ContainsFloats() ? floating_objects_->Set().back().Get() : nullptr;
+    return ContainsFloats() ? floating_objects_->Set().back().get() : nullptr;
   }
 
   void SetShouldDoFullPaintInvalidationForFirstLine();
@@ -755,7 +754,7 @@
       rect.Expand(f->MarginBoxOutsets());
     }
 
-    UntracedMember<LayoutBox> object;
+    LayoutBox* object;
     LayoutRect rect;
     bool ever_had_layout;
   };
@@ -833,20 +832,20 @@
       return (-block->MarginAfter()).ClampNegativeToZero();
     }
 
-    void Trace(Visitor*) const;
+    void Trace(Visitor*) const {}
 
     MarginValues margins_;
     LayoutUnit pagination_strut_propagated_from_child_;
 
     LayoutUnit first_forced_break_offset_;
 
-    Member<LayoutMultiColumnFlowThread> multi_column_flow_thread_;
+    LayoutMultiColumnFlowThread* multi_column_flow_thread_ = nullptr;
 
     // |offset_mapping_| is used only for legacy layout tree for caching offset
     // mapping for |NGInlineNode::GetOffsetMapping()|.
     // TODO(yosin): Once we have no legacy support, we should get rid of
     // |offset_mapping_| here.
-    Member<NGOffsetMapping> offset_mapping_;
+    std::unique_ptr<NGOffsetMapping> offset_mapping_;
 
     // Name of the start page for this object, if propagated from a descendant;
     // see https://drafts.csswg.org/css-page-3/#start-page-value
@@ -864,11 +863,11 @@
 
   void ClearOffsetMappingIfNeeded();
   const NGOffsetMapping* GetOffsetMapping() const;
-  void SetOffsetMapping(NGOffsetMapping*);
+  void SetOffsetMapping(std::unique_ptr<NGOffsetMapping>);
 
   const FloatingObjects* GetFloatingObjects() const {
     NOT_DESTROYED();
-    return floating_objects_;
+    return floating_objects_.get();
   }
 
   static void UpdateAncestorShouldPaintFloatingObject(
@@ -1001,8 +1000,8 @@
   bool CheckIfIsSelfCollapsingBlock() const;
 
  protected:
-  Member<LayoutBlockFlowRareData> rare_data_;
-  Member<FloatingObjects> floating_objects_;
+  Persistent<LayoutBlockFlowRareData> rare_data_;
+  std::unique_ptr<FloatingObjects> floating_objects_;
 
   friend class MarginInfo;
   friend class LineWidth;  // needs to know FloatingObject
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
index 3e285ae..0fa4693 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
+++ b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
@@ -105,7 +105,7 @@
 
         // Don't justify for white-space: pre.
         if (r->line_layout_item_.StyleRef().WhiteSpace() != EWhiteSpace::kPre) {
-          auto* text_box = To<InlineTextBox>(r->box_.Get());
+          auto* text_box = To<InlineTextBox>(r->box_);
           CHECK(total_opportunities_);
           int expansion = ((available_logical_width - total_logical_width) *
                            opportunities_in_run / total_opportunities_)
@@ -547,7 +547,7 @@
   const Font& font = layout_text.Style(line_info.IsFirstLine())->GetFont();
 
   LayoutUnit hyphen_width;
-  if (To<InlineTextBox>(run->box_.Get())->HasHyphen())
+  if (To<InlineTextBox>(run->box_)->HasHyphen())
     hyphen_width = LayoutUnit(layout_text.HyphenWidth(font, run->Direction()));
 
   float measured_width = 0;
@@ -634,7 +634,7 @@
     DCHECK(run->box_->IsText());
     GlyphOverflowAndFallbackFontsMap::ValueType* it =
         text_box_data_map
-            .insert(To<InlineTextBox>(run->box_.Get()),
+            .insert(To<InlineTextBox>(run->box_),
                     std::make_pair(Vector<const SimpleFontData*>(),
                                    GlyphOverflow()))
             .stored_value;
@@ -646,7 +646,7 @@
     DCHECK(run->box_->IsText());
     GlyphOverflowAndFallbackFontsMap::ValueType* it =
         text_box_data_map
-            .insert(To<InlineTextBox>(run->box_.Get()),
+            .insert(To<InlineTextBox>(run->box_),
                     std::make_pair(Vector<const SimpleFontData*>(),
                                    GlyphOverflow()))
             .stored_value;
@@ -831,7 +831,7 @@
       if (text_align == ETextAlign::kJustify && r != trailing_space_run &&
           text_justify != TextJustify::kNone) {
         if (!is_after_expansion)
-          To<InlineTextBox>(r->box_.Get())->SetCanHaveLeadingExpansion(true);
+          To<InlineTextBox>(r->box_)->SetCanHaveLeadingExpansion(true);
         expansions.AddRunWithExpansions(*r, is_after_expansion, text_justify);
       }
 
@@ -1000,7 +1000,7 @@
   RootInlineBox* start_line = DetermineStartPosition(layout_state, resolver);
 
   if (ContainsFloats())
-    layout_state.SetLastFloat(floating_objects_->Set().back().Get());
+    layout_state.SetLastFloat(floating_objects_->Set().back().get());
 
   // We also find the first clean line and extract these lines.  We will add
   // them back if we determine that we're able to synchronize after handling all
@@ -1052,7 +1052,7 @@
     it = last_float_iterator;
   }
   for (; it != end; ++it) {
-    FloatingObject& floating_object = *it->Get();
+    FloatingObject& floating_object = *it->get();
     // If we've reached the start of clean lines any remaining floating children
     // belong to them.
     if (clean_line_start.GetLineLayoutItem().IsEqual(
@@ -1080,7 +1080,7 @@
     layout_state.SetFloatIndex(layout_state.FloatIndex() + 1);
   }
   layout_state.SetLastFloat(!floating_object_set.IsEmpty()
-                                ? floating_object_set.back().Get()
+                                ? floating_object_set.back().get()
                                 : nullptr);
 }
 
@@ -1134,7 +1134,7 @@
     bool is_new_uba_paragraph =
         layout_state.GetLineInfo().PreviousLineBrokeCleanly();
     FloatingObject* last_float_from_previous_line =
-        (ContainsFloats()) ? floating_objects_->Set().back().Get() : nullptr;
+        (ContainsFloats()) ? floating_objects_->Set().back().get() : nullptr;
 
     WordMeasurements word_measurements;
     end_of_line =
@@ -1145,7 +1145,7 @@
       // FIXME: We shouldn't be creating any runs in nextLineBreak to begin
       // with! Once BidiRunList is separated from BidiResolver this will not be
       // needed.
-      resolver.Runs().ClearRuns();
+      resolver.Runs().DeleteRuns();
       resolver.MarkCurrentRunEmpty();  // FIXME: This can probably be replaced
                                        // by an ASSERT (or just removed).
       resolver.SetPosition(
@@ -1163,7 +1163,7 @@
         LastRootBox()->SetLineBreakInfo(end_of_line.GetLineLayoutItem(),
                                         end_of_line.Offset(),
                                         resolver.Status());
-      resolver.Runs().ClearRuns();
+      resolver.Runs().DeleteRuns();
     } else {
       VisualDirectionOverride override =
           (style_to_use.RtlOrdering() == EOrder::kVisual
@@ -1220,7 +1220,7 @@
           layout_state.GetLineInfo(), vertical_position_cache,
           trailing_space_run, word_measurements);
 
-      bidi_runs.ClearRuns();
+      bidi_runs.DeleteRuns();
       resolver.MarkCurrentRunEmpty();  // FIXME: This can probably be replaced
                                        // by an ASSERT (or just removed).
 
@@ -1419,8 +1419,8 @@
         }
         if (delta)
           line->MoveInBlockDirection(delta);
-        if (auto* clean_line_floats = line->FloatsPtr()) {
-          for (const auto& box : *clean_line_floats) {
+        if (Vector<LayoutBox*>* clean_line_floats = line->FloatsPtr()) {
+          for (auto* box : *clean_line_floats) {
             FloatingObject* floating_object = InsertFloatingObject(*box);
             DCHECK(!floating_object->OriginatingLine());
             floating_object->SetOriginatingLine(line);
@@ -1998,7 +1998,7 @@
     // the replaced elements later. In partial layout mode, line boxes are not
     // deleted and only dirtied. In that case, we can layout the replaced
     // elements at the same time.
-    HeapVector<Member<LayoutBox>> atomic_inline_children;
+    Vector<LayoutBox*> atomic_inline_children;
     for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.AtEnd();
          walker.Advance()) {
       LayoutObject* o = walker.Current().GetLayoutObject();
@@ -2064,7 +2064,7 @@
     // Now all |DirtyLineBoxesForObject()| is done. We can safely start
     // adding |InlineBox|es to |LineBoxes()|.
     DCHECK(!is_full_layout || !LineBoxes()->First());
-    for (const auto& atomic_inline_child : atomic_inline_children) {
+    for (LayoutBox* atomic_inline_child : atomic_inline_children) {
       atomic_inline_child->LayoutIfNeeded();
 #if DCHECK_IS_ON()
       // |LayoutIfNeeded| should not mark itself and its ancestors to
@@ -2208,8 +2208,8 @@
     // Restore floats from clean lines.
     RootInlineBox* line = FirstRootBox();
     while (line != curr) {
-      if (auto* clean_line_floats = line->FloatsPtr()) {
-        for (const auto& box : *clean_line_floats) {
+      if (Vector<LayoutBox*>* clean_line_floats = line->FloatsPtr()) {
+        for (auto* box : *clean_line_floats) {
           FloatingObject* floating_object = InsertFloatingObject(*box);
           DCHECK(!floating_object->OriginatingLine());
           floating_object->SetOriginatingLine(line);
@@ -2355,7 +2355,7 @@
   FloatingObjectSetIterator end = floating_object_set.end();
   for (FloatingObjectSetIterator it = floating_object_set.begin(); it != end;
        ++it) {
-    const FloatingObject& floating_object = *it->Get();
+    const FloatingObject& floating_object = *it->get();
     if (LogicalBottomForFloat(floating_object) >= logical_top &&
         LogicalBottomForFloat(floating_object) < logical_bottom)
       return false;
diff --git a/third_party/blink/renderer/core/layout/layout_block_test.cc b/third_party/blink/renderer/core/layout/layout_block_test.cc
index 38bd000..0bdd34e 100644
--- a/third_party/blink/renderer/core/layout/layout_block_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_block_test.cc
@@ -19,7 +19,8 @@
 class LayoutBlockTest : public RenderingTest {};
 
 TEST_F(LayoutBlockTest, LayoutNameCalledWithNullStyle) {
-  ComputedStyle* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style =
+      GetDocument().GetStyleResolver().CreateComputedStyle();
   LayoutObject* obj = LayoutBlockFlow::CreateAnonymous(&GetDocument(), style,
                                                        LegacyLayout::kAuto);
   obj->SetModifiedStyleOutsideStyleRecalc(nullptr,
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index a0dd6ee..86630deb 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -129,12 +129,9 @@
   LayoutRectOutsets margin_box_outsets;
   MinMaxSizes intrinsic_logical_widths;
   LayoutUnit intrinsic_logical_widths_initial_block_size;
-  Member<void*> result;
-  HeapVector<Member<const NGLayoutResult>, 1> layout_results;
-  void* pointers[2];
-  Member<void*> inline_box_wrapper;
-  wtf_size_t first_fragment_item_index_;
-  Member<void*> rare_data;
+  void* pointers[4];
+  Vector<scoped_refptr<const NGLayoutResult>, 1> layout_results;
+  Persistent<void*> rare_data;
 };
 
 ASSERT_SIZE(LayoutBox, SameSizeAsLayoutBox);
@@ -400,13 +397,12 @@
 
 }  // namespace
 
-BoxLayoutExtraInput::BoxLayoutExtraInput(LayoutBox& layout_box)
-    : box(&layout_box) {
-  box->SetBoxLayoutExtraInput(this);
+BoxLayoutExtraInput::BoxLayoutExtraInput(LayoutBox& box) : box(box) {
+  box.SetBoxLayoutExtraInput(this);
 }
 
 BoxLayoutExtraInput::~BoxLayoutExtraInput() {
-  box->SetBoxLayoutExtraInput(nullptr);
+  box.SetBoxLayoutExtraInput(nullptr);
 }
 
 LayoutBoxRareData::LayoutBoxRareData()
@@ -419,13 +415,10 @@
       has_override_percentage_resolution_block_size_(false),
       has_previous_content_box_rect_(false),
       percent_height_container_(nullptr),
-      snap_container_(nullptr) {}
+      snap_container_(nullptr),
+      snap_areas_(nullptr) {}
 
 void LayoutBoxRareData::Trace(Visitor* visitor) const {
-  visitor->Trace(spanner_placeholder_);
-  visitor->Trace(percent_height_container_);
-  visitor->Trace(snap_container_);
-  visitor->Trace(snap_areas_);
   visitor->Trace(layout_child_);
 }
 
@@ -439,14 +432,6 @@
     SetIsHTMLLegendElement();
 }
 
-void LayoutBox::Trace(Visitor* visitor) const {
-  visitor->Trace(measure_result_);
-  visitor->Trace(layout_results_);
-  visitor->Trace(inline_box_wrapper_);
-  visitor->Trace(rare_data_);
-  LayoutBoxModelObject::Trace(visitor);
-}
-
 LayoutBox::~LayoutBox() = default;
 
 PaintLayerType LayoutBox::LayerTypeRequired() const {
@@ -3167,7 +3152,7 @@
 
 InlineBox* LayoutBox::CreateInlineBox() {
   NOT_DESTROYED();
-  return MakeGarbageCollected<InlineBox>(LineLayoutItem(this));
+  return new InlineBox(LineLayoutItem(this));
 }
 
 void LayoutBox::DirtyLineBoxes(bool full_layout) {
@@ -3238,7 +3223,8 @@
   return IndexOf(fragment) != kNotFound;
 }
 
-void LayoutBox::SetCachedLayoutResult(const NGLayoutResult* result) {
+void LayoutBox::SetCachedLayoutResult(
+    scoped_refptr<const NGLayoutResult> result) {
   NOT_DESTROYED();
   DCHECK(!result->PhysicalFragment().BreakToken());
   DCHECK(To<NGPhysicalBoxFragment>(result->PhysicalFragment()).IsOnlyForNode());
@@ -3274,7 +3260,7 @@
   AddLayoutResult(std::move(result), 0);
 }
 
-void LayoutBox::AddLayoutResult(const NGLayoutResult* result,
+void LayoutBox::AddLayoutResult(scoped_refptr<const NGLayoutResult> result,
                                 wtf_size_t index) {
   NOT_DESTROYED();
   DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess);
@@ -3289,7 +3275,7 @@
   AddLayoutResult(std::move(result));
 }
 
-void LayoutBox::AddLayoutResult(const NGLayoutResult* result) {
+void LayoutBox::AddLayoutResult(scoped_refptr<const NGLayoutResult> result) {
   const auto& fragment = To<NGPhysicalBoxFragment>(result->PhysicalFragment());
   layout_results_.push_back(std::move(result));
   CheckDidAddFragment(*this, fragment);
@@ -3300,12 +3286,12 @@
     NGFragmentItems::FinalizeAfterLayout(layout_results_);
 }
 
-void LayoutBox::ReplaceLayoutResult(const NGLayoutResult* result,
+void LayoutBox::ReplaceLayoutResult(scoped_refptr<const NGLayoutResult> result,
                                     wtf_size_t index) {
   NOT_DESTROYED();
   DCHECK_LE(index, layout_results_.size());
-  const NGLayoutResult* old_result = layout_results_[index];
-  if (old_result == result)
+  const NGLayoutResult* old_result = layout_results_[index].get();
+  if (old_result == result.get())
     return;
   const auto& fragment = To<NGPhysicalBoxFragment>(result->PhysicalFragment());
   bool got_new_fragment = &old_result->PhysicalFragment() != &fragment;
@@ -3335,7 +3321,7 @@
     NGFragmentItems::FinalizeAfterLayout(layout_results_);
 }
 
-void LayoutBox::ReplaceLayoutResult(const NGLayoutResult* result,
+void LayoutBox::ReplaceLayoutResult(scoped_refptr<const NGLayoutResult> result,
                                     const NGPhysicalBoxFragment& old_fragment) {
   DCHECK_EQ(this, old_fragment.OwnerLayoutBox());
   DCHECK_EQ(result->PhysicalFragment().GetSelfOrContainerLayoutObject(),
@@ -3396,7 +3382,7 @@
   if (layout_results_.IsEmpty())
     return nullptr;
   // Only return re-usable results.
-  const NGLayoutResult* result = layout_results_[0];
+  const NGLayoutResult* result = layout_results_[0].get();
   if (!To<NGPhysicalBoxFragment>(result->PhysicalFragment()).IsOnlyForNode())
     return nullptr;
   DCHECK(!result->PhysicalFragment().IsLayoutObjectDestroyedOrMoved() ||
@@ -3414,10 +3400,10 @@
            .IsOnlyForNode())
     return nullptr;
 
-  return measure_result_;
+  return measure_result_.get();
 }
 
-const NGLayoutResult* LayoutBox::CachedLayoutResult(
+scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
     const NGConstraintSpace& new_space,
     const NGBreakToken* break_token,
     const NGEarlyBreak* early_break,
@@ -3642,7 +3628,7 @@
       NeedsLayoutOverflowRecalc() &&
       RuntimeEnabledFeatures::LayoutNGLayoutOverflowRecalcEnabled()) {
 #if DCHECK_IS_ON()
-    const NGLayoutResult* cloned_cached_layout_result =
+    scoped_refptr<const NGLayoutResult> cloned_cached_layout_result =
         NGLayoutResult::CloneWithPostLayoutFragments(*cached_layout_result);
 #endif
     RecalcLayoutOverflow();
@@ -3690,9 +3676,10 @@
     return cached_layout_result;
   }
 
-  const NGLayoutResult* new_result = MakeGarbageCollected<NGLayoutResult>(
-      *cached_layout_result, new_space, end_margin_strut, bfc_line_offset,
-      bfc_block_offset, block_offset_delta);
+  scoped_refptr<const NGLayoutResult> new_result =
+      base::AdoptRef(new NGLayoutResult(*cached_layout_result, new_space,
+                                        end_margin_strut, bfc_line_offset,
+                                        bfc_block_offset, block_offset_delta));
 
   if (needs_cached_result_update)
     SetCachedLayoutResult(new_result);
@@ -8073,7 +8060,7 @@
 void LayoutBox::ClearSnapAreas() {
   NOT_DESTROYED();
   if (SnapAreaSet* areas = SnapAreas()) {
-    for (const auto& snap_area : *areas)
+    for (auto* const snap_area : *areas)
       snap_area->rare_data_->snap_container_ = nullptr;
     areas->clear();
   }
@@ -8081,15 +8068,15 @@
 
 void LayoutBox::AddSnapArea(LayoutBox& snap_area) {
   NOT_DESTROYED();
-  EnsureRareData().snap_areas_.insert(&snap_area);
+  EnsureRareData().EnsureSnapAreas().insert(&snap_area);
 }
 
 void LayoutBox::RemoveSnapArea(const LayoutBox& snap_area) {
   NOT_DESTROYED();
   // const_cast is safe here because we only need to modify the type to match
   // the key type, and not actually mutate the object.
-  if (rare_data_)
-    rare_data_->snap_areas_.erase(const_cast<LayoutBox*>(&snap_area));
+  if (rare_data_ && rare_data_->snap_areas_)
+    rare_data_->snap_areas_->erase(const_cast<LayoutBox*>(&snap_area));
 }
 
 void LayoutBox::ReassignSnapAreas(LayoutBox& new_container) {
@@ -8097,7 +8084,7 @@
   SnapAreaSet* areas = SnapAreas();
   if (!areas)
     return;
-  for (const auto& snap_area : *areas) {
+  for (auto* const snap_area : *areas) {
     snap_area->rare_data_->snap_container_ = &new_container;
     new_container.AddSnapArea(*snap_area);
   }
@@ -8118,7 +8105,7 @@
 
 SnapAreaSet* LayoutBox::SnapAreas() const {
   NOT_DESTROYED();
-  return rare_data_ ? &rare_data_->snap_areas_ : nullptr;
+  return rare_data_ ? rare_data_->snap_areas_.get() : nullptr;
 }
 
 CustomLayoutChild* LayoutBox::GetCustomLayoutChild() const {
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h
index aee56df..0b3d48a 100644
--- a/third_party/blink/renderer/core/layout/layout_box.h
+++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -72,7 +72,7 @@
   kIncludeScrollbarGutter
 };
 
-using SnapAreaSet = HeapHashSet<Member<LayoutBox>>;
+using SnapAreaSet = HashSet<LayoutBox*>;
 
 struct LayoutBoxRareData final : public GarbageCollected<LayoutBoxRareData> {
  public:
@@ -84,7 +84,7 @@
 
   // For spanners, the spanner placeholder that lays us out within the multicol
   // container.
-  Member<LayoutMultiColumnSpannerPlaceholder> spanner_placeholder_;
+  LayoutMultiColumnSpannerPlaceholder* spanner_placeholder_;
 
   LayoutUnit override_logical_width_;
   LayoutUnit override_logical_height_;
@@ -102,12 +102,19 @@
 
   LayoutUnit pagination_strut_;
 
-  Member<LayoutBlock> percent_height_container_;
+  LayoutBlock* percent_height_container_;
   // For snap area, the owning snap container.
-  Member<LayoutBox> snap_container_;
+  LayoutBox* snap_container_;
   // For snap container, the descendant snap areas that contribute snap
   // points.
-  SnapAreaSet snap_areas_;
+  std::unique_ptr<SnapAreaSet> snap_areas_;
+
+  SnapAreaSet& EnsureSnapAreas() {
+    if (!snap_areas_)
+      snap_areas_ = std::make_unique<SnapAreaSet>();
+
+    return *snap_areas_;
+  }
 
   // Used by BoxPaintInvalidator. Stores the previous content rect after the
   // last paint invalidation. It's valid if has_previous_content_box_rect_ is
@@ -216,7 +223,6 @@
 class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
  public:
   explicit LayoutBox(ContainerNode*);
-  void Trace(Visitor*) const override;
 
   PaintLayerType LayerTypeRequired() const override;
 
@@ -1181,14 +1187,15 @@
 
   void InvalidateItems(const NGLayoutResult&);
 
-  void SetCachedLayoutResult(const NGLayoutResult*);
+  void SetCachedLayoutResult(scoped_refptr<const NGLayoutResult>);
 
   // Store one layout result (with its physical fragment) at the specified
   // index, and delete all entries following it.
-  void AddLayoutResult(const NGLayoutResult*, wtf_size_t index);
-  void AddLayoutResult(const NGLayoutResult*);
-  void ReplaceLayoutResult(const NGLayoutResult*, wtf_size_t index);
-  void ReplaceLayoutResult(const NGLayoutResult*,
+  void AddLayoutResult(scoped_refptr<const NGLayoutResult>, wtf_size_t index);
+  void AddLayoutResult(scoped_refptr<const NGLayoutResult>);
+  void ReplaceLayoutResult(scoped_refptr<const NGLayoutResult>,
+                           wtf_size_t index);
+  void ReplaceLayoutResult(scoped_refptr<const NGLayoutResult>,
                            const NGPhysicalBoxFragment& old_fragment);
 
   void ShrinkLayoutResults(wtf_size_t results_to_keep);
@@ -1207,14 +1214,14 @@
   // |out_cache_status| indicates what type of layout pass is required.
   //
   // TODO(ikilpatrick): Move this function into NGBlockNode.
-  const NGLayoutResult* CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> CachedLayoutResult(
       const NGConstraintSpace&,
       const NGBreakToken*,
       const NGEarlyBreak*,
       base::Optional<NGFragmentGeometry>* initial_fragment_geometry,
       NGLayoutCacheStatus* out_cache_status);
 
-  using NGLayoutResultList = HeapVector<Member<const NGLayoutResult>, 1>;
+  using NGLayoutResultList = Vector<scoped_refptr<const NGLayoutResult>, 1>;
   class NGPhysicalFragmentList {
     STACK_ALLOCATED();
 
@@ -2342,7 +2349,7 @@
   MinMaxSizes intrinsic_logical_widths_;
   LayoutUnit intrinsic_logical_widths_initial_block_size_;
 
-  Member<const NGLayoutResult> measure_result_;
+  scoped_refptr<const NGLayoutResult> measure_result_;
   NGLayoutResultList layout_results_;
 
   // LayoutBoxUtils is used for the LayoutNG code querying protected methods on
@@ -2368,16 +2375,17 @@
   // laid out.
   const BoxLayoutExtraInput* extra_input_ = nullptr;
 
-  // The inline box containing this LayoutBox, for atomic inline elements.
-  // Valid only when !IsInLayoutNGInlineFormattingContext().
-  Member<InlineBox> inline_box_wrapper_;
+  union {
+    // The inline box containing this LayoutBox, for atomic inline elements.
+    // Valid only when !IsInLayoutNGInlineFormattingContext().
+    InlineBox* inline_box_wrapper_;
+    // The index of the first fragment item associated with this object in
+    // |NGFragmentItems::Items()|. Zero means there are no such item.
+    // Valid only when IsInLayoutNGInlineFormattingContext().
+    wtf_size_t first_fragment_item_index_;
+  };
 
-  // The index of the first fragment item associated with this object in
-  // |NGFragmentItems::Items()|. Zero means there are no such item.
-  // Valid only when IsInLayoutNGInlineFormattingContext().
-  wtf_size_t first_fragment_item_index_ = 0u;
-
-  Member<LayoutBoxRareData> rare_data_;
+  Persistent<LayoutBoxRareData> rare_data_;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
index 9b2deb7..055328a7 100644
--- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -81,13 +81,11 @@
 // The HashMap for storing continuation pointers.
 // The continuation chain is a singly linked list. As such, the HashMap's value
 // is the next pointer associated with the key.
-typedef HeapHashMap<WeakMember<const LayoutBoxModelObject>,
-                    Member<LayoutBoxModelObject>>
+typedef HashMap<const LayoutBoxModelObject*, LayoutBoxModelObject*>
     ContinuationMap;
 static ContinuationMap& GetContinuationMap() {
-  DEFINE_STATIC_LOCAL(Persistent<ContinuationMap>, map,
-                      (MakeGarbageCollected<ContinuationMap>()));
-  return *map;
+  DEFINE_STATIC_LOCAL(ContinuationMap, map, ());
+  return map;
 }
 
 void LayoutBoxModelObject::ContentChanged(ContentChangeType change_type) {
@@ -215,7 +213,11 @@
   return paint_location;
 }
 
-LayoutBoxModelObject::~LayoutBoxModelObject() = default;
+LayoutBoxModelObject::~LayoutBoxModelObject() {
+  // Our layer should have been destroyed and cleared by now
+  DCHECK(!HasLayer());
+  DCHECK(!Layer());
+}
 
 void LayoutBoxModelObject::WillBeDestroyed() {
   NOT_DESTROYED();
@@ -242,10 +244,6 @@
 
   if (HasLayer())
     DestroyLayer();
-
-  // Our layer should have been destroyed and cleared by now
-  DCHECK(!HasLayer());
-  DCHECK(!Layer());
 }
 
 void LayoutBoxModelObject::StyleWillChange(StyleDifference diff,
@@ -539,7 +537,7 @@
   NOT_DESTROYED();
   DCHECK(!HasLayer() && !Layer());
   GetMutableForPainting().FirstFragment().SetLayer(
-      MakeGarbageCollected<PaintLayer>(this));
+      std::make_unique<PaintLayer>(*this));
   SetHasLayer(true);
   Layer()->InsertOnlyThisLayerAfterStyleChange();
   // Creating a layer may affect existence of the LocalBorderBoxProperties, so
@@ -970,8 +968,7 @@
 
   const PhysicalSize constraining_size = ComputeStickyConstrainingRect().size;
 
-  StickyPositionScrollingConstraints* constraints =
-      MakeGarbageCollected<StickyPositionScrollingConstraints>();
+  StickyPositionScrollingConstraints constraints;
   PhysicalOffset skipped_containers_offset;
   LayoutBlock* sticky_container = StickyContainer();
   // The location container for boxes is not always the containing block.
@@ -1046,7 +1043,7 @@
                             max_container_width) +
           MinimumValueForLength(StyleRef().MarginLeft(), max_width));
 
-  constraints->scroll_container_relative_containing_block_rect =
+  constraints.scroll_container_relative_containing_block_rect =
       scroll_container_relative_containing_block_rect;
 
   PhysicalRect sticky_box_rect;
@@ -1067,7 +1064,7 @@
   PhysicalOffset container_border_offset(sticky_container->BorderLeft(),
                                          sticky_container->BorderTop());
   sticky_location -= container_border_offset;
-  constraints->scroll_container_relative_sticky_box_rect = PhysicalRect(
+  constraints.scroll_container_relative_sticky_box_rect = PhysicalRect(
       scroll_container_relative_padding_box_rect.offset + sticky_location,
       sticky_box_rect.size);
 
@@ -1077,11 +1074,11 @@
   //
   // The respective search ranges are [container, containingBlock) and
   // [containingBlock, scrollAncestor).
-  constraints->nearest_sticky_layer_shifting_sticky_box =
+  constraints.nearest_sticky_layer_shifting_sticky_box =
       FindFirstStickyBetween(location_container, sticky_container);
   // We cannot use |scrollAncestor| here as it disregards the root
   // ancestorOverflowLayer(), which we should include.
-  constraints->nearest_sticky_layer_shifting_containing_block =
+  constraints.nearest_sticky_layer_shifting_containing_block =
       FindFirstStickyBetween(
           sticky_container,
           &Layer()->AncestorScrollContainerLayer()->GetLayoutObject());
@@ -1102,15 +1099,15 @@
   }
 
   if (!StyleRef().Left().IsAuto() && !skip_left) {
-    constraints->left_offset =
+    constraints.left_offset =
         MinimumValueForLength(StyleRef().Left(), constraining_size.width);
-    constraints->is_anchored_left = true;
+    constraints.is_anchored_left = true;
   }
 
   if (!StyleRef().Right().IsAuto() && !skip_right) {
-    constraints->right_offset =
+    constraints.right_offset =
         MinimumValueForLength(StyleRef().Right(), constraining_size.width);
-    constraints->is_anchored_right = true;
+    constraints.is_anchored_right = true;
   }
 
   bool skip_bottom = false;
@@ -1128,15 +1125,15 @@
   }
 
   if (!StyleRef().Top().IsAuto()) {
-    constraints->top_offset =
+    constraints.top_offset =
         MinimumValueForLength(StyleRef().Top(), constraining_size.height);
-    constraints->is_anchored_top = true;
+    constraints.is_anchored_top = true;
   }
 
   if (!StyleRef().Bottom().IsAuto() && !skip_bottom) {
-    constraints->bottom_offset =
+    constraints.bottom_offset =
         MinimumValueForLength(StyleRef().Bottom(), constraining_size.height);
-    constraints->is_anchored_bottom = true;
+    constraints.is_anchored_bottom = true;
   }
   PaintLayerScrollableArea* scrollable_area =
       Layer()->AncestorScrollContainerLayer()->GetScrollableArea();
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc b/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc
index baa593f..2bd36c3 100644
--- a/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc
@@ -45,18 +45,18 @@
   sticky->UpdateStickyPositionConstraints();
   ASSERT_EQ(scroller->Layer(), sticky->Layer()->AncestorScrollContainerLayer());
 
-  const StickyPositionScrollingConstraints* constraints =
+  const StickyPositionScrollingConstraints& constraints =
       scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
-  ASSERT_EQ(0.f, constraints->top_offset);
+  ASSERT_EQ(0.f, constraints.top_offset);
 
   // The coordinates of the constraint rects should all be with respect to the
   // unscrolled scroller.
   ASSERT_EQ(IntRect(15, 115, 170, 370),
             EnclosingIntRect(
-                constraints->scroll_container_relative_containing_block_rect));
+                constraints.scroll_container_relative_containing_block_rect));
   ASSERT_EQ(
       IntRect(15, 115, 100, 100),
-      EnclosingIntRect(constraints->scroll_container_relative_sticky_box_rect));
+      EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
 
   // The sticky constraining rect also doesn't include the border offset.
   ASSERT_EQ(IntRect(0, 0, 400, 100),
@@ -86,18 +86,18 @@
   sticky->UpdateStickyPositionConstraints();
   ASSERT_EQ(scroller->Layer(), sticky->Layer()->AncestorScrollContainerLayer());
 
-  const StickyPositionScrollingConstraints* constraints =
+  const StickyPositionScrollingConstraints& constraints =
       scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
-  ASSERT_EQ(0.f, constraints->top_offset);
+  ASSERT_EQ(0.f, constraints.top_offset);
 
   // The coordinates of the constraint rects should all be with respect to the
   // unscrolled scroller.
   ASSERT_EQ(IntRect(215, 115, 170, 370),
             EnclosingIntRect(
-                constraints->scroll_container_relative_containing_block_rect));
+                constraints.scroll_container_relative_containing_block_rect));
   ASSERT_EQ(
       IntRect(285, 115, 100, 100),
-      EnclosingIntRect(constraints->scroll_container_relative_sticky_box_rect));
+      EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
 
   // The sticky constraining rect also doesn't include the border offset.
   ASSERT_EQ(IntRect(0, 0, 400, 100),
@@ -136,19 +136,19 @@
 
   EXPECT_EQ(scroller->Layer(), sticky->Layer()->AncestorScrollContainerLayer());
 
-  const StickyPositionScrollingConstraints* constraints =
+  const StickyPositionScrollingConstraints& constraints =
       scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
 
-  EXPECT_EQ(10.f, constraints->top_offset);
+  EXPECT_EQ(10.f, constraints.top_offset);
 
   // The coordinates of the constraint rects should all be with respect to the
   // unscrolled scroller.
   EXPECT_EQ(IntRect(0, 100, 200, 400),
             EnclosingIntRect(
-                constraints->scroll_container_relative_containing_block_rect));
+                constraints.scroll_container_relative_containing_block_rect));
   EXPECT_EQ(
       IntRect(0, 100, 10, 10),
-      EnclosingIntRect(constraints->scroll_container_relative_sticky_box_rect));
+      EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
   EXPECT_EQ(IntRect(0, 0, 100, 100),
             EnclosingIntRect(sticky->ComputeStickyConstrainingRect()));
 }
@@ -193,19 +193,19 @@
 
   EXPECT_EQ(scroller->Layer(), sticky->Layer()->AncestorScrollContainerLayer());
 
-  const StickyPositionScrollingConstraints* constraints =
+  const StickyPositionScrollingConstraints& constraints =
       scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
 
-  EXPECT_EQ(10.f, constraints->top_offset);
+  EXPECT_EQ(10.f, constraints.top_offset);
 
   // The coordinates of the constraint rects should all be with respect to the
   // unscrolled scroller.
   EXPECT_EQ(IntRect(2000, 100, 200, 400),
             EnclosingIntRect(
-                constraints->scroll_container_relative_containing_block_rect));
+                constraints.scroll_container_relative_containing_block_rect));
   EXPECT_EQ(
       IntRect(2190, 100, 10, 10),
-      EnclosingIntRect(constraints->scroll_container_relative_sticky_box_rect));
+      EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
   EXPECT_EQ(IntRect(0, 0, 100, 100),
             EnclosingIntRect(sticky->ComputeStickyConstrainingRect()));
 }
@@ -233,18 +233,18 @@
   sticky->UpdateStickyPositionConstraints();
   ASSERT_EQ(scroller->Layer(), sticky->Layer()->AncestorScrollContainerLayer());
 
-  const StickyPositionScrollingConstraints* constraints =
+  const StickyPositionScrollingConstraints& constraints =
       scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
-  ASSERT_EQ(0.f, constraints->top_offset);
+  ASSERT_EQ(0.f, constraints.top_offset);
 
   // The coordinates of the constraint rects should all be with respect to the
   // unscrolled scroller.
   ASSERT_EQ(IntRect(15, 115, 170, 370),
             EnclosingIntRect(
-                constraints->scroll_container_relative_containing_block_rect));
+                constraints.scroll_container_relative_containing_block_rect));
   ASSERT_EQ(
       IntRect(15, 115, 100, 100),
-      EnclosingIntRect(constraints->scroll_container_relative_sticky_box_rect));
+      EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
 }
 
 // Verifies that the sticky constraints are correctly computed.
@@ -269,16 +269,16 @@
   sticky->UpdateStickyPositionConstraints();
   ASSERT_EQ(scroller->Layer(), sticky->Layer()->AncestorScrollContainerLayer());
 
-  const StickyPositionScrollingConstraints* constraints =
+  const StickyPositionScrollingConstraints& constraints =
       scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
-  ASSERT_EQ(0.f, constraints->top_offset);
+  ASSERT_EQ(0.f, constraints.top_offset);
 
   ASSERT_EQ(IntRect(25, 145, 200, 330),
             EnclosingIntRect(
-                constraints->scroll_container_relative_containing_block_rect));
+                constraints.scroll_container_relative_containing_block_rect));
   ASSERT_EQ(
       IntRect(25, 145, 100, 100),
-      EnclosingIntRect(constraints->scroll_container_relative_sticky_box_rect));
+      EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
 }
 
 // Verifies that the sticky constraints are correct when the sticky position
@@ -302,14 +302,14 @@
   sticky->UpdateStickyPositionConstraints();
   ASSERT_EQ(scroller->Layer(), sticky->Layer()->AncestorScrollContainerLayer());
 
-  const StickyPositionScrollingConstraints* constraints =
+  const StickyPositionScrollingConstraints& constraints =
       scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
   ASSERT_EQ(IntRect(0, 0, 400, 1100),
             EnclosingIntRect(
-                constraints->scroll_container_relative_containing_block_rect));
+                constraints.scroll_container_relative_containing_block_rect));
   ASSERT_EQ(
       IntRect(0, 0, 100, 100),
-      EnclosingIntRect(constraints->scroll_container_relative_sticky_box_rect));
+      EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
 }
 
 // Verifies that the sticky constraints are correct when the sticky position
@@ -336,14 +336,14 @@
   sticky->UpdateStickyPositionConstraints();
   ASSERT_EQ(scroller->Layer(), sticky->Layer()->AncestorScrollContainerLayer());
 
-  const StickyPositionScrollingConstraints* constraints =
+  const StickyPositionScrollingConstraints& constraints =
       scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
   ASSERT_EQ(IntRect(15, 115, 170, 370),
             EnclosingIntRect(
-                constraints->scroll_container_relative_containing_block_rect));
+                constraints.scroll_container_relative_containing_block_rect));
   ASSERT_EQ(
       IntRect(15, 165, 100, 100),
-      EnclosingIntRect(constraints->scroll_container_relative_sticky_box_rect));
+      EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
 }
 
 TEST_F(LayoutBoxModelObjectTest, StickyPositionTableContainers) {
@@ -363,14 +363,14 @@
   PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
   auto* sticky = GetLayoutBoxModelObjectByElementId("sticky");
   sticky->UpdateStickyPositionConstraints();
-  const StickyPositionScrollingConstraints* constraints =
+  const StickyPositionScrollingConstraints& constraints =
       scrollable_area->GetStickyConstraintsMap().at(sticky->Layer());
   EXPECT_EQ(IntRect(0, 0, 50, 100),
             EnclosingIntRect(
-                constraints->scroll_container_relative_containing_block_rect));
+                constraints.scroll_container_relative_containing_block_rect));
   EXPECT_EQ(
       IntRect(0, 50, 50, 50),
-      EnclosingIntRect(constraints->scroll_container_relative_sticky_box_rect));
+      EnclosingIntRect(constraints.scroll_container_relative_sticky_box_rect));
 }
 
 // Tests that when a non-layer changes size it invalidates the constraints for
@@ -400,14 +400,14 @@
       scrollable_area->GetStickyConstraintsMap().Contains(sticky->Layer()));
   EXPECT_EQ(25.f, scrollable_area->GetStickyConstraintsMap()
                       .at(sticky->Layer())
-                      ->scroll_container_relative_sticky_box_rect.X());
+                      .scroll_container_relative_sticky_box_rect.X());
   To<HTMLElement>(target->GetNode())->classList().Add("hide");
   // After updating layout we should have the updated position.
   GetDocument().View()->UpdateLifecycleToLayoutClean(
       DocumentUpdateReason::kTest);
   EXPECT_EQ(50.f, scrollable_area->GetStickyConstraintsMap()
                       .at(sticky->Layer())
-                      ->scroll_container_relative_sticky_box_rect.X());
+                      .scroll_container_relative_sticky_box_rect.X());
 }
 
 // Verifies that the correct sticky-box shifting ancestor is found when
@@ -458,19 +458,18 @@
 
   // The outer block element trivially has no sticky-box shifting ancestor.
   EXPECT_FALSE(constraints_map.at(sticky_outer_div)
-                   ->nearest_sticky_layer_shifting_sticky_box);
+                   .nearest_sticky_layer_shifting_sticky_box);
 
   // Neither does the outer inline element, as its parent element is also its
   // containing block.
   EXPECT_FALSE(constraints_map.at(sticky_outer_inline)
-                   ->nearest_sticky_layer_shifting_sticky_box);
+                   .nearest_sticky_layer_shifting_sticky_box);
 
   // However the inner inline element does have a sticky-box shifting ancestor,
   // as its containing block is the ancestor block element, above its ancestor
   // sticky element.
-  EXPECT_EQ(sticky_outer_inline,
-            constraints_map.at(sticky_inner_inline)
-                ->nearest_sticky_layer_shifting_sticky_box);
+  EXPECT_EQ(sticky_outer_inline, constraints_map.at(sticky_inner_inline)
+                                     .nearest_sticky_layer_shifting_sticky_box);
 }
 
 // Verifies that the correct containing-block shifting ancestor is found when
@@ -515,20 +514,16 @@
 
   // The outer <div> should not detect the scroller as its containing-block
   // shifting ancestor.
-  EXPECT_FALSE(constraints_map
-                   .at(sticky_parent)
-
-                   ->nearest_sticky_layer_shifting_containing_block);
+  EXPECT_FALSE(constraints_map.at(sticky_parent)
+                   .nearest_sticky_layer_shifting_containing_block);
 
   // Both inner children should detect the parent <div> as their
   // containing-block shifting ancestor. They skip past unanchored sticky
   // because it will never have a non-zero offset.
-  EXPECT_EQ(sticky_parent,
-            constraints_map.at(sticky_child)
-                ->nearest_sticky_layer_shifting_containing_block);
-  EXPECT_EQ(sticky_parent,
-            constraints_map.at(sticky_nested_child)
-                ->nearest_sticky_layer_shifting_containing_block);
+  EXPECT_EQ(sticky_parent, constraints_map.at(sticky_child)
+                               .nearest_sticky_layer_shifting_containing_block);
+  EXPECT_EQ(sticky_parent, constraints_map.at(sticky_nested_child)
+                               .nearest_sticky_layer_shifting_containing_block);
 }
 
 // Verifies that the correct containing-block shifting ancestor is found when
@@ -559,9 +554,8 @@
 
   // The grandchild sticky should detect the parent as its containing-block
   // shifting ancestor.
-  EXPECT_EQ(sticky_parent,
-            constraints_map.at(sticky_grandchild)
-                ->nearest_sticky_layer_shifting_containing_block);
+  EXPECT_EQ(sticky_parent, constraints_map.at(sticky_grandchild)
+                               .nearest_sticky_layer_shifting_containing_block);
 }
 
 // Verifies that the correct containing-block shifting ancestor is found when
@@ -594,7 +588,7 @@
   // The table cell should detect the outer <div> as its containing-block
   // shifting ancestor.
   EXPECT_EQ(sticky_outer, constraints_map.at(sticky_th)
-                              ->nearest_sticky_layer_shifting_containing_block);
+                              .nearest_sticky_layer_shifting_containing_block);
 }
 
 // Verifies that the calculated position:sticky offsets are correct when we have
@@ -988,9 +982,9 @@
 
   // The inner sticky should not detect the outer one as any sort of ancestor.
   EXPECT_FALSE(constraints_map.at(inner_sticky->Layer())
-                   ->nearest_sticky_layer_shifting_sticky_box);
+                   .nearest_sticky_layer_shifting_sticky_box);
   EXPECT_FALSE(constraints_map.at(inner_sticky->Layer())
-                   ->nearest_sticky_layer_shifting_containing_block);
+                   .nearest_sticky_layer_shifting_containing_block);
 
   // Scroll the page down.
   scrollable_area->ScrollToAbsolutePosition(
diff --git a/third_party/blink/renderer/core/layout/layout_button.cc b/third_party/blink/renderer/core/layout/layout_button.cc
index d75a3c8..00ed9a3 100644
--- a/third_party/blink/renderer/core/layout/layout_button.cc
+++ b/third_party/blink/renderer/core/layout/layout_button.cc
@@ -29,11 +29,6 @@
 
 LayoutButton::~LayoutButton() = default;
 
-void LayoutButton::Trace(Visitor* visitor) const {
-  visitor->Trace(inner_);
-  LayoutFlexibleBox::Trace(visitor);
-}
-
 void LayoutButton::AddChild(LayoutObject* new_child,
                             LayoutObject* before_child) {
   NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/layout_button.h b/third_party/blink/renderer/core/layout/layout_button.h
index a47f782..279451d0 100644
--- a/third_party/blink/renderer/core/layout/layout_button.h
+++ b/third_party/blink/renderer/core/layout/layout_button.h
@@ -35,7 +35,6 @@
  public:
   explicit LayoutButton(Element*);
   ~LayoutButton() override;
-  void Trace(Visitor*) const override;
 
   const char* GetName() const override {
     NOT_DESTROYED();
@@ -69,7 +68,7 @@
   void UpdateAnonymousChildStyle(const LayoutObject* child,
                                  ComputedStyle& child_style) const override;
 
-  Member<LayoutBlock> inner_;
+  LayoutBlock* inner_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_counter.cc b/third_party/blink/renderer/core/layout/layout_counter.cc
index 329f308..a51d17f5 100644
--- a/third_party/blink/renderer/core/layout/layout_counter.cc
+++ b/third_party/blink/renderer/core/layout/layout_counter.cc
@@ -45,8 +45,7 @@
 
 namespace blink {
 
-typedef HeapHashMap<WeakMember<const LayoutObject>, std::unique_ptr<CounterMap>>
-    CounterMaps;
+typedef HashMap<const LayoutObject*, std::unique_ptr<CounterMap>> CounterMaps;
 
 namespace {
 
@@ -56,9 +55,8 @@
 
 // See class definition as to why we have this map.
 CounterMaps& GetCounterMaps() {
-  DEFINE_STATIC_LOCAL(Persistent<CounterMaps>, static_counter_maps,
-                      (MakeGarbageCollected<CounterMaps>()));
-  return *static_counter_maps;
+  DEFINE_STATIC_LOCAL(CounterMaps, static_counter_maps, ());
+  return static_counter_maps;
 }
 
 Element* AncestorStyleContainmentObject(const Element& element) {
@@ -509,12 +507,6 @@
 
 LayoutCounter::~LayoutCounter() = default;
 
-void LayoutCounter::Trace(Visitor* visitor) const {
-  visitor->Trace(counter_);
-  visitor->Trace(next_for_same_counter_);
-  LayoutText::Trace(visitor);
-}
-
 void LayoutCounter::WillBeDestroyed() {
   NOT_DESTROYED();
   if (counter_node_) {
diff --git a/third_party/blink/renderer/core/layout/layout_counter.h b/third_party/blink/renderer/core/layout/layout_counter.h
index ae1f00c1..0d8b79c 100644
--- a/third_party/blink/renderer/core/layout/layout_counter.h
+++ b/third_party/blink/renderer/core/layout/layout_counter.h
@@ -55,7 +55,6 @@
  public:
   LayoutCounter(PseudoElement&, const CounterContentData&);
   ~LayoutCounter() override;
-  void Trace(Visitor*) const override;
 
   // These functions are static so that any LayoutObject can call them.
   // The reason is that any LayoutObject in the tree can have a CounterNode
@@ -93,9 +92,9 @@
   // changes.
   void Invalidate();
 
-  Member<const CounterContentData> counter_;
+  Persistent<const CounterContentData> counter_;
   CounterNode* counter_node_;
-  Member<LayoutCounter> next_for_same_counter_;
+  LayoutCounter* next_for_same_counter_;
   friend class CounterNode;
 };
 
diff --git a/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.cc b/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.cc
index 032403b..ef5e3bb 100644
--- a/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.cc
+++ b/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.cc
@@ -85,8 +85,7 @@
     CustomScrollbar* scrollbar,
     ScrollbarPart part) {
   LayoutCustomScrollbarPart* layout_object =
-      MakeGarbageCollected<LayoutCustomScrollbarPart>(scrollable_area,
-                                                      scrollbar, part);
+      new LayoutCustomScrollbarPart(scrollable_area, scrollbar, part);
   RecordScrollbarPartStats(*document, part);
   layout_object->SetDocumentForAnonymous(document);
   return layout_object;
diff --git a/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h b/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h
index 2d7dbfa..cb2a7ce 100644
--- a/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h
+++ b/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h
@@ -79,9 +79,9 @@
     return scrollable_area_;
   }
 
+ private:
   LayoutCustomScrollbarPart(ScrollableArea*, CustomScrollbar*, ScrollbarPart);
 
- private:
   void UpdateFromStyle() override;
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
   void ImageChanged(WrappedImagePtr, CanDeferInvalidation) override;
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_content.cc b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
index 3e9ba68..cb2f706 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_content.cc
+++ b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
@@ -44,11 +44,21 @@
 namespace blink {
 
 LayoutEmbeddedContent::LayoutEmbeddedContent(HTMLFrameOwnerElement* element)
-    : LayoutReplaced(element) {
+    : LayoutReplaced(element),
+      // Reference counting is used to prevent the part from being destroyed
+      // while inside the EmbeddedContentView code, which might not be able to
+      // handle that.
+      ref_count_(1) {
   DCHECK(element);
   SetInline(false);
 }
 
+void LayoutEmbeddedContent::Release() {
+  NOT_DESTROYED();
+  if (--ref_count_ <= 0)
+    delete this;
+}
+
 void LayoutEmbeddedContent::WillBeDestroyed() {
   NOT_DESTROYED();
   if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
@@ -58,8 +68,26 @@
     frame_owner->SetEmbeddedContentView(nullptr);
 
   LayoutReplaced::WillBeDestroyed();
+}
 
+void LayoutEmbeddedContent::DeleteThis() {
+  NOT_DESTROYED();
+  // We call clearNode here because LayoutEmbeddedContent is ref counted. This
+  // call to destroy may not actually destroy the layout object. We can keep it
+  // around because of references from the LocalFrameView class. (The actual
+  // destruction of the class happens in PostDestroy() which is called from
+  // Release()).
+  //
+  // But, we've told the system we've destroyed the layoutObject, which happens
+  // when the DOM node is destroyed. So there is a good chance the DOM node this
+  // object points too is invalid, so we have to clear the node so we make sure
+  // we don't access it in the future.
   ClearNode();
+  Release();
+}
+
+LayoutEmbeddedContent::~LayoutEmbeddedContent() {
+  DCHECK_LE(ref_count_, 0);
 }
 
 FrameView* LayoutEmbeddedContent::ChildFrameView() const {
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_content.h b/third_party/blink/renderer/core/layout/layout_embedded_content.h
index 25d12d8..fc5b7c8 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_content.h
+++ b/third_party/blink/renderer/core/layout/layout_embedded_content.h
@@ -42,6 +42,7 @@
 class CORE_EXPORT LayoutEmbeddedContent : public LayoutReplaced {
  public:
   explicit LayoutEmbeddedContent(HTMLFrameOwnerElement*);
+  ~LayoutEmbeddedContent() override;
 
   bool ContentDocumentContainsGraphicsLayer() const;
 
@@ -50,6 +51,12 @@
                    const PhysicalOffset& accumulated_offset,
                    HitTestAction) override;
 
+  void AddRef() {
+    NOT_DESTROYED();
+    ++ref_count_;
+  }
+  void Release();
+
   // LayoutEmbeddedContent::ChildFrameView returns the LocalFrameView associated
   // with the current Node, if Node is HTMLFrameOwnerElement. This is different
   // to LayoutObject::GetFrameView which returns the LocalFrameView associated
@@ -98,12 +105,15 @@
   CompositingReasons AdditionalCompositingReasons() const override;
 
   void WillBeDestroyed() final;
+  void DeleteThis() final;
 
   bool NodeAtPointOverEmbeddedContentView(
       HitTestResult&,
       const HitTestLocation&,
       const PhysicalOffset& accumulated_offset,
       HitTestAction);
+
+  int ref_count_;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_content_test.cc b/third_party/blink/renderer/core/layout/layout_embedded_content_test.cc
new file mode 100644
index 0000000..4a0d2c0
--- /dev/null
+++ b/third_party/blink/renderer/core/layout/layout_embedded_content_test.cc
@@ -0,0 +1,25 @@
+// 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.
+
+#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/html/html_element.h"
+#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+
+namespace blink {
+
+class LayoutEmbeddedContentTest : public RenderingTest {};
+
+class OverriddenLayoutEmbeddedContent : public LayoutEmbeddedContent {
+ public:
+  explicit OverriddenLayoutEmbeddedContent(HTMLFrameOwnerElement* element)
+      : LayoutEmbeddedContent(element) {}
+
+  const char* GetName() const override {
+    return "OverriddenLayoutEmbeddedContent";
+  }
+};
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
index aebfd153..7fa9dcf 100644
--- a/third_party/blink/renderer/core/layout/layout_flexible_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
@@ -71,12 +71,6 @@
 
 LayoutFlexibleBox::~LayoutFlexibleBox() = default;
 
-void LayoutFlexibleBox::Trace(Visitor* visitor) const {
-  visitor->Trace(intrinsic_size_along_main_axis_);
-  visitor->Trace(relaid_out_children_);
-  LayoutBlock::Trace(visitor);
-}
-
 bool LayoutFlexibleBox::IsChildAllowed(LayoutObject* object,
                                        const ComputedStyle& style) const {
   NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.h b/third_party/blink/renderer/core/layout/layout_flexible_box.h
index ac8374c..3caa818b 100644
--- a/third_party/blink/renderer/core/layout/layout_flexible_box.h
+++ b/third_party/blink/renderer/core/layout/layout_flexible_box.h
@@ -47,7 +47,6 @@
  public:
   explicit LayoutFlexibleBox(Element*);
   ~LayoutFlexibleBox() override;
-  void Trace(Visitor*) const override;
 
   const char* GetName() const override {
     NOT_DESTROYED();
@@ -238,15 +237,14 @@
 
   // This is used to cache the preferred size for orthogonal flow children so we
   // don't have to relayout to get it
-  HeapHashMap<Member<const LayoutObject>, LayoutUnit>
-      intrinsic_size_along_main_axis_;
+  HashMap<const LayoutObject*, LayoutUnit> intrinsic_size_along_main_axis_;
 
   // This set is used to keep track of which children we laid out in this
   // current layout iteration. We need it because the ones in this set may
   // need an additional layout pass for correct stretch alignment handling, as
   // the first layout likely did not use the correct value for percentage
   // sizing of children.
-  HeapHashSet<Member<const LayoutObject>> relaid_out_children_;
+  HashSet<const LayoutObject*> relaid_out_children_;
 
   mutable OrderIterator order_iterator_;
   int number_of_in_flow_children_on_first_line_;
diff --git a/third_party/blink/renderer/core/layout/layout_flow_thread.cc b/third_party/blink/renderer/core/layout/layout_flow_thread.cc
index a782737..e2cd563 100644
--- a/third_party/blink/renderer/core/layout/layout_flow_thread.cc
+++ b/third_party/blink/renderer/core/layout/layout_flow_thread.cc
@@ -40,11 +40,6 @@
       page_logical_size_changed_(false),
       needs_paint_layer_(needs_paint_layer) {}
 
-void LayoutFlowThread::Trace(Visitor* visitor) const {
-  visitor->Trace(multi_column_set_list_);
-  LayoutBlockFlow::Trace(visitor);
-}
-
 LayoutFlowThread* LayoutFlowThread::LocateFlowThreadContainingBlockOf(
     const LayoutObject& descendant,
     AncestorSearchConstraint constraint) {
@@ -263,7 +258,7 @@
   // manually managing the tree nodes lifecycle.
   multi_column_set_interval_tree_.Clear();
   multi_column_set_interval_tree_.InitIfNeeded();
-  for (const auto& column_set : multi_column_set_list_)
+  for (auto* column_set : multi_column_set_list_)
     multi_column_set_interval_tree_.Add(
         MultiColumnSetIntervalTree::CreateInterval(
             column_set->LogicalTopInFlowThread(),
@@ -288,7 +283,7 @@
   DCHECK(!column_sets_invalidated_);
 
   LayoutRect result;
-  for (const auto& column_set : multi_column_set_list_)
+  for (auto* column_set : multi_column_set_list_)
     result.Unite(column_set->FragmentsBoundingBox(layer_bounding_box));
 
   return result;
diff --git a/third_party/blink/renderer/core/layout/layout_flow_thread.h b/third_party/blink/renderer/core/layout/layout_flow_thread.h
index e8bf7e59..10d05d7 100644
--- a/third_party/blink/renderer/core/layout/layout_flow_thread.h
+++ b/third_party/blink/renderer/core/layout/layout_flow_thread.h
@@ -39,8 +39,7 @@
 
 class LayoutMultiColumnSet;
 
-typedef HeapLinkedHashSet<Member<LayoutMultiColumnSet>>
-    LayoutMultiColumnSetList;
+typedef LinkedHashSet<LayoutMultiColumnSet*> LayoutMultiColumnSetList;
 
 // Layout state for multicol. To be stored when laying out a block child, so
 // that we can roll back to the initial state if we need to re-lay out said
@@ -56,7 +55,7 @@
       : column_set_(column_set) {}
   LayoutMultiColumnSet* ColumnSet() const { return column_set_; }
 
-  UntracedMember<LayoutMultiColumnSet> column_set_;
+  LayoutMultiColumnSet* column_set_;
 };
 
 // LayoutFlowThread is used to collect all the layout objects that participate
@@ -68,7 +67,6 @@
  public:
   explicit LayoutFlowThread(bool needs_paint_layer);
   ~LayoutFlowThread() override = default;
-  void Trace(Visitor*) const override;
 
   bool IsLayoutFlowThread() const final {
     NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/layout_frame_set.cc b/third_party/blink/renderer/core/layout/layout_frame_set.cc
index e4e5448..d26607e 100644
--- a/third_party/blink/renderer/core/layout/layout_frame_set.cc
+++ b/third_party/blink/renderer/core/layout/layout_frame_set.cc
@@ -55,11 +55,6 @@
 
 LayoutFrameSet::~LayoutFrameSet() = default;
 
-void LayoutFrameSet::Trace(Visitor* visitor) const {
-  visitor->Trace(children_);
-  LayoutBox::Trace(visitor);
-}
-
 LayoutFrameSet::GridAxis::GridAxis() : split_being_resized_(kNoSplit) {}
 
 HTMLFrameSetElement* LayoutFrameSet::FrameSet() const {
diff --git a/third_party/blink/renderer/core/layout/layout_frame_set.h b/third_party/blink/renderer/core/layout/layout_frame_set.h
index 1853c4b..a0406768 100644
--- a/third_party/blink/renderer/core/layout/layout_frame_set.h
+++ b/third_party/blink/renderer/core/layout/layout_frame_set.h
@@ -67,7 +67,6 @@
  public:
   LayoutFrameSet(HTMLFrameSetElement*);
   ~LayoutFrameSet() override;
-  void Trace(Visitor*) const override;
 
   LayoutObject* FirstChild() const {
     NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/layout_grid.cc b/third_party/blink/renderer/core/layout/layout_grid.cc
index ead4acb4..60d2e83 100644
--- a/third_party/blink/renderer/core/layout/layout_grid.cc
+++ b/third_party/blink/renderer/core/layout/layout_grid.cc
@@ -54,14 +54,8 @@
 
 LayoutGrid::~LayoutGrid() = default;
 
-void LayoutGrid::Trace(Visitor* visitor) const {
-  visitor->Trace(column_of_positioned_item_);
-  visitor->Trace(row_of_positioned_item_);
-  LayoutBlock::Trace(visitor);
-}
-
 LayoutGrid* LayoutGrid::CreateAnonymous(Document* document) {
-  LayoutGrid* layout_grid = MakeGarbageCollected<LayoutGrid>(nullptr);
+  LayoutGrid* layout_grid = new LayoutGrid(nullptr);
   layout_grid->SetDocumentForAnonymous(document);
   return layout_grid;
 }
@@ -871,8 +865,8 @@
   DCHECK(!grid.HasGridItems());
   PopulateExplicitGridAndOrderIterator(grid);
 
-  HeapVector<Member<LayoutBox>> auto_major_axis_auto_grid_items;
-  HeapVector<Member<LayoutBox>> specified_major_axis_auto_grid_items;
+  Vector<LayoutBox*> auto_major_axis_auto_grid_items;
+  Vector<LayoutBox*> specified_major_axis_auto_grid_items;
 #if DCHECK_IS_ON()
   DCHECK(!grid.HasAnyGridItemPaintOrder());
 #endif
@@ -1082,7 +1076,7 @@
 
 void LayoutGrid::PlaceSpecifiedMajorAxisItemsOnGrid(
     Grid& grid,
-    const HeapVector<Member<LayoutBox>>& auto_grid_items) const {
+    const Vector<LayoutBox*>& auto_grid_items) const {
   NOT_DESTROYED();
   bool is_for_columns = AutoPlacementMajorAxisDirection() == kForColumns;
   bool is_grid_auto_flow_dense = StyleRef().IsGridAutoFlowAlgorithmDense();
@@ -1095,7 +1089,7 @@
           WTF::UnsignedWithZeroKeyHashTraits<unsigned>>
       minor_axis_cursors;
 
-  for (const auto& auto_grid_item : auto_grid_items) {
+  for (auto* const auto_grid_item : auto_grid_items) {
     GridSpan major_axis_positions =
         grid.GridItemSpan(*auto_grid_item, AutoPlacementMajorAxisDirection());
     DCHECK(major_axis_positions.IsTranslatedDefinite());
@@ -1128,12 +1122,12 @@
 
 void LayoutGrid::PlaceAutoMajorAxisItemsOnGrid(
     Grid& grid,
-    const HeapVector<Member<LayoutBox>>& auto_grid_items) const {
+    const Vector<LayoutBox*>& auto_grid_items) const {
   NOT_DESTROYED();
   std::pair<size_t, size_t> auto_placement_cursor = std::make_pair(0, 0);
   bool is_grid_auto_flow_dense = StyleRef().IsGridAutoFlowAlgorithmDense();
 
-  for (const auto& auto_grid_item : auto_grid_items) {
+  for (auto* const auto_grid_item : auto_grid_items) {
     PlaceAutoMajorAxisItemOnGrid(grid, *auto_grid_item, auto_placement_cursor);
 
     // If grid-auto-flow is dense, reset auto-placement cursor.
@@ -1431,7 +1425,7 @@
   if (!positioned_descendants)
     return;
 
-  for (const auto& child : *positioned_descendants) {
+  for (auto* child : *positioned_descendants) {
     LayoutUnit column_breadth =
         GridAreaBreadthForOutOfFlowChild(*child, kForColumns);
     LayoutUnit row_breadth = GridAreaBreadthForOutOfFlowChild(*child, kForRows);
diff --git a/third_party/blink/renderer/core/layout/layout_grid.h b/third_party/blink/renderer/core/layout/layout_grid.h
index 8d879e1..7f916439 100644
--- a/third_party/blink/renderer/core/layout/layout_grid.h
+++ b/third_party/blink/renderer/core/layout/layout_grid.h
@@ -57,7 +57,6 @@
  public:
   explicit LayoutGrid(Element*);
   ~LayoutGrid() override;
-  void Trace(Visitor*) const override;
 
   static LayoutGrid* CreateAnonymous(Document*);
   const char* GetName() const override {
@@ -196,12 +195,9 @@
       const LayoutBox&,
       GridTrackSizingDirection,
       const GridSpan& specified_positions) const;
-  void PlaceSpecifiedMajorAxisItemsOnGrid(
-      Grid&,
-      const HeapVector<Member<LayoutBox>>&) const;
-  void PlaceAutoMajorAxisItemsOnGrid(
-      Grid&,
-      const HeapVector<Member<LayoutBox>>&) const;
+  void PlaceSpecifiedMajorAxisItemsOnGrid(Grid&,
+                                          const Vector<LayoutBox*>&) const;
+  void PlaceAutoMajorAxisItemsOnGrid(Grid&, const Vector<LayoutBox*>&) const;
   void PlaceAutoMajorAxisItemOnGrid(
       Grid&,
       LayoutBox&,
@@ -333,7 +329,7 @@
   ContentAlignmentData offset_between_columns_;
   ContentAlignmentData offset_between_rows_;
 
-  typedef HeapHashMap<Member<const LayoutBox>, base::Optional<size_t>>
+  typedef HashMap<const LayoutBox*, base::Optional<size_t>>
       OutOfFlowPositionsMap;
   OutOfFlowPositionsMap column_of_positioned_item_;
   OutOfFlowPositionsMap row_of_positioned_item_;
diff --git a/third_party/blink/renderer/core/layout/layout_image.cc b/third_party/blink/renderer/core/layout/layout_image.cc
index ec32280..4e2fb9a 100644
--- a/third_party/blink/renderer/core/layout/layout_image.cc
+++ b/third_party/blink/renderer/core/layout/layout_image.cc
@@ -59,18 +59,13 @@
       image_device_pixel_ratio_(1.0f) {}
 
 LayoutImage* LayoutImage::CreateAnonymous(PseudoElement& pseudo) {
-  LayoutImage* image = MakeGarbageCollected<LayoutImage>(nullptr);
+  LayoutImage* image = new LayoutImage(nullptr);
   image->SetDocumentForAnonymous(&pseudo.GetDocument());
   return image;
 }
 
 LayoutImage::~LayoutImage() = default;
 
-void LayoutImage::Trace(Visitor* visitor) const {
-  visitor->Trace(image_resource_);
-  LayoutReplaced::Trace(visitor);
-}
-
 void LayoutImage::WillBeDestroyed() {
   NOT_DESTROYED();
   DCHECK(image_resource_);
diff --git a/third_party/blink/renderer/core/layout/layout_image.h b/third_party/blink/renderer/core/layout/layout_image.h
index bccd0f19..ff27e25b 100644
--- a/third_party/blink/renderer/core/layout/layout_image.h
+++ b/third_party/blink/renderer/core/layout/layout_image.h
@@ -50,7 +50,6 @@
  public:
   LayoutImage(Element*);
   ~LayoutImage() override;
-  void Trace(Visitor*) const override;
 
   static LayoutImage* CreateAnonymous(PseudoElement&);
 
@@ -174,7 +173,7 @@
   // * For generated content, the resource is loaded during style resolution
   // and thus is stored in ComputedStyle (see ContentData::image) that gets
   // propagated to the anonymous LayoutImage in LayoutObject::createObject.
-  Member<LayoutImageResource> image_resource_;
+  Persistent<LayoutImageResource> image_resource_;
   bool did_increment_visually_non_empty_pixel_count_;
 
   // This field stores whether this image is generated with 'content'.
diff --git a/third_party/blink/renderer/core/layout/layout_image_resource.cc b/third_party/blink/renderer/core/layout/layout_image_resource.cc
index 7c441d5..62774f0 100644
--- a/third_party/blink/renderer/core/layout/layout_image_resource.cc
+++ b/third_party/blink/renderer/core/layout/layout_image_resource.cc
@@ -43,11 +43,6 @@
 
 LayoutImageResource::~LayoutImageResource() = default;
 
-void LayoutImageResource::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_object_);
-  visitor->Trace(cached_image_);
-}
-
 void LayoutImageResource::Initialize(LayoutObject* layout_object) {
   DCHECK(!layout_object_);
   DCHECK(layout_object);
@@ -126,7 +121,7 @@
   }
   if (layout_object_ && layout_object_->IsLayoutImage() && size.Width() &&
       size.Height())
-    size.Scale(To<LayoutImage>(layout_object_.Get())->ImageDevicePixelRatio());
+    size.Scale(To<LayoutImage>(layout_object_)->ImageDevicePixelRatio());
   return size;
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_image_resource.h b/third_party/blink/renderer/core/layout/layout_image_resource.h
index bdec915b..f8ce0b4 100644
--- a/third_party/blink/renderer/core/layout/layout_image_resource.h
+++ b/third_party/blink/renderer/core/layout/layout_image_resource.h
@@ -42,7 +42,6 @@
   LayoutImageResource(const LayoutImageResource&) = delete;
   LayoutImageResource& operator=(const LayoutImageResource&) = delete;
   virtual ~LayoutImageResource();
-  virtual void Trace(Visitor* visitor) const;
 
   virtual void Initialize(LayoutObject*);
   virtual void Shutdown();
@@ -73,13 +72,15 @@
   virtual RespectImageOrientationEnum ImageOrientation() const;
   virtual WrappedImagePtr ImagePtr() const { return cached_image_.Get(); }
 
+  virtual void Trace(Visitor* visitor) const { visitor->Trace(cached_image_); }
+
  protected:
   // Device scale factor for the associated LayoutObject.
   float DeviceScaleFactor() const;
   // Returns an image based on the passed device scale factor.
   static Image* BrokenImage(float device_scale_factor);
 
-  Member<LayoutObject> layout_object_;
+  LayoutObject* layout_object_;
   Member<ImageResourceContent> cached_image_;
 };
 
diff --git a/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc b/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc
index 8044069..ac6e978e7 100644
--- a/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc
+++ b/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc
@@ -73,8 +73,7 @@
   // TODO(davve): Find out the correct default object size in this context.
   FloatSize default_size =
       layout_object_->IsListMarkerImage()
-          ? FloatSize(
-                To<LayoutListMarkerImage>(layout_object_.Get())->DefaultSize())
+          ? FloatSize(To<LayoutListMarkerImage>(layout_object_)->DefaultSize())
           : FloatSize(LayoutReplaced::kDefaultWidth,
                       LayoutReplaced::kDefaultHeight);
   return ImageSizeWithDefaultSize(multiplier, default_size);
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc
index 332921b..f9e0906 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.cc
+++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -73,7 +73,6 @@
   ~SameSizeAsLayoutInline() override = default;
   LayoutObjectChildList children_;
   LineBoxList line_boxes_;
-  wtf_size_t first_fragment_item_index_;
 };
 
 ASSERT_SIZE(LayoutInline, SameSizeAsLayoutInline);
@@ -83,14 +82,15 @@
   SetChildrenInline(true);
 }
 
-void LayoutInline::Trace(Visitor* visitor) const {
-  visitor->Trace(children_);
-  visitor->Trace(line_boxes_);
-  LayoutBoxModelObject::Trace(visitor);
+LayoutInline::~LayoutInline() {
+#if DCHECK_IS_ON()
+  if (!IsInLayoutNGInlineFormattingContext())
+    line_boxes_.AssertIsEmpty();
+#endif
 }
 
 LayoutInline* LayoutInline::CreateAnonymous(Document* document) {
-  LayoutInline* layout_inline = MakeGarbageCollected<LayoutInline>(nullptr);
+  LayoutInline* layout_inline = new LayoutInline(nullptr);
   layout_inline->SetDocumentForAnonymous(document);
   return layout_inline;
 }
@@ -137,11 +137,6 @@
   DeleteLineBoxes();
 
   LayoutBoxModelObject::WillBeDestroyed();
-
-#if DCHECK_IS_ON()
-  if (!IsInLayoutNGInlineFormattingContext())
-    line_boxes_.AssertIsEmpty();
-#endif
 }
 
 void LayoutInline::DeleteLineBoxes() {
@@ -231,7 +226,8 @@
         InFlowPositionedInlineAncestor(block_flow->InlineElementContinuation()))
       continue;
 
-    ComputedStyle* new_block_style = ComputedStyle::Clone(block->StyleRef());
+    scoped_refptr<ComputedStyle> new_block_style =
+        ComputedStyle::Clone(block->StyleRef());
     new_block_style->SetPosition(new_style.GetPosition());
     block->SetStyle(new_block_style);
   }
@@ -542,7 +538,7 @@
 LayoutInline* LayoutInline::Clone() const {
   NOT_DESTROYED();
   DCHECK(!IsAnonymous());
-  LayoutInline* clone_inline = MakeGarbageCollected<LayoutInline>(GetNode());
+  LayoutInline* clone_inline = new LayoutInline(GetNode());
   clone_inline->SetStyle(Style());
   clone_inline->SetIsInsideFlowThread(IsInsideFlowThread());
   return clone_inline;
@@ -579,7 +575,7 @@
   // limit. This *will* result in incorrect rendering, but the alternative is to
   // hang forever.
   const unsigned kCMaxSplitDepth = 200;
-  HeapVector<Member<LayoutInline>> inlines_to_clone;
+  Vector<LayoutInline*> inlines_to_clone;
   LayoutInline* top_most_inline = this;
   for (LayoutObject* o = this; o != from_block; o = o->Parent()) {
     if (o->IsLayoutNGInsideListMarker())
@@ -727,7 +723,7 @@
   // hold |newChild|. We then make that block box a continuation of this
   // inline. We take all of the children after |beforeChild| and put them in a
   // clone of this object.
-  ComputedStyle* new_style =
+  scoped_refptr<ComputedStyle> new_style =
       GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
           StyleRef(), EDisplay::kBlock);
   const LayoutBlock* containing_block = ContainingBlock();
@@ -1657,7 +1653,7 @@
 
 InlineFlowBox* LayoutInline::CreateInlineFlowBox() {
   NOT_DESTROYED();
-  return MakeGarbageCollected<InlineFlowBox>(LineLayoutItem(this));
+  return new InlineFlowBox(LineLayoutItem(this));
 }
 
 InlineFlowBox* LayoutInline::CreateAndAppendInlineFlowBox() {
diff --git a/third_party/blink/renderer/core/layout/layout_inline.h b/third_party/blink/renderer/core/layout/layout_inline.h
index e16ebf9..a514b960 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.h
+++ b/third_party/blink/renderer/core/layout/layout_inline.h
@@ -116,7 +116,7 @@
  public:
   explicit LayoutInline(Element*);
 
-  void Trace(Visitor*) const override;
+  ~LayoutInline() override;
 
   static LayoutInline* CreateAnonymous(Document*);
 
@@ -453,16 +453,17 @@
 
   LayoutObjectChildList children_;
 
-  // All of the line boxes created for this inline flow. For example,
-  // <i>Hello<br>world.</i> will have two <i> line boxes.
-  // Valid only when !IsInLayoutNGInlineFormattingContext().
-  LineBoxList line_boxes_;
-
-  // The index of the first fragment item associated with this object in
-  // |NGFragmentItems::Items()|. Zero means there are no such item.
-  // Valid only when IsInLayoutNGInlineFormattingContext().
-  wtf_size_t first_fragment_item_index_ = 0u;
+  union {
+    // All of the line boxes created for this inline flow. For example,
+    // <i>Hello<br>world.</i> will have two <i> line boxes.
+    // Valid only when !IsInLayoutNGInlineFormattingContext().
+    LineBoxList line_boxes_;
+    // The index of the first fragment item associated with this object in
+    // |NGFragmentItems::Items()|. Zero means there are no such item.
+    // Valid only when IsInLayoutNGInlineFormattingContext().
+    wtf_size_t first_fragment_item_index_;
   };
+};
 
 inline LineBoxList* LayoutInline::MutableLineBoxes() {
   CHECK(!IsInLayoutNGInlineFormattingContext());
diff --git a/third_party/blink/renderer/core/layout/layout_list_item.cc b/third_party/blink/renderer/core/layout/layout_list_item.cc
index 6f2c25bc..5cd7442 100644
--- a/third_party/blink/renderer/core/layout/layout_list_item.cc
+++ b/third_party/blink/renderer/core/layout/layout_list_item.cc
@@ -230,7 +230,8 @@
   if (layout_object.StyleRef().LogicalHeight() == height)
     return;
 
-  ComputedStyle* new_style = ComputedStyle::Clone(layout_object.StyleRef());
+  scoped_refptr<ComputedStyle> new_style =
+      ComputedStyle::Clone(layout_object.StyleRef());
   new_style->SetLogicalHeight(height);
   layout_object.SetModifiedStyleOutsideStyleRecalc(
       std::move(new_style), LayoutObject::ApplyStyleChanges::kNo);
diff --git a/third_party/blink/renderer/core/layout/layout_list_marker.cc b/third_party/blink/renderer/core/layout/layout_list_marker.cc
index f3528ed8..4cbdc40 100644
--- a/third_party/blink/renderer/core/layout/layout_list_marker.cc
+++ b/third_party/blink/renderer/core/layout/layout_list_marker.cc
@@ -46,11 +46,6 @@
 
 LayoutListMarker::~LayoutListMarker() = default;
 
-void LayoutListMarker::Trace(Visitor* visitor) const {
-  visitor->Trace(image_);
-  LayoutBox::Trace(visitor);
-}
-
 void LayoutListMarker::WillBeDestroyed() {
   NOT_DESTROYED();
   if (image_)
diff --git a/third_party/blink/renderer/core/layout/layout_list_marker.h b/third_party/blink/renderer/core/layout/layout_list_marker.h
index 85b6140..6042c09 100644
--- a/third_party/blink/renderer/core/layout/layout_list_marker.h
+++ b/third_party/blink/renderer/core/layout/layout_list_marker.h
@@ -40,7 +40,6 @@
  public:
   explicit LayoutListMarker(Element*);
   ~LayoutListMarker() override;
-  void Trace(Visitor*) const override;
 
   // Marker text without suffix, e.g. "1".
   const String& GetText() const {
@@ -121,7 +120,7 @@
   void CounterStyleChanged();
 
   String text_;
-  Member<StyleImage> image_;
+  Persistent<StyleImage> image_;
   LayoutUnit list_item_inline_start_offset_;
 };
 
diff --git a/third_party/blink/renderer/core/layout/layout_list_marker_image.cc b/third_party/blink/renderer/core/layout/layout_list_marker_image.cc
index 1e4b39c..787137d 100644
--- a/third_party/blink/renderer/core/layout/layout_list_marker_image.cc
+++ b/third_party/blink/renderer/core/layout/layout_list_marker_image.cc
@@ -15,8 +15,7 @@
 
 LayoutListMarkerImage* LayoutListMarkerImage::CreateAnonymous(
     Document* document) {
-  LayoutListMarkerImage* object =
-      MakeGarbageCollected<LayoutListMarkerImage>(nullptr);
+  LayoutListMarkerImage* object = new LayoutListMarkerImage(nullptr);
   object->SetDocumentForAnonymous(document);
   return object;
 }
diff --git a/third_party/blink/renderer/core/layout/layout_media.cc b/third_party/blink/renderer/core/layout/layout_media.cc
index 356800e..3a1b85f 100644
--- a/third_party/blink/renderer/core/layout/layout_media.cc
+++ b/third_party/blink/renderer/core/layout/layout_media.cc
@@ -42,11 +42,6 @@
 
 LayoutMedia::~LayoutMedia() = default;
 
-void LayoutMedia::Trace(Visitor* visitor) const {
-  visitor->Trace(children_);
-  LayoutImage::Trace(visitor);
-}
-
 HTMLMediaElement* LayoutMedia::MediaElement() const {
   NOT_DESTROYED();
   return To<HTMLMediaElement>(GetNode());
diff --git a/third_party/blink/renderer/core/layout/layout_media.h b/third_party/blink/renderer/core/layout/layout_media.h
index e76d427..d0559c7 100644
--- a/third_party/blink/renderer/core/layout/layout_media.h
+++ b/third_party/blink/renderer/core/layout/layout_media.h
@@ -37,7 +37,6 @@
  public:
   explicit LayoutMedia(HTMLMediaElement*);
   ~LayoutMedia() override;
-  void Trace(Visitor*) const override;
 
   LayoutObject* FirstChild() const {
     NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc b/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc
index 4ad1695..01ca4bd 100644
--- a/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc
+++ b/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc
@@ -50,17 +50,12 @@
 
 LayoutMultiColumnFlowThread::~LayoutMultiColumnFlowThread() = default;
 
-void LayoutMultiColumnFlowThread::Trace(Visitor* visitor) const {
-  visitor->Trace(last_set_worked_on_);
-  LayoutFlowThread::Trace(visitor);
-}
-
 LayoutMultiColumnFlowThread* LayoutMultiColumnFlowThread::CreateAnonymous(
     Document& document,
     const ComputedStyle& parent_style,
     bool needs_paint_layer) {
   LayoutMultiColumnFlowThread* layout_object =
-      MakeGarbageCollected<LayoutMultiColumnFlowThread>(needs_paint_layer);
+      new LayoutMultiColumnFlowThread(needs_paint_layer);
   layout_object->SetDocumentForAnonymous(&document);
   layout_object->SetStyle(
       document.GetStyleResolver().CreateAnonymousStyleWithDisplay(
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h b/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h
index a23afee8d..e0092b63 100644
--- a/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h
+++ b/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h
@@ -146,7 +146,6 @@
       public FragmentationContext {
  public:
   ~LayoutMultiColumnFlowThread() override;
-  void Trace(Visitor*) const override;
 
   static LayoutMultiColumnFlowThread* CreateAnonymous(
       Document&,
@@ -326,11 +325,8 @@
     return "LayoutMultiColumnFlowThread";
   }
 
-  // Note: We call this constructor only in |CreateAnonymous()|, but mark this
-  // "public" for |MakeGarbageCollected<T>|.
-  explicit LayoutMultiColumnFlowThread(bool needs_paint_layer);
-
  private:
+  explicit LayoutMultiColumnFlowThread(bool needs_paint_layer);
   void UpdateLayout() override;
 
   void CalculateColumnHeightAvailable();
@@ -373,7 +369,7 @@
   // concept of a "current set" is difficult, since layout may jump back and
   // forth in the tree, due to wrong top location estimates (due to e.g. margin
   // collapsing), and possibly for other reasons.
-  Member<LayoutMultiColumnSet> last_set_worked_on_;
+  LayoutMultiColumnSet* last_set_worked_on_;
 
 #if DCHECK_IS_ON()
   // Used to check consistency between calls to
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_set.cc b/third_party/blink/renderer/core/layout/layout_multi_column_set.cc
index e918c7bb..759996e 100644
--- a/third_party/blink/renderer/core/layout/layout_multi_column_set.cc
+++ b/third_party/blink/renderer/core/layout/layout_multi_column_set.cc
@@ -44,8 +44,7 @@
     LayoutFlowThread& flow_thread,
     const ComputedStyle& parent_style) {
   Document& document = flow_thread.GetDocument();
-  LayoutMultiColumnSet* layout_object =
-      MakeGarbageCollected<LayoutMultiColumnSet>(&flow_thread);
+  LayoutMultiColumnSet* layout_object = new LayoutMultiColumnSet(&flow_thread);
   layout_object->SetDocumentForAnonymous(&document);
   layout_object->SetStyle(
       document.GetStyleResolver().CreateAnonymousStyleWithDisplay(
@@ -53,11 +52,6 @@
   return layout_object;
 }
 
-void LayoutMultiColumnSet::Trace(Visitor* visitor) const {
-  visitor->Trace(flow_thread_);
-  LayoutBlockFlow::Trace(visitor);
-}
-
 unsigned LayoutMultiColumnSet::FragmentainerGroupIndexAtFlowThreadOffset(
     LayoutUnit flow_thread_offset,
     PageBoundaryRule rule) const {
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_set.h b/third_party/blink/renderer/core/layout/layout_multi_column_set.h
index 07a8592..302d308 100644
--- a/third_party/blink/renderer/core/layout/layout_multi_column_set.h
+++ b/third_party/blink/renderer/core/layout/layout_multi_column_set.h
@@ -69,8 +69,6 @@
       LayoutFlowThread&,
       const ComputedStyle& parent_style);
 
-  void Trace(Visitor*) const override;
-
   const MultiColumnFragmentainerGroup& FirstFragmentainerGroup() const {
     NOT_DESTROYED();
     return fragmentainer_groups_.First();
@@ -272,6 +270,7 @@
 
   void FinishLayoutFromNG();
 
+ protected:
   LayoutMultiColumnSet(LayoutFlowThread*);
 
  private:
@@ -299,7 +298,7 @@
   void AddLayoutOverflowFromChildren() override;
 
   MultiColumnFragmentainerGroupList fragmentainer_groups_;
-  Member<LayoutFlowThread> flow_thread_;
+  LayoutFlowThread* flow_thread_;
 
   // Height of the tallest piece of unbreakable content. This is the minimum
   // column logical height required to avoid fragmentation where it shouldn't
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc b/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc
index 958998f..d23c4c47 100644
--- a/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc
+++ b/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc
@@ -24,8 +24,7 @@
     const ComputedStyle& parent_style,
     LayoutBox& layout_object_in_flow_thread) {
   LayoutMultiColumnSpannerPlaceholder* new_spanner =
-      MakeGarbageCollected<LayoutMultiColumnSpannerPlaceholder>(
-          &layout_object_in_flow_thread);
+      new LayoutMultiColumnSpannerPlaceholder(&layout_object_in_flow_thread);
   Document& document = layout_object_in_flow_thread.GetDocument();
   new_spanner->SetDocumentForAnonymous(&document);
   new_spanner->UpdateProperties(parent_style);
@@ -37,11 +36,6 @@
     : LayoutBox(nullptr),
       layout_object_in_flow_thread_(layout_object_in_flow_thread) {}
 
-void LayoutMultiColumnSpannerPlaceholder::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_object_in_flow_thread_);
-  LayoutBox::Trace(visitor);
-}
-
 void LayoutMultiColumnSpannerPlaceholder::
     LayoutObjectInFlowThreadStyleDidChange(const ComputedStyle* old_style) {
   NOT_DESTROYED();
@@ -69,7 +63,7 @@
 void LayoutMultiColumnSpannerPlaceholder::UpdateProperties(
     const ComputedStyle& parent_style) {
   NOT_DESTROYED();
-  ComputedStyle* new_style =
+  scoped_refptr<ComputedStyle> new_style =
       GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
           parent_style, EDisplay::kBlock);
   CopyMarginProperties(*new_style, layout_object_in_flow_thread_->StyleRef());
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h b/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h
index b039b9d..d9a26bd5 100644
--- a/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h
+++ b/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h
@@ -27,8 +27,6 @@
       const ComputedStyle& parent_style,
       LayoutBox&);
 
-  void Trace(Visitor*) const override;
-
   LayoutBlockFlow* MultiColumnBlockFlow() const {
     NOT_DESTROYED();
     return To<LayoutBlockFlow>(Parent());
@@ -61,8 +59,6 @@
   void LayoutObjectInFlowThreadStyleDidChange(const ComputedStyle* old_style);
   void UpdateProperties(const ComputedStyle& parent_style);
 
-  explicit LayoutMultiColumnSpannerPlaceholder(LayoutBox*);
-
   const char* GetName() const override {
     NOT_DESTROYED();
     return "LayoutMultiColumnSpannerPlaceholder";
@@ -85,6 +81,8 @@
                    HitTestAction) override;
 
  private:
+  LayoutMultiColumnSpannerPlaceholder(LayoutBox*);
+
   MinMaxSizes ComputeIntrinsicLogicalWidths() const final {
     NOT_DESTROYED();
     NOTREACHED();
@@ -92,7 +90,7 @@
   }
 
   // The actual column-span:all layoutObject inside the flow thread.
-  Member<LayoutBox> layout_object_in_flow_thread_;
+  LayoutBox* layout_object_in_flow_thread_;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index 4adb44bb..564d550 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -218,7 +218,11 @@
   unsigned bitfields_;
   unsigned bitfields2_;
   unsigned bitfields3_;
-  Member<void*> members[6];
+  void* pointers[4];
+  Member<void*> members[1];
+  // The following fields are in FragmentData.
+  PhysicalOffset paint_offset_;
+  std::unique_ptr<int> rare_data_;
 #if DCHECK_IS_ON()
   bool is_destroyed_;
 #endif
@@ -228,6 +232,17 @@
 
 bool LayoutObject::affects_parent_block_ = false;
 
+void* LayoutObject::operator new(size_t sz) {
+  DCHECK(IsMainThread());
+  return WTF::Partitions::LayoutPartition()->Alloc(
+      sz, WTF_HEAP_PROFILER_TYPE_NAME(LayoutObject));
+}
+
+void LayoutObject::operator delete(void* ptr) {
+  DCHECK(IsMainThread());
+  WTF::Partitions::LayoutPartition()->Free(ptr);
+}
+
 LayoutObject* LayoutObject::CreateObject(Element* element,
                                          const ComputedStyle& style,
                                          LegacyLayout legacy) {
@@ -239,7 +254,7 @@
   // feature.
   const ContentData* content_data = style.GetContentData();
   if (!element->IsPseudoElement() && ShouldUseContentData(content_data)) {
-    LayoutImage* image = MakeGarbageCollected<LayoutImage>(element);
+    LayoutImage* image = new LayoutImage(element);
     // LayoutImageResourceStyleImage requires a style being present on the
     // image but we don't want to trigger a style change now as the node is
     // not fully attached. Moving this code to style change doesn't make sense
@@ -265,7 +280,7 @@
     case EDisplay::kContents:
       return nullptr;
     case EDisplay::kInline:
-      return MakeGarbageCollected<LayoutInline>(element);
+      return new LayoutInline(element);
     case EDisplay::kBlock:
     case EDisplay::kFlowRoot:
     case EDisplay::kInlineBlock:
@@ -308,7 +323,7 @@
     case EDisplay::kLayoutCustom:
     case EDisplay::kInlineLayoutCustom:
       DCHECK(RuntimeEnabledFeatures::LayoutNGEnabled());
-      return MakeGarbageCollected<LayoutNGCustom>(element);
+      return new LayoutNGCustom(element);
   }
 
   NOTREACHED();
@@ -327,28 +342,21 @@
       node_(node),
       parent_(nullptr),
       previous_(nullptr),
-      next_(nullptr),
-      fragment_(MakeGarbageCollected<FragmentData>()) {
+      next_(nullptr) {
   InstanceCounters::IncrementCounter(InstanceCounters::kLayoutObjectCounter);
   if (node_)
     GetFrameView()->IncrementLayoutObjectCount();
 }
 
 LayoutObject::~LayoutObject() {
-  DCHECK(bitfields_.BeingDestroyed());
 #if DCHECK_IS_ON()
-  DCHECK(is_destroyed_);
+  DCHECK(!has_ax_object_);
+  DCHECK(BeingDestroyed());
 #endif
   InstanceCounters::DecrementCounter(InstanceCounters::kLayoutObjectCounter);
-}
-
-void LayoutObject::Trace(Visitor* visitor) const {
-  visitor->Trace(style_);
-  visitor->Trace(node_);
-  visitor->Trace(parent_);
-  visitor->Trace(previous_);
-  visitor->Trace(next_);
-  visitor->Trace(fragment_);
+#if DCHECK_IS_ON()
+  is_destroyed_ = true;
+#endif
 }
 
 bool LayoutObject::IsDescendantOf(const LayoutObject* obj) const {
@@ -2255,8 +2263,9 @@
   return diff;
 }
 
-void LayoutObject::SetPseudoElementStyle(const ComputedStyle* pseudo_style,
-                                         bool match_parent_size) {
+void LayoutObject::SetPseudoElementStyle(
+    scoped_refptr<const ComputedStyle> pseudo_style,
+    bool match_parent_size) {
   NOT_DESTROYED();
   DCHECK(pseudo_style->StyleType() == kPseudoIdBefore ||
          pseudo_style->StyleType() == kPseudoIdAfter ||
@@ -2266,15 +2275,15 @@
   // FIXME: We should consider just making all pseudo items use an inherited
   // style.
 
-  // Images are special and must inherit the pseudoStyle so the width and
-  // height of the pseudo element doesn't change the size of the image. In all
-  // other cases we can just share the style.
+  // Images are special and must inherit the pseudoStyle so the width and height
+  // of the pseudo element doesn't change the size of the image. In all other
+  // cases we can just share the style.
   //
   // Quotes are also LayoutInline, so we need to create an inherited style to
   // avoid getting an inline with positioning or an invalid display.
   //
   if (IsImage() || IsQuote()) {
-    ComputedStyle* style =
+    scoped_refptr<ComputedStyle> style =
         GetDocument().GetStyleResolver().CreateComputedStyle();
     style->InheritFrom(*pseudo_style);
     if (match_parent_size) {
@@ -2359,7 +2368,7 @@
 }
 
 DISABLE_CFI_PERF
-void LayoutObject::SetStyle(const ComputedStyle* style,
+void LayoutObject::SetStyle(scoped_refptr<const ComputedStyle> style,
                             ApplyStyleChanges apply_changes) {
   NOT_DESTROYED();
   if (style_ == style)
@@ -2390,17 +2399,17 @@
 
   StyleWillChange(diff, *style);
 
-  const ComputedStyle* old_style = std::move(style_);
+  scoped_refptr<const ComputedStyle> old_style = std::move(style_);
   SetStyleInternal(std::move(style));
 
   if (!IsText())
-    UpdateImageObservers(old_style, style_);
+    UpdateImageObservers(old_style.get(), style_.get());
 
-  CheckCounterChanges(old_style, style_);
+  CheckCounterChanges(old_style.get(), style_.get());
 
   bool does_not_need_layout_or_paint_invalidation = !parent_;
 
-  StyleDidChange(diff, old_style);
+  StyleDidChange(diff, old_style.get());
 
   // FIXME: |this| might be destroyed here. This can currently happen for a
   // LayoutTextFragment when its first-letter block gets an update in
@@ -2553,20 +2562,19 @@
     return;
 
   using FirstLineStyleMap =
-      HeapHashMap<WeakMember<const LayoutObject>, Member<const ComputedStyle>>;
-  DEFINE_STATIC_LOCAL(Persistent<FirstLineStyleMap>, first_line_style_map,
-                      (MakeGarbageCollected<FirstLineStyleMap>()));
+      HashMap<const LayoutObject*, scoped_refptr<const ComputedStyle>>;
+  DEFINE_STATIC_LOCAL(FirstLineStyleMap, first_line_style_map, ());
   DCHECK_EQ(bitfields_.RegisteredAsFirstLineImageObserver(),
-            first_line_style_map->Contains(this));
+            first_line_style_map.Contains(this));
   const auto* old_first_line_style =
       bitfields_.RegisteredAsFirstLineImageObserver()
-          ? first_line_style_map->at(this)
+          ? first_line_style_map.at(this)
           : nullptr;
 
   // UpdateFillImages() may indirectly call LayoutBlock::ImageChanged() which
   // will invalidate the first line style cache and remove a reference to
   // new_first_line_style, so hold a reference here.
-  const ComputedStyle* new_first_line_style =
+  scoped_refptr<const ComputedStyle> new_first_line_style =
       has_new_first_line_style ? FirstLineStyleWithoutFallback() : nullptr;
 
   if (new_first_line_style && !new_first_line_style->HasBackgroundImage())
@@ -2587,13 +2595,13 @@
           &FirstLineStyleWithoutFallback()->BackgroundLayers()));
       new_first_line_style = FirstLineStyleWithoutFallback();
       bitfields_.SetRegisteredAsFirstLineImageObserver(true);
-      first_line_style_map->Set(this, new_first_line_style);
+      first_line_style_map.Set(this, std::move(new_first_line_style));
     } else {
       bitfields_.SetRegisteredAsFirstLineImageObserver(false);
-      first_line_style_map->erase(this);
+      first_line_style_map.erase(this);
     }
     DCHECK_EQ(bitfields_.RegisteredAsFirstLineImageObserver(),
-              first_line_style_map->Contains(this));
+              first_line_style_map.Contains(this));
   }
 }
 
@@ -2925,7 +2933,7 @@
     if (child->AnonymousHasStylePropagationOverride())
       continue;
 
-    ComputedStyle* new_style =
+    scoped_refptr<ComputedStyle> new_style =
         GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
             StyleRef(), child->StyleRef().Display());
 
@@ -3598,7 +3606,7 @@
 
   // Remove this object as ImageResourceObserver.
   if (style_ && !IsText())
-    UpdateImageObservers(style_, nullptr);
+    UpdateImageObservers(style_.get(), nullptr);
 
   // We must have removed all image observers.
   SECURITY_CHECK(!bitfields_.RegisteredAsFirstLineImageObserver());
@@ -3870,10 +3878,12 @@
   // other house keepings.
   bitfields_.SetBeingDestroyed(true);
   WillBeDestroyed();
-#if DCHECK_IS_ON()
-  DCHECK(!has_ax_object_);
-  is_destroyed_ = true;
-#endif
+  DeleteThis();
+}
+
+void LayoutObject::DeleteThis() {
+  NOT_DESTROYED();
+  delete this;
 }
 
 PositionWithAffinity LayoutObject::PositionForPoint(
@@ -4025,7 +4035,7 @@
       // it's based on first_line_block's style. We need to get the uncached
       // first line style based on this object's style and cache the result in
       // it.
-      if (ComputedStyle* first_line_style =
+      if (scoped_refptr<ComputedStyle> first_line_style =
               first_line_block->GetUncachedPseudoElementStyle(
                   StyleRequest(kPseudoIdFirstLine, Style()))) {
         return StyleRef().AddCachedPseudoElementStyle(
@@ -4042,7 +4052,7 @@
             Parent()->FirstLineStyleWithoutFallback()) {
       // A first-line style is in effect. Get uncached first line style based on
       // parent_first_line_style and cache the result in this object's style.
-      if (ComputedStyle* first_line_style =
+      if (scoped_refptr<ComputedStyle> first_line_style =
               GetUncachedPseudoElementStyle(StyleRequest(
                   kPseudoIdFirstLineInherited, parent_first_line_style))) {
         return StyleRef().AddCachedPseudoElementStyle(
@@ -4068,7 +4078,7 @@
   return element->CachedStyleForPseudoElement(pseudo);
 }
 
-ComputedStyle* LayoutObject::GetUncachedPseudoElementStyle(
+scoped_refptr<ComputedStyle> LayoutObject::GetUncachedPseudoElementStyle(
     const StyleRequest& request) const {
   NOT_DESTROYED();
   DCHECK_NE(request.pseudo_id, kPseudoIdBefore);
@@ -4757,7 +4767,7 @@
 void LayoutObject::InvalidateClipPathCache() {
   NOT_DESTROYED();
   SetNeedsPaintPropertyUpdate();
-  for (FragmentData* fragment = fragment_; fragment;
+  for (auto* fragment = &fragment_; fragment;
        fragment = fragment->NextFragment())
     fragment->InvalidateClipPathCache();
 }
@@ -4772,7 +4782,7 @@
 }
 
 void LayoutObject::SetModifiedStyleOutsideStyleRecalc(
-    const ComputedStyle* style,
+    scoped_refptr<const ComputedStyle> style,
     ApplyStyleChanges apply_changes) {
   NOT_DESTROYED();
   SetStyle(style, apply_changes);
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index e4bafe6..4286b468 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -76,6 +76,7 @@
 class HitTestLocation;
 class HitTestRequest;
 class InlineBox;
+class LayoutBoxModelObject;
 class LayoutBlock;
 class LayoutBlockFlow;
 class LayoutFlowThread;
@@ -269,8 +270,7 @@
 // IntrinsicLogicalWidthsDirty.
 //
 // See the individual getters below for more details about what each width is.
-class CORE_EXPORT LayoutObject : public GarbageCollected<LayoutObject>,
-                                 public ImageResourceObserver,
+class CORE_EXPORT LayoutObject : public ImageResourceObserver,
                                  public DisplayItemClient {
   friend class LayoutObjectChildList;
   FRIEND_TEST_ALL_PREFIXES(LayoutObjectTest, MutableForPaintingClearPaintFlags);
@@ -289,31 +289,16 @@
   FRIEND_TEST_ALL_PREFIXES(
       LayoutObjectTest,
       ContainingBlockAbsoluteLayoutObjectShouldNotBeNonStaticallyPositionedInlineAncestor);
-  FRIEND_TEST_ALL_PREFIXES(LayoutObjectTest, VisualRect);
 
   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*);
   LayoutObject(const LayoutObject&) = delete;
   LayoutObject& operator=(const LayoutObject&) = delete;
   ~LayoutObject() override;
-  virtual void Trace(Visitor*) const;
 
 // Should be added at the beginning of every method to ensure we are not
 // accessing a LayoutObject after the Desroy() call.
@@ -346,7 +331,7 @@
  protected:
   void EnsureIdForTesting() {
     NOT_DESTROYED();
-    fragment_->EnsureId();
+    fragment_.EnsureId();
   }
 
  private:
@@ -593,7 +578,7 @@
 
   UniqueObjectId UniqueId() const {
     NOT_DESTROYED();
-    return fragment_->UniqueId();
+    return fragment_.UniqueId();
   }
 
   inline bool ShouldApplyPaintContainment(const ComputedStyle& style) const {
@@ -771,6 +756,10 @@
                                     const ComputedStyle&,
                                     LegacyLayout);
 
+  // LayoutObjects are allocated out of the rendering partition.
+  void* operator new(size_t);
+  void operator delete(void*);
+
   bool IsPseudoElement() const {
     NOT_DESTROYED();
     return GetNode() && GetNode()->IsPseudoElement();
@@ -1758,7 +1747,8 @@
   // from the originating element's style (because we can cache only one
   // version), while the uncached pseudo style can inherit from any style.
   const ComputedStyle* GetCachedPseudoElementStyle(PseudoId) const;
-  ComputedStyle* GetUncachedPseudoElementStyle(const StyleRequest&) const;
+  scoped_refptr<ComputedStyle> GetUncachedPseudoElementStyle(
+      const StyleRequest&) const;
 
   LayoutView* View() const {
     NOT_DESTROYED();
@@ -2227,11 +2217,11 @@
   // and new ComputedStyle like paint and size invalidations. If kNo, just set
   // the ComputedStyle member.
   enum class ApplyStyleChanges { kNo, kYes };
-  void SetStyle(const ComputedStyle*,
+  void SetStyle(scoped_refptr<const ComputedStyle>,
                 ApplyStyleChanges = ApplyStyleChanges::kYes);
 
   // Set the style of the object if it's generated content.
-  void SetPseudoElementStyle(const ComputedStyle*,
+  void SetPseudoElementStyle(scoped_refptr<const ComputedStyle>,
                              bool match_parent_size = false);
 
   // In some cases we modify the ComputedStyle after the style recalc, either
@@ -2244,7 +2234,7 @@
   // visual invalidation etc.
   //
   // Do not use unless strictly necessary.
-  void SetModifiedStyleOutsideStyleRecalc(const ComputedStyle*,
+  void SetModifiedStyleOutsideStyleRecalc(scoped_refptr<const ComputedStyle>,
                                           ApplyStyleChanges);
 
   void ClearBaseComputedStyle();
@@ -2490,7 +2480,7 @@
 
   const ComputedStyle* Style() const {
     NOT_DESTROYED();
-    return style_;
+    return style_.get();
   }
 
   // style_ can only be nullptr before the first style is set, thus most
@@ -2992,7 +2982,7 @@
   // See ../paint/README.md for more on fragments.
   const FragmentData& FirstFragment() const {
     NOT_DESTROYED();
-    return *fragment_;
+    return fragment_;
   }
 
   // Attempt to return the top/left fragment, to be used in block-fragmentation-
@@ -3017,8 +3007,8 @@
     NOT_DESTROYED();
     DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
     if (LIKELY(!HasFlippedBlocksWritingMode() || !IsLayoutNGObject()))
-      return *fragment_;
-    return fragment_->LastFragment();
+      return fragment_;
+    return fragment_.LastFragment();
   }
 
   enum OverflowRecalcType {
@@ -3190,9 +3180,9 @@
           .SetShouldAssumePaintOffsetTranslationForLayoutShiftTracking(b);
     }
 
-    FragmentData& FirstFragment() { return *layout_object_.fragment_; }
+    FragmentData& FirstFragment() { return layout_object_.fragment_; }
 
-    void EnsureId() { layout_object_.fragment_->EnsureId(); }
+    void EnsureId() { layout_object_.fragment_.EnsureId(); }
 
    protected:
     friend class LayoutBoxModelObject;
@@ -3509,12 +3499,16 @@
     return false;
   }
 
-  void SetDestroyedForTesting() {
+  // While the |DeleteThis()| method is virtual, this should only be overridden
+  // in very rare circumstances.
+  // You want to override |WillBeDestroyed()| instead unless you explicitly need
+  // to stop this object from being destroyed (for example,
+  // |LayoutEmbeddedContent| overrides |DeleteThis()| for this purpose).
+  virtual void DeleteThis();
+
+  void SetBeingDestroyedForTesting() {
     NOT_DESTROYED();
     bitfields_.SetBeingDestroyed(true);
-#if DCHECK_IS_ON()
-    is_destroyed_ = true;
-#endif
   }
 
   const ComputedStyle& SlowEffectiveStyle(NGStyleVariant style_variant) const;
@@ -3522,9 +3516,9 @@
   // Updates only the local style ptr of the object.  Does not update the state
   // of the object, and so only should be called when the style is known not to
   // have changed (or from SetStyle).
-  void SetStyleInternal(const ComputedStyle* style) {
+  void SetStyleInternal(scoped_refptr<const ComputedStyle> style) {
     NOT_DESTROYED();
-    style_ = style;
+    style_ = std::move(style);
   }
   // Overrides should call the superclass at the end. style_ will be 0 the
   // first time this function will be called.
@@ -4147,7 +4141,6 @@
                          HasNonCollapsedBorderDecoration);
 
     // True at start of |Destroy()| before calling |WillBeDestroyed()|.
-    // TODO(yukiy): Remove this bitfield
     ADD_BOOLEAN_BITFIELD(being_destroyed_, BeingDestroyed);
 
     // From LayoutListMarkerImage
@@ -4308,18 +4301,21 @@
 
  private:
   friend class LineLayoutItem;
-  friend class LocalFrameView;
 
-  Member<const ComputedStyle> style_;
-  Member<Node> node_;
-  Member<LayoutObject> parent_;
-  Member<LayoutObject> previous_;
-  Member<LayoutObject> next_;
-  Member<FragmentData> fragment_;
+  scoped_refptr<const ComputedStyle> style_;
+
+  // Oilpan: This untraced pointer to the owning Node is considered safe.
+  UntracedMember<Node> node_;
+
+  LayoutObject* parent_;
+  LayoutObject* previous_;
+  LayoutObject* next_;
 
   // Store state between styleWillChange and styleDidChange
   static bool affects_parent_block_;
 
+  FragmentData fragment_;
+
 #if DCHECK_IS_ON()
   bool is_destroyed_ = false;
 #endif
diff --git a/third_party/blink/renderer/core/layout/layout_object_child_list.cc b/third_party/blink/renderer/core/layout/layout_object_child_list.cc
index ed9db64c..c4bd22a 100644
--- a/third_party/blink/renderer/core/layout/layout_object_child_list.cc
+++ b/third_party/blink/renderer/core/layout/layout_object_child_list.cc
@@ -71,11 +71,6 @@
 
 }  // namespace
 
-void LayoutObjectChildList::Trace(Visitor* visitor) const {
-  visitor->Trace(first_child_);
-  visitor->Trace(last_child_);
-}
-
 void LayoutObjectChildList::DestroyLeftoverChildren() {
   // Destroy any anonymous children remaining in the layout tree, as well as
   // implicit (shadow) DOM elements like those used in the engine-based text
diff --git a/third_party/blink/renderer/core/layout/layout_object_child_list.h b/third_party/blink/renderer/core/layout/layout_object_child_list.h
index df58b9a..8901294 100644
--- a/third_party/blink/renderer/core/layout/layout_object_child_list.h
+++ b/third_party/blink/renderer/core/layout/layout_object_child_list.h
@@ -38,7 +38,6 @@
 
  public:
   LayoutObjectChildList() : first_child_(nullptr), last_child_(nullptr) {}
-  void Trace(Visitor*) const;
 
   LayoutObject* FirstChild() const { return first_child_; }
   LayoutObject* LastChild() const { return last_child_; }
@@ -61,8 +60,8 @@
  private:
   void InvalidatePaintOnRemoval(LayoutObject& old_child);
 
-  Member<LayoutObject> first_child_;
-  Member<LayoutObject> last_child_;
+  LayoutObject* first_child_;
+  LayoutObject* last_child_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_object_factory.cc b/third_party/blink/renderer/core/layout/layout_object_factory.cc
index 2601fee..2151fc07 100644
--- a/third_party/blink/renderer/core/layout/layout_object_factory.cc
+++ b/third_party/blink/renderer/core/layout/layout_object_factory.cc
@@ -6,6 +6,7 @@
 
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/layout/layout_block_flow.h"
 #include "third_party/blink/renderer/core/layout/layout_button.h"
 #include "third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h"
@@ -92,9 +93,9 @@
     force_legacy = legacy == LegacyLayout::kForce;
 
     if (!force_legacy)
-      return MakeGarbageCollected<NGType>(element);
+      return new NGType(element);
   }
-  BaseType* new_object = MakeGarbageCollected<LegacyType>(element);
+  BaseType* new_object = new LegacyType(element);
   if (force_legacy)
     new_object->SetForceLegacyLayout();
   return new_object;
@@ -302,9 +303,9 @@
   if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
     force_legacy = legacy == LegacyLayout::kForce;
     if (!force_legacy)
-      return MakeGarbageCollected<LayoutNGText>(node, str);
+      return new LayoutNGText(node, str);
   }
-  LayoutText* layout_text = MakeGarbageCollected<LayoutText>(node, str);
+  LayoutText* layout_text = new LayoutText(node, str);
   if (force_legacy)
     layout_text->SetForceLegacyLayout();
   return layout_text;
@@ -319,13 +320,11 @@
   bool force_legacy = false;
   if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
     force_legacy = legacy == LegacyLayout::kForce;
-    if (!force_legacy) {
-      return MakeGarbageCollected<LayoutNGTextFragment>(node, str, start_offset,
-                                                        length);
-    }
+    if (!force_legacy)
+      return new LayoutNGTextFragment(node, str, start_offset, length);
   }
   LayoutTextFragment* layout_text_fragment =
-      MakeGarbageCollected<LayoutTextFragment>(node, str, start_offset, length);
+      new LayoutTextFragment(node, str, start_offset, length);
   if (force_legacy)
     layout_text_fragment->SetForceLegacyLayout();
   return layout_text_fragment;
@@ -362,7 +361,7 @@
 LayoutBox* LayoutObjectFactory::CreateAnonymousTableWithParent(
     const LayoutObject& parent,
     bool child_forces_legacy) {
-  ComputedStyle* new_style =
+  scoped_refptr<ComputedStyle> new_style =
       parent.GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
           parent.StyleRef(),
           parent.IsLayoutInline() ? EDisplay::kInlineTable : EDisplay::kTable);
@@ -379,7 +378,7 @@
 
 LayoutBox* LayoutObjectFactory::CreateAnonymousTableSectionWithParent(
     const LayoutObject& parent) {
-  ComputedStyle* new_style =
+  scoped_refptr<ComputedStyle> new_style =
       parent.GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
           parent.StyleRef(), EDisplay::kTableRowGroup);
   LegacyLayout legacy =
@@ -394,7 +393,7 @@
 
 LayoutBox* LayoutObjectFactory::CreateAnonymousTableRowWithParent(
     const LayoutObject& parent) {
-  ComputedStyle* new_style =
+  scoped_refptr<ComputedStyle> new_style =
       parent.GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
           parent.StyleRef(), EDisplay::kTableRow);
   LegacyLayout legacy =
@@ -407,7 +406,7 @@
 
 LayoutBlockFlow* LayoutObjectFactory::CreateAnonymousTableCellWithParent(
     const LayoutObject& parent) {
-  ComputedStyle* new_style =
+  scoped_refptr<ComputedStyle> new_style =
       parent.GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
           parent.StyleRef(), EDisplay::kTableCell);
   LegacyLayout legacy =
diff --git a/third_party/blink/renderer/core/layout/layout_object_test.cc b/third_party/blink/renderer/core/layout/layout_object_test.cc
index 1105bf5..a8fcf6a 100644
--- a/third_party/blink/renderer/core/layout/layout_object_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_object_test.cc
@@ -725,6 +725,7 @@
   class MockLayoutObject : public LayoutObject {
    public:
     MockLayoutObject() : LayoutObject(nullptr) {}
+    ~MockLayoutObject() override { SetBeingDestroyedForTesting(); }
     MOCK_CONST_METHOD0(VisualRectRespectsVisibility, bool());
 
    private:
@@ -738,20 +739,19 @@
     }
   };
 
-  MockLayoutObject* mock_object = MakeGarbageCollected<MockLayoutObject>();
-  auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
-  mock_object->SetStyle(style);
-  EXPECT_EQ(PhysicalRect(10, 10, 20, 20), mock_object->LocalVisualRect());
-  EXPECT_EQ(PhysicalRect(10, 10, 20, 20), mock_object->LocalVisualRect());
+  MockLayoutObject mock_object;
+  auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  mock_object.SetStyle(style.get());
+  EXPECT_EQ(PhysicalRect(10, 10, 20, 20), mock_object.LocalVisualRect());
+  EXPECT_EQ(PhysicalRect(10, 10, 20, 20), mock_object.LocalVisualRect());
 
   style->SetVisibility(EVisibility::kHidden);
-  EXPECT_CALL(*mock_object, VisualRectRespectsVisibility())
+  EXPECT_CALL(mock_object, VisualRectRespectsVisibility())
       .WillOnce(Return(true));
-  EXPECT_TRUE(mock_object->LocalVisualRect().IsEmpty());
-  EXPECT_CALL(*mock_object, VisualRectRespectsVisibility())
+  EXPECT_TRUE(mock_object.LocalVisualRect().IsEmpty());
+  EXPECT_CALL(mock_object, VisualRectRespectsVisibility())
       .WillOnce(Return(false));
-  EXPECT_EQ(PhysicalRect(10, 10, 20, 20), mock_object->LocalVisualRect());
-  mock_object->SetDestroyedForTesting();
+  EXPECT_EQ(PhysicalRect(10, 10, 20, 20), mock_object.LocalVisualRect());
 }
 
 TEST_F(LayoutObjectTest, DisplayContentsInlineWrapper) {
diff --git a/third_party/blink/renderer/core/layout/layout_progress.h b/third_party/blink/renderer/core/layout/layout_progress.h
index 3afdf9bf..af76904 100644
--- a/third_party/blink/renderer/core/layout/layout_progress.h
+++ b/third_party/blink/renderer/core/layout/layout_progress.h
@@ -33,11 +33,6 @@
   explicit LayoutProgress(Element* element);
   ~LayoutProgress() override;
 
-  void Trace(Visitor* visitor) const override {
-    visitor->Trace(animation_timer_);
-    LayoutBlockFlow::Trace(visitor);
-  }
-
   double GetPosition() const {
     NOT_DESTROYED();
     return position_;
@@ -71,7 +66,7 @@
   double position_;
   base::TimeTicks animation_start_time_;
   bool animating_;
-  HeapTaskRunnerTimer<LayoutProgress> animation_timer_;
+  TaskRunnerTimer<LayoutProgress> animation_timer_;
 
   friend class LayoutProgressTest;
 };
diff --git a/third_party/blink/renderer/core/layout/layout_quote.cc b/third_party/blink/renderer/core/layout/layout_quote.cc
index b1e792d..bbcd2f7 100644
--- a/third_party/blink/renderer/core/layout/layout_quote.cc
+++ b/third_party/blink/renderer/core/layout/layout_quote.cc
@@ -49,13 +49,6 @@
   DCHECK(!previous_);
 }
 
-void LayoutQuote::Trace(Visitor* visitor) const {
-  visitor->Trace(next_);
-  visitor->Trace(previous_);
-  visitor->Trace(owning_pseudo_);
-  LayoutInline::Trace(visitor);
-}
-
 void LayoutQuote::WillBeDestroyed() {
   NOT_DESTROYED();
   DetachQuote();
diff --git a/third_party/blink/renderer/core/layout/layout_quote.h b/third_party/blink/renderer/core/layout/layout_quote.h
index 2129bee6..8dd16057 100644
--- a/third_party/blink/renderer/core/layout/layout_quote.h
+++ b/third_party/blink/renderer/core/layout/layout_quote.h
@@ -42,8 +42,6 @@
  public:
   LayoutQuote(PseudoElement&, const QuoteType);
   ~LayoutQuote() override;
-  void Trace(Visitor*) const override;
-
   void AttachQuote();
 
   const char* GetName() const override {
@@ -87,13 +85,13 @@
   // The next and previous LayoutQuote in layout tree order.
   // LayoutQuotes are linked together by this doubly-linked list.
   // Those are used to compute |m_depth| in an efficient manner.
-  Member<LayoutQuote> next_;
-  Member<LayoutQuote> previous_;
+  LayoutQuote* next_;
+  LayoutQuote* previous_;
 
   // The pseudo-element that owns us.
   //
   // Lifetime is the same as LayoutObject::m_node, so this is safe.
-  Member<PseudoElement> owning_pseudo_;
+  UntracedMember<PseudoElement> owning_pseudo_;
 
   // This tracks whether this LayoutQuote was inserted into the layout tree
   // and its position in the linked list is correct (m_next and m_previous).
diff --git a/third_party/blink/renderer/core/layout/layout_ruby_base.cc b/third_party/blink/renderer/core/layout/layout_ruby_base.cc
index a9e9eaf9..bd4929b 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby_base.cc
+++ b/third_party/blink/renderer/core/layout/layout_ruby_base.cc
@@ -46,9 +46,9 @@
                                                 const LayoutRubyRun& ruby_run) {
   LayoutRubyBase* layout_object;
   if (ruby_run.IsLayoutNGObject()) {
-    layout_object = MakeGarbageCollected<LayoutNGRubyBase>();
+    layout_object = new LayoutNGRubyBase();
   } else {
-    layout_object = MakeGarbageCollected<LayoutRubyBase>(nullptr);
+    layout_object = new LayoutRubyBase(nullptr);
   }
   layout_object->SetDocumentForAnonymous(document);
   return layout_object;
diff --git a/third_party/blink/renderer/core/layout/layout_ruby_base.h b/third_party/blink/renderer/core/layout/layout_ruby_base.h
index 0e4f9e699..acf764d 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby_base.h
+++ b/third_party/blink/renderer/core/layout/layout_ruby_base.h
@@ -57,11 +57,11 @@
 
   bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
 
+ private:
   // The argument must be nullptr. It's necessary for the LayoutNGMixin
   // constructor.
   explicit LayoutRubyBase(Element*);
 
- private:
   ETextAlign TextAlignmentForLine(bool ends_with_soft_break) const override;
   void AdjustInlineDirectionLineBounds(
       unsigned expansion_opportunity_count,
diff --git a/third_party/blink/renderer/core/layout/layout_ruby_run.cc b/third_party/blink/renderer/core/layout/layout_ruby_run.cc
index 353f8a4f..59a1a01a 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby_run.cc
+++ b/third_party/blink/renderer/core/layout/layout_ruby_run.cc
@@ -194,7 +194,7 @@
   NOT_DESTROYED();
   LayoutRubyBase* layout_object =
       LayoutRubyBase::CreateAnonymous(&GetDocument(), *this);
-  ComputedStyle* new_style =
+  scoped_refptr<ComputedStyle> new_style =
       GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
           StyleRef(), EDisplay::kBlock);
   new_style->SetTextAlign(ETextAlign::kCenter);  // FIXME: use WEBKIT_CENTER?
@@ -209,12 +209,12 @@
   DCHECK(parent_ruby->IsRuby());
   LayoutRubyRun* rr;
   if (containing_block.IsLayoutNGObject()) {
-    rr = MakeGarbageCollected<LayoutNGRubyRun>();
+    rr = new LayoutNGRubyRun();
   } else {
-    rr = MakeGarbageCollected<LayoutRubyRun>(nullptr);
+    rr = new LayoutRubyRun(nullptr);
   }
   rr->SetDocumentForAnonymous(&parent_ruby->GetDocument());
-  ComputedStyle* new_style =
+  scoped_refptr<ComputedStyle> new_style =
       parent_ruby->GetDocument()
           .GetStyleResolver()
           .CreateAnonymousStyleWithDisplay(parent_ruby->StyleRef(),
diff --git a/third_party/blink/renderer/core/layout/layout_ruby_run.h b/third_party/blink/renderer/core/layout/layout_ruby_run.h
index b3c1568..2f963a9 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby_run.h
+++ b/third_party/blink/renderer/core/layout/layout_ruby_run.h
@@ -82,13 +82,13 @@
     return "LayoutRubyRun";
   }
 
-  // The argument must be nullptr.
-  explicit LayoutRubyRun(Element*);
-
  protected:
   LayoutRubyBase* CreateRubyBase() const;
 
  private:
+  // The argument must be nullptr.
+  explicit LayoutRubyRun(Element*);
+
   bool IsOfType(LayoutObjectType type) const override {
     NOT_DESTROYED();
     return type == kLayoutObjectRubyRun || LayoutBlockFlow::IsOfType(type);
diff --git a/third_party/blink/renderer/core/layout/layout_ruby_text.cc b/third_party/blink/renderer/core/layout/layout_ruby_text.cc
index 8e00b67..5d4a665 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_ruby_text.cc
@@ -31,6 +31,8 @@
 
 #include "third_party/blink/renderer/core/layout/layout_ruby_text.h"
 
+#include "third_party/blink/renderer/core/frame/web_feature.h"
+
 namespace blink {
 
 LayoutRubyText::LayoutRubyText(Element* element) : LayoutBlockFlow(element) {}
diff --git a/third_party/blink/renderer/core/layout/layout_state.h b/third_party/blink/renderer/core/layout/layout_state.h
index 6b99ad58..302994a 100644
--- a/third_party/blink/renderer/core/layout/layout_state.h
+++ b/third_party/blink/renderer/core/layout/layout_state.h
@@ -27,7 +27,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_STATE_H_
 
 #include "third_party/blink/renderer/platform/geometry/layout_rect.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -121,7 +120,7 @@
   bool containing_block_logical_width_changed_ : 1;
   bool pagination_state_changed_ : 1;
 
-  UntracedMember<LayoutFlowThread> flow_thread_;
+  LayoutFlowThread* flow_thread_;
 
   LayoutState* next_;
 
@@ -139,7 +138,7 @@
 
   AtomicString input_page_name_;
 
-  const UntracedMember<LayoutObject> layout_object_;
+  LayoutObject* const layout_object_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_table.cc b/third_party/blink/renderer/core/layout/layout_table.cc
index 7eed5f46..692babc 100644
--- a/third_party/blink/renderer/core/layout/layout_table.cc
+++ b/third_party/blink/renderer/core/layout/layout_table.cc
@@ -81,15 +81,6 @@
 
 LayoutTable::~LayoutTable() = default;
 
-void LayoutTable::Trace(Visitor* visitor) const {
-  visitor->Trace(captions_);
-  visitor->Trace(column_layout_objects_);
-  visitor->Trace(head_);
-  visitor->Trace(foot_);
-  visitor->Trace(first_body_);
-  LayoutBlock::Trace(visitor);
-}
-
 void LayoutTable::StyleDidChange(StyleDifference diff,
                                  const ComputedStyle* old_style) {
   NOT_DESTROYED();
@@ -137,9 +128,8 @@
     MarkAllCellsWidthsDirtyAndOrNeedsLayout(kMarkDirtyAndNeedsLayout);
 }
 
-static inline void ResetSectionPointerIfNotBefore(
-    Member<LayoutTableSection>& ptr,
-    LayoutObject* before) {
+static inline void ResetSectionPointerIfNotBefore(LayoutTableSection*& ptr,
+                                                  LayoutObject* before) {
   if (!before || !ptr)
     return;
   LayoutObject* o = before->PreviousSibling();
@@ -644,7 +634,7 @@
   // FIXME: We should walk through the items in the tree in tree order to do the
   // layout here instead of walking through individual parts of the tree.
   // crbug.com/442737
-  for (auto& caption : captions_)
+  for (auto*& caption : captions_)
     caption->LayoutIfNeeded();
 
   for (LayoutTableSection* section = TopSection(); section;
@@ -685,7 +675,7 @@
 
 void LayoutTable::RecalcVisualOverflow() {
   NOT_DESTROYED();
-  for (const auto& caption : captions_) {
+  for (auto* caption : captions_) {
     if (!caption->HasSelfPaintingLayer())
       caption->RecalcVisualOverflow();
   }
@@ -1050,7 +1040,7 @@
   }
 
   // Add overflow from our caption.
-  for (const auto& caption : captions_)
+  for (auto* caption : captions_)
     AddVisualOverflowFromChild(*caption);
 
   // Add overflow from our sections.
@@ -1165,7 +1155,7 @@
   table_layout_->ApplyPreferredLogicalWidthQuirks(sizes.min_size,
                                                   sizes.max_size);
 
-  for (const auto& caption : captions_) {
+  for (const auto* caption : captions_) {
     LayoutUnit min_preferred_logical_width =
         caption->PreferredLogicalWidths().min_size;
     sizes.Encompass(min_preferred_logical_width);
diff --git a/third_party/blink/renderer/core/layout/layout_table.h b/third_party/blink/renderer/core/layout/layout_table.h
index fd3f628..f3e66e8 100644
--- a/third_party/blink/renderer/core/layout/layout_table.h
+++ b/third_party/blink/renderer/core/layout/layout_table.h
@@ -139,7 +139,6 @@
  public:
   explicit LayoutTable(Element*);
   ~LayoutTable() override;
-  void Trace(Visitor*) const override;
 
   // Per CSS 3 writing-mode: "The first and second values of the
   // 'border-spacing' property represent spacing between columns and rows
@@ -580,17 +579,17 @@
   mutable Vector<int> effective_column_positions_;
 
   // The captions associated with this object.
-  mutable HeapVector<Member<LayoutTableCaption>> captions_;
+  mutable Vector<LayoutTableCaption*> captions_;
 
   // Holds pointers to LayoutTableCol objects for <col>s and <colgroup>s under
   // this table.
   // There is no direct relationship between the size of and index into this
   // vector and those of m_effectiveColumns because they hold different things.
-  mutable HeapVector<Member<LayoutTableCol>> column_layout_objects_;
+  mutable Vector<LayoutTableCol*> column_layout_objects_;
 
-  mutable Member<LayoutTableSection> head_;
-  mutable Member<LayoutTableSection> foot_;
-  mutable Member<LayoutTableSection> first_body_;
+  mutable LayoutTableSection* head_;
+  mutable LayoutTableSection* foot_;
+  mutable LayoutTableSection* first_body_;
 
   // The layout algorithm used by this table.
   //
diff --git a/third_party/blink/renderer/core/layout/layout_table_box_component.cc b/third_party/blink/renderer/core/layout/layout_table_box_component.cc
index e427d261..9c162339 100644
--- a/third_party/blink/renderer/core/layout/layout_table_box_component.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_box_component.cc
@@ -10,11 +10,6 @@
 
 namespace blink {
 
-void LayoutTableBoxComponent::Trace(Visitor* visitor) const {
-  visitor->Trace(children_);
-  LayoutBox::Trace(visitor);
-}
-
 void LayoutTableBoxComponent::InvalidateCollapsedBordersOnStyleChange(
     const LayoutObject& table_part,
     LayoutTable& table,
diff --git a/third_party/blink/renderer/core/layout/layout_table_box_component.h b/third_party/blink/renderer/core/layout/layout_table_box_component.h
index b797ad2..4561e0b 100644
--- a/third_party/blink/renderer/core/layout/layout_table_box_component.h
+++ b/third_party/blink/renderer/core/layout/layout_table_box_component.h
@@ -28,8 +28,6 @@
                                     const StyleDifference&,
                                     const ComputedStyle& old_style);
 
-  void Trace(Visitor*) const override;
-
   class MutableForPainting : public LayoutObject::MutableForPainting {
    public:
     void UpdatePaintResult(PaintResult, const CullRect& paint_rect);
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell.cc b/third_party/blink/renderer/core/layout/layout_table_cell.cc
index f3dc1c9f..e30bc902 100644
--- a/third_party/blink/renderer/core/layout/layout_table_cell.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_cell.cc
@@ -464,7 +464,7 @@
 void LayoutTableCell::UpdateStyleWritingModeFromRow(const LayoutObject* row) {
   NOT_DESTROYED();
   DCHECK_NE(StyleRef().GetWritingMode(), row->StyleRef().GetWritingMode());
-  ComputedStyle* new_style = ComputedStyle::Clone(StyleRef());
+  scoped_refptr<ComputedStyle> new_style = ComputedStyle::Clone(StyleRef());
   new_style->SetWritingMode(row->StyleRef().GetWritingMode());
   new_style->UpdateFontOrientation();
   SetModifiedStyleOutsideStyleRecalc(new_style,
@@ -1222,9 +1222,10 @@
   }
 }
 
-LayoutTableCell* LayoutTableCell::CreateAnonymous(Document* document,
-                                                  ComputedStyle* style,
-                                                  LegacyLayout legacy) {
+LayoutTableCell* LayoutTableCell::CreateAnonymous(
+    Document* document,
+    scoped_refptr<ComputedStyle> style,
+    LegacyLayout legacy) {
   LayoutBlockFlow* layout_object =
       LayoutObjectFactory::CreateTableCell(*document, *style, legacy);
   layout_object->SetDocumentForAnonymous(document);
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell.h b/third_party/blink/renderer/core/layout/layout_table_cell.h
index 740c92b7..cd87020 100644
--- a/third_party/blink/renderer/core/layout/layout_table_cell.h
+++ b/third_party/blink/renderer/core/layout/layout_table_cell.h
@@ -266,7 +266,7 @@
   }
 
   static LayoutTableCell* CreateAnonymous(Document*,
-                                          ComputedStyle*,
+                                          scoped_refptr<ComputedStyle>,
                                           LegacyLayout);
 
   LayoutBox* CreateAnonymousBoxWithSameTypeAs(
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell_test.cc b/third_party/blink/renderer/core/layout/layout_table_cell_test.cc
index 87191665..3b4382d 100644
--- a/third_party/blink/renderer/core/layout/layout_table_cell_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_cell_test.cc
@@ -38,7 +38,7 @@
 
   void SetUp() override {
     RenderingTest::SetUp();
-    auto* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+    auto style = GetDocument().GetStyleResolver().CreateComputedStyle();
     style->SetDisplay(EDisplay::kTableCell);
     cell_ = LayoutTableCell::CreateAnonymous(&GetDocument(), std::move(style),
                                              LegacyLayout::kAuto);
@@ -49,7 +49,7 @@
     RenderingTest::TearDown();
   }
 
-  Persistent<LayoutTableCell> cell_;
+  LayoutTableCell* cell_;
 };
 
 TEST_F(LayoutTableCellDeathTest, CanSetColumn) {
diff --git a/third_party/blink/renderer/core/layout/layout_table_row.cc b/third_party/blink/renderer/core/layout/layout_table_row.cc
index d4018dee7..121e476 100644
--- a/third_party/blink/renderer/core/layout/layout_table_row.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_row.cc
@@ -70,7 +70,7 @@
 
   // Legacy tables cannont handle relative/fixed rows.
   if (StyleRef().HasInFlowPosition()) {
-    ComputedStyle* new_style = ComputedStyle::Clone(StyleRef());
+    scoped_refptr<ComputedStyle> new_style = ComputedStyle::Clone(StyleRef());
     new_style->SetPosition(EPosition::kStatic);
     SetModifiedStyleOutsideStyleRecalc(new_style,
                                        LayoutObject::ApplyStyleChanges::kNo);
@@ -318,7 +318,7 @@
 }
 
 LayoutTableRow* LayoutTableRow::CreateAnonymous(Document* document) {
-  LayoutTableRow* layout_object = MakeGarbageCollected<LayoutTableRow>(nullptr);
+  LayoutTableRow* layout_object = new LayoutTableRow(nullptr);
   layout_object->SetDocumentForAnonymous(document);
   return layout_object;
 }
diff --git a/third_party/blink/renderer/core/layout/layout_table_row_test.cc b/third_party/blink/renderer/core/layout/layout_table_row_test.cc
index 760bc9e..8f55b4e 100644
--- a/third_party/blink/renderer/core/layout/layout_table_row_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_row_test.cc
@@ -41,7 +41,7 @@
 
   void TearDown() override { row_->Destroy(); }
 
-  Persistent<LayoutTableRow> row_;
+  LayoutTableRow* row_;
 };
 
 TEST_F(LayoutTableRowDeathTest, CanSetRow) {
diff --git a/third_party/blink/renderer/core/layout/layout_table_section.cc b/third_party/blink/renderer/core/layout/layout_table_section.cc
index 6ec0f557..5d96a9f 100644
--- a/third_party/blink/renderer/core/layout/layout_table_section.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_section.cc
@@ -45,11 +45,6 @@
 
 namespace blink {
 
-void LayoutTableSection::TableGridRow::Trace(Visitor* visitor) const {
-  visitor->Trace(grid_cells);
-  visitor->Trace(row);
-}
-
 void LayoutTableSection::TableGridRow::
     SetRowLogicalHeightToRowStyleLogicalHeight() {
   DCHECK(row);
@@ -110,12 +105,6 @@
 
 LayoutTableSection::~LayoutTableSection() = default;
 
-void LayoutTableSection::Trace(Visitor* visitor) const {
-  visitor->Trace(grid_);
-  visitor->Trace(visually_overflowing_cells_);
-  LayoutTableBoxComponent::Trace(visitor);
-}
-
 void LayoutTableSection::StyleDidChange(StyleDifference diff,
                                         const ComputedStyle* old_style) {
   NOT_DESTROYED();
@@ -125,7 +114,7 @@
 
   // Legacy tables cannot handle relative/sticky sections.
   if (StyleRef().HasInFlowPosition()) {
-    ComputedStyle* new_style = ComputedStyle::Clone(StyleRef());
+    scoped_refptr<ComputedStyle> new_style = ComputedStyle::Clone(StyleRef());
     new_style->SetPosition(EPosition::kStatic);
     SetModifiedStyleOutsideStyleRecalc(new_style,
                                        LayoutObject::ApplyStyleChanges::kNo);
@@ -160,12 +149,6 @@
   SetNeedsCellRecalc();
 }
 
-void LayoutTableSection::EnsureCols(unsigned row_index, unsigned num_cols) {
-  NOT_DESTROYED();
-  if (num_cols > NumCols(row_index))
-    grid_[row_index].grid_cells.Grow(num_cols);
-}
-
 void LayoutTableSection::AddChild(LayoutObject* child,
                                   LayoutObject* before_child) {
   NOT_DESTROYED();
@@ -233,7 +216,7 @@
 }
 
 static inline void CheckThatVectorIsDOMOrdered(
-    const HeapVector<Member<LayoutTableCell>, 1>& cells) {
+    const Vector<LayoutTableCell*, 1>& cells) {
 #ifndef NDEBUG
   // This function should be called on a non-empty vector.
   DCHECK_GT(cells.size(), 0u);
@@ -913,7 +896,7 @@
     for (auto& grid_cell : grid_[r].grid_cells) {
       if (grid_cell.InColSpan())
         continue;
-      for (const auto& cell : grid_cell.Cells()) {
+      for (auto* cell : grid_cell.Cells()) {
         // For row spanning cells, we only handle them for the first row they
         // span. This ensures we take their baseline into account.
         if (cell->RowIndex() != r)
@@ -1637,7 +1620,7 @@
     unsigned smallest_row = rows.Start();
     for (unsigned c = columns.Start(); c < std::min(columns.End(), n_cols);
          ++c) {
-      for (const auto& cell : GridCellAt(rows.Start(), c).Cells()) {
+      for (const auto* cell : GridCellAt(rows.Start(), c).Cells()) {
         smallest_row = std::min(smallest_row, cell->RowIndex());
         if (!smallest_row)
           break;
diff --git a/third_party/blink/renderer/core/layout/layout_table_section.h b/third_party/blink/renderer/core/layout/layout_table_section.h
index 65d26ef..3ffbae5 100644
--- a/third_party/blink/renderer/core/layout/layout_table_section.h
+++ b/third_party/blink/renderer/core/layout/layout_table_section.h
@@ -108,7 +108,6 @@
  public:
   explicit LayoutTableSection(Element*);
   ~LayoutTableSection() override;
-  void Trace(Visitor*) const override;
 
   LayoutTableRow* FirstRow() const;
   LayoutTableRow* LastRow() const;
@@ -133,7 +132,7 @@
     return To<LayoutTable>(Parent());
   }
 
-  typedef HeapVector<Member<LayoutTableCell>, 2> SpanningLayoutTableCells;
+  typedef Vector<LayoutTableCell*, 2> SpanningLayoutTableCells;
 
   struct SpanningRowsHeight {
     STACK_ALLOCATED();
@@ -266,8 +265,7 @@
                                       CellSpan& rows,
                                       CellSpan& columns) const;
 
-  const HeapHashSet<Member<const LayoutTableCell>>& VisuallyOverflowingCells()
-      const {
+  const HashSet<const LayoutTableCell*>& VisuallyOverflowingCells() const {
     NOT_DESTROYED();
     return visually_overflowing_cells_;
   }
@@ -373,24 +371,6 @@
   LayoutNGTableRowInterface* LastRowInterface() const final;
 
   // LayoutNGTableSectionInterface methods end.
-
-  // This is made public just to set VectorTraits.
-  struct TableGridRow {
-    DISALLOW_NEW();
-
-   public:
-    void Trace(Visitor*) const;
-
-    inline void SetRowLogicalHeightToRowStyleLogicalHeight();
-    inline void UpdateLogicalHeightForCell(const LayoutTableCell*);
-
-    // The index is effective column index.
-    HeapVector<TableGridCell> grid_cells;
-    Member<LayoutTableRow> row;
-    LayoutUnit baseline = LayoutUnit(-1);
-    Length logical_height;
-  };
-
  protected:
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
   bool NodeAtPoint(HitTestResult&,
@@ -425,7 +405,11 @@
       grid_.Grow(num_rows);
   }
 
-  void EnsureCols(unsigned row_index, unsigned num_cols);
+  void EnsureCols(unsigned row_index, unsigned num_cols) {
+    NOT_DESTROYED();
+    if (num_cols > NumCols(row_index))
+      grid_[row_index].grid_cells.Grow(num_cols);
+  }
 
   bool RowHasOnlySpanningCells(unsigned);
   unsigned CalcRowHeightHavingOnlySpanningCells(unsigned,
@@ -502,8 +486,22 @@
 
   bool GroupShouldRepeat() const;
 
+  struct TableGridRow {
+    DISALLOW_NEW();
+
+   public:
+    inline void SetRowLogicalHeightToRowStyleLogicalHeight();
+    inline void UpdateLogicalHeightForCell(const LayoutTableCell*);
+
+    // The index is effective column index.
+    Vector<TableGridCell> grid_cells;
+    LayoutTableRow* row = nullptr;
+    LayoutUnit baseline = LayoutUnit(-1);
+    Length logical_height;
+  };
+
   // The representation of the rows and their grid cells.
-  HeapVector<TableGridRow> grid_;
+  Vector<TableGridRow> grid_;
 
   // The logical offset of each row from the top of the section.
   //
@@ -542,7 +540,7 @@
   // This HashSet holds the overflowing cells for the partial paint path. If we
   // have too many overflowing cells, it will be empty and force_full_paint_
   // will be set to save memory. See ComputeVisualOverflowFromDescendants().
-  HeapHashSet<Member<const LayoutTableCell>> visually_overflowing_cells_;
+  HashSet<const LayoutTableCell*> visually_overflowing_cells_;
   bool force_full_paint_;
 
   // This boolean tracks if we have cells overlapping due to rowspan / colspan
@@ -572,15 +570,4 @@
 
 }  // namespace blink
 
-namespace WTF {
-
-template <>
-struct VectorTraits<blink::LayoutTableSection::TableGridRow>
-    : VectorTraitsBase<blink::LayoutTableSection::TableGridRow> {
-  STATIC_ONLY(VectorTraits);
-  static constexpr bool kCanClearUnusedSlotsWithMemset = true;
-};
-
-}  // namespace WTF
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_TABLE_SECTION_H_
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc
index 851c9c51..0daf3bb7 100644
--- a/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -57,7 +57,6 @@
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_span.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
 #include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
@@ -86,20 +85,17 @@
   DOMNodeId node_id;
   float widths[4];
   String text;
-  Member<void*> members[2];
+  void* pointers[2];
   PhysicalOffset previous_starting_point;
-  wtf_size_t first_fragment_item_index_;
 };
 
 ASSERT_SIZE(LayoutText, SameSizeAsLayoutText);
 
 class SecureTextTimer;
-typedef HeapHashMap<WeakMember<LayoutText>, SecureTextTimer*>
-    SecureTextTimerMap;
+typedef HashMap<LayoutText*, SecureTextTimer*> SecureTextTimerMap;
 static SecureTextTimerMap& GetSecureTextTimers() {
-  DEFINE_STATIC_LOCAL(const Persistent<SecureTextTimerMap>, map,
-                      (MakeGarbageCollected<SecureTextTimerMap>()));
-  return *map;
+  DEFINE_STATIC_LOCAL(SecureTextTimerMap, map, ());
+  return map;
 }
 
 class SecureTextTimer final : public TimerBase {
@@ -128,7 +124,7 @@
     layout_text_->ForceSetText(layout_text_->GetText().Impl());
   }
 
-  UntracedMember<LayoutText> layout_text_;
+  LayoutText* layout_text_;
   int last_typed_character_offset_;
 };
 
@@ -137,12 +133,10 @@
 };
 
 using SelectionDisplayItemClientMap =
-    HeapHashMap<WeakMember<const LayoutText>,
-                std::unique_ptr<SelectionDisplayItemClient>>;
+    HashMap<const LayoutText*, std::unique_ptr<SelectionDisplayItemClient>>;
 SelectionDisplayItemClientMap& GetSelectionDisplayItemClientMap() {
-  DEFINE_STATIC_LOCAL(Persistent<SelectionDisplayItemClientMap>, map,
-                      (MakeGarbageCollected<SelectionDisplayItemClientMap>()));
-  return *map;
+  DEFINE_STATIC_LOCAL(SelectionDisplayItemClientMap, map, ());
+  return map;
 }
 
 }  // anonymous namespace
@@ -174,14 +168,19 @@
     GetFrameView()->IncrementVisuallyNonEmptyCharacterCount(text_.length());
 }
 
-void LayoutText::Trace(Visitor* visitor) const {
-  visitor->Trace(text_boxes_);
-  LayoutObject::Trace(visitor);
+LayoutText::~LayoutText() {
+#if DCHECK_IS_ON()
+  if (IsInLayoutNGInlineFormattingContext())
+    DCHECK(!first_fragment_item_index_);
+  else
+    text_boxes_.AssertIsEmpty();
+#endif
 }
 
-LayoutText* LayoutText::CreateEmptyAnonymous(Document& doc,
-                                             const ComputedStyle* style,
-                                             LegacyLayout legacy) {
+LayoutText* LayoutText::CreateEmptyAnonymous(
+    Document& doc,
+    scoped_refptr<const ComputedStyle> style,
+    LegacyLayout legacy) {
   LayoutText* text =
       LayoutObjectFactory::CreateText(nullptr, StringImpl::empty_, legacy);
   text->SetDocumentForAnonymous(&doc);
@@ -189,10 +188,11 @@
   return text;
 }
 
-LayoutText* LayoutText::CreateAnonymous(Document& doc,
-                                        const ComputedStyle* style,
-                                        scoped_refptr<StringImpl> text,
-                                        LegacyLayout legacy) {
+LayoutText* LayoutText::CreateAnonymous(
+    Document& doc,
+    scoped_refptr<const ComputedStyle> style,
+    scoped_refptr<StringImpl> text,
+    LegacyLayout legacy) {
   LayoutText* layout_text =
       LayoutObjectFactory::CreateText(nullptr, std::move(text), legacy);
   layout_text->SetDocumentForAnonymous(&doc);
@@ -286,13 +286,6 @@
   RemoveAndDestroyTextBoxes();
   LayoutObject::WillBeDestroyed();
   valid_ng_items_ = false;
-
-#if DCHECK_IS_ON()
-  if (IsInLayoutNGInlineFormattingContext())
-    DCHECK(!first_fragment_item_index_);
-  else
-    text_boxes_.AssertIsEmpty();
-#endif
 }
 
 void LayoutText::ExtractTextBox(InlineTextBox* box) {
@@ -1652,7 +1645,7 @@
     }
   }
   if (run)
-    bidi_resolver.Runs().ClearRuns();
+    bidi_resolver.Runs().DeleteRuns();
 
   if ((needs_word_spacing && len > 1) || (ignoring_spaces && !first_word))
     curr_max_width += word_spacing;
@@ -2217,8 +2210,7 @@
 
 InlineTextBox* LayoutText::CreateTextBox(int start, uint16_t length) {
   NOT_DESTROYED();
-  return MakeGarbageCollected<InlineTextBox>(LineLayoutItem(this), start,
-                                             length);
+  return new InlineTextBox(LineLayoutItem(this), start, length);
 }
 
 InlineTextBox* LayoutText::CreateInlineTextBox(int start, uint16_t length) {
@@ -2800,30 +2792,29 @@
   return nullptr;
 }
 
-void LayoutText::SetInlineItems(NGInlineItemsData* data,
-                                size_t begin,
-                                size_t size) {
+void LayoutText::SetInlineItems(NGInlineItem* begin, NGInlineItem* end) {
   NOT_DESTROYED();
 #if DCHECK_IS_ON()
-  for (size_t i = begin; i < begin + size; i++)
-    DCHECK_EQ(data->items[i].GetLayoutObject(), this);
+  for (NGInlineItem* item = begin; item != end; ++item) {
+    DCHECK_EQ(item->GetLayoutObject(), this);
+  }
 #endif
-  auto* items = GetNGInlineItems();
+  base::span<NGInlineItem>* items = GetNGInlineItems();
   if (!items)
     return;
   valid_ng_items_ = true;
-  items->SetItems(data, begin, size);
+  *items = base::make_span(begin, end);
 }
 
 void LayoutText::ClearInlineItems() {
   NOT_DESTROYED();
   has_bidi_control_items_ = false;
   valid_ng_items_ = false;
-  if (auto* items = GetNGInlineItems())
-    items->Clear();
+  if (base::span<NGInlineItem>* items = GetNGInlineItems())
+    *items = base::span<NGInlineItem>();
 }
 
-const NGInlineItemSpan& LayoutText::InlineItems() const {
+const base::span<NGInlineItem>& LayoutText::InlineItems() const {
   NOT_DESTROYED();
   DCHECK(valid_ng_items_);
   DCHECK(GetNGInlineItems());
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h
index 6ab8352..c3c1f60 100644
--- a/third_party/blink/renderer/core/layout/layout_text.h
+++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -41,8 +41,7 @@
 class AbstractInlineTextBox;
 class ContentCaptureManager;
 class InlineTextBox;
-struct NGInlineItemsData;
-struct NGInlineItemSpan;
+class NGInlineItem;
 class NGOffsetMapping;
 
 enum class OnlyWhitespaceOrNbsp : unsigned { kUnknown = 0, kNo = 1, kYes = 2 };
@@ -83,14 +82,14 @@
   // doesn't re-transform the string.
   LayoutText(Node*, scoped_refptr<StringImpl>);
 
-  void Trace(Visitor*) const override;
+  ~LayoutText() override;
 
   static LayoutText* CreateEmptyAnonymous(Document&,
-                                          const ComputedStyle*,
+                                          scoped_refptr<const ComputedStyle>,
                                           LegacyLayout);
 
   static LayoutText* CreateAnonymous(Document&,
-                                     const ComputedStyle*,
+                                     scoped_refptr<const ComputedStyle>,
                                      scoped_refptr<StringImpl>,
                                      LegacyLayout legacy);
 
@@ -372,13 +371,13 @@
     return node_id_ != kInvalidDOMNodeId;
   }
 
-  void SetInlineItems(NGInlineItemsData* data, size_t begin, size_t size);
+  void SetInlineItems(NGInlineItem* begin, NGInlineItem* end);
   void ClearInlineItems();
   bool HasValidInlineItems() const {
     NOT_DESTROYED();
     return valid_ng_items_;
   }
-  const NGInlineItemSpan& InlineItems() const;
+  const base::span<NGInlineItem>& InlineItems() const;
   // Inline items depends on context. It needs to be invalidated not only when
   // it was inserted/changed but also it was moved.
   void InvalidateInlineItems() {
@@ -399,11 +398,11 @@
     has_bidi_control_items_ = false;
   }
 
-  virtual const NGInlineItemSpan* GetNGInlineItems() const {
+  virtual const base::span<NGInlineItem>* GetNGInlineItems() const {
     NOT_DESTROYED();
     return nullptr;
   }
-  virtual NGInlineItemSpan* GetNGInlineItems() {
+  virtual base::span<NGInlineItem>* GetNGInlineItems() {
     NOT_DESTROYED();
     return nullptr;
   }
@@ -589,15 +588,16 @@
   mutable LogicalOffset previous_logical_starting_point_ =
       UninitializedLogicalStartingPoint();
 
-  // The line boxes associated with this object.
-  // Read the LINE BOXES OWNERSHIP section in the class header comment.
-  // Valid only when !IsInLayoutNGInlineFormattingContext().
-  InlineTextBoxList text_boxes_;
-
-  // The index of the first fragment item associated with this object in
-  // |NGFragmentItems::Items()|. Zero means there are no such item.
-  // Valid only when IsInLayoutNGInlineFormattingContext().
-  wtf_size_t first_fragment_item_index_ = 0u;
+  union {
+    // The line boxes associated with this object.
+    // Read the LINE BOXES OWNERSHIP section in the class header comment.
+    // Valid only when !IsInLayoutNGInlineFormattingContext().
+    InlineTextBoxList text_boxes_;
+    // The index of the first fragment item associated with this object in
+    // |NGFragmentItems::Items()|. Zero means there are no such item.
+    // Valid only when IsInLayoutNGInlineFormattingContext().
+    wtf_size_t first_fragment_item_index_;
+  };
 };
 
 inline InlineTextBoxList& LayoutText::MutableTextBoxes() {
diff --git a/third_party/blink/renderer/core/layout/layout_text_combine.cc b/third_party/blink/renderer/core/layout/layout_text_combine.cc
index 1e960a1..a0a1cf29 100644
--- a/third_party/blink/renderer/core/layout/layout_text_combine.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_combine.cc
@@ -165,7 +165,7 @@
   NOT_DESTROYED();
   DCHECK(is_combined_);
 
-  ComputedStyle* style = ComputedStyle::Clone(StyleRef());
+  scoped_refptr<ComputedStyle> style = ComputedStyle::Clone(StyleRef());
   SetStyleInternal(style);
 
   unsigned offset = 0;
diff --git a/third_party/blink/renderer/core/layout/layout_text_fragment.h b/third_party/blink/renderer/core/layout/layout_text_fragment.h
index 4f07933..4ede7de 100644
--- a/third_party/blink/renderer/core/layout/layout_text_fragment.h
+++ b/third_party/blink/renderer/core/layout/layout_text_fragment.h
@@ -118,10 +118,9 @@
   Text* AssociatedTextNode() const;
   LayoutText* GetFirstLetterPart() const override;
 
-  LayoutTextFragment(Node*, StringImpl*, int start_offset, int length);
-
  protected:
   friend class LayoutObjectFactory;
+  LayoutTextFragment(Node*, StringImpl*, int start_offset, int length);
   void WillBeDestroyed() override;
 
  private:
diff --git a/third_party/blink/renderer/core/layout/layout_tree_as_text.cc b/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
index ad2b5b2d..0c43bb6d 100644
--- a/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_tree_as_text.cc
@@ -660,11 +660,10 @@
     Write(ts, layer.GetLayoutObject(), indent + 1, behavior);
 }
 
-static HeapVector<Member<PaintLayer>> ChildLayers(
-    const PaintLayer* layer,
-    PaintLayerIteration which_children) {
-  HeapVector<Member<PaintLayer>> vector;
-  PaintLayerPaintOrderIterator it(layer, which_children);
+static Vector<PaintLayer*> ChildLayers(const PaintLayer* layer,
+                                       PaintLayerIteration which_children) {
+  Vector<PaintLayer*> vector;
+  PaintLayerPaintOrderIterator it(*layer, which_children);
   while (PaintLayer* child = it.Next())
     vector.push_back(child);
   return vector;
@@ -729,7 +728,7 @@
       ts << " negative z-order list(" << neg_list.size() << ")\n";
       ++curr_indent;
     }
-    for (auto& child_layer : neg_list) {
+    for (auto* child_layer : neg_list) {
       WriteLayers(ts, root_layer, child_layer, curr_indent, behavior,
                   marked_layer);
     }
@@ -751,7 +750,7 @@
       ts << " normal flow list(" << normal_flow_list.size() << ")\n";
       ++curr_indent;
     }
-    for (auto& child_layer : normal_flow_list) {
+    for (auto* child_layer : normal_flow_list) {
       WriteLayers(ts, root_layer, child_layer, curr_indent, behavior,
                   marked_layer);
     }
@@ -765,7 +764,7 @@
       ts << " positive z-order list(" << pos_list.size() << ")\n";
       ++curr_indent;
     }
-    for (auto& child_layer : pos_list) {
+    for (auto* child_layer : pos_list) {
       WriteLayers(ts, root_layer, child_layer, curr_indent, behavior,
                   marked_layer);
     }
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc
index 63dc0522..0095ca8 100644
--- a/third_party/blink/renderer/core/layout/layout_view.cc
+++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -102,7 +102,7 @@
       layout_state_(nullptr),
       compositor_(RuntimeEnabledFeatures::CompositeAfterPaintEnabled()
                       ? nullptr
-                      : MakeGarbageCollected<PaintLayerCompositor>(*this)),
+                      : std::make_unique<PaintLayerCompositor>(*this)),
       layout_quote_head_(nullptr),
       layout_counter_count_(0),
       hit_test_count_(0),
@@ -127,14 +127,6 @@
 
 LayoutView::~LayoutView() = default;
 
-void LayoutView::Trace(Visitor* visitor) const {
-  visitor->Trace(frame_view_);
-  visitor->Trace(compositor_);
-  visitor->Trace(layout_quote_head_);
-  visitor->Trace(hit_test_cache_);
-  LayoutBlockFlow::Trace(visitor);
-}
-
 bool LayoutView::HitTest(const HitTestLocation& location,
                          HitTestResult& result) {
   NOT_DESTROYED();
@@ -837,7 +829,7 @@
 
 PaintLayerCompositor* LayoutView::Compositor() {
   NOT_DESTROYED();
-  return compositor_;
+  return compositor_.get();
 }
 
 void LayoutView::CleanUpCompositor() {
@@ -873,7 +865,7 @@
   if (PaintLayer* layer = Layer())
     layer->SetNeedsRepaint();
   LayoutBlockFlow::WillBeDestroyed();
-  compositor_.Clear();
+  compositor_.reset();
 }
 
 void LayoutView::UpdateFromStyle() {
diff --git a/third_party/blink/renderer/core/layout/layout_view.h b/third_party/blink/renderer/core/layout/layout_view.h
index c1f912d..ff7eed3 100644
--- a/third_party/blink/renderer/core/layout/layout_view.h
+++ b/third_party/blink/renderer/core/layout/layout_view.h
@@ -30,7 +30,6 @@
 #include "third_party/blink/renderer/core/layout/hit_test_cache.h"
 #include "third_party/blink/renderer/core/layout/hit_test_result.h"
 #include "third_party/blink/renderer/core/layout/layout_block_flow.h"
-#include "third_party/blink/renderer/core/layout/layout_quote.h"
 #include "third_party/blink/renderer/core/layout/layout_state.h"
 #include "third_party/blink/renderer/core/scroll/scrollable_area.h"
 #include "third_party/blink/renderer/platform/graphics/overlay_scrollbar_clip_behavior.h"
@@ -65,7 +64,6 @@
  public:
   explicit LayoutView(Document*);
   ~LayoutView() override;
-  void Trace(Visitor*) const override;
 
   void WillBeDestroyed() override;
 
@@ -379,7 +377,7 @@
 
   bool UpdateLogicalWidthAndColumnWidth() override;
 
-  Member<LocalFrameView> frame_view_;
+  UntracedMember<LocalFrameView> frame_view_;
 
   // The page logical height.
   // This is only used during printing to split the content into pages.
@@ -394,17 +392,17 @@
 
   std::unique_ptr<ViewFragmentationContext> fragmentation_context_;
   std::unique_ptr<NamedPagesMapper> named_pages_mapper_;
-  Member<PaintLayerCompositor> compositor_;
+  std::unique_ptr<PaintLayerCompositor> compositor_;
   scoped_refptr<IntervalArena> interval_arena_;
 
-  Member<LayoutQuote> layout_quote_head_;
+  LayoutQuote* layout_quote_head_;
   unsigned layout_counter_count_ = 0;
   unsigned layout_list_item_count_ = 0;
   bool needs_marker_counter_update_ = false;
 
   unsigned hit_test_count_;
   unsigned hit_test_cache_hits_;
-  Member<HitTestCache> hit_test_cache_;
+  Persistent<HitTestCache> hit_test_cache_;
 
   // FrameViewAutoSizeInfo controls scrollbar appearance manually rather than
   // relying on layout. These members are used to override the ScrollbarModes
diff --git a/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.cc b/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.cc
index f7fb2d2..468c744 100644
--- a/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.cc
+++ b/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.cc
@@ -40,17 +40,6 @@
 
 namespace blink {
 
-typedef HeapHashMap<Member<InlineTextBox>, scoped_refptr<AbstractInlineTextBox>>
-    InlineToLegacyAbstractInlineTextBoxHashMap;
-
-InlineToLegacyAbstractInlineTextBoxHashMap& GetAbstractInlineTextBoxMap() {
-  DEFINE_STATIC_LOCAL(
-      Persistent<InlineToLegacyAbstractInlineTextBoxHashMap>,
-      abstract_inline_text_box_map,
-      (MakeGarbageCollected<InlineToLegacyAbstractInlineTextBoxHashMap>()));
-  return *abstract_inline_text_box_map;
-}
-
 AbstractInlineTextBox::AbstractInlineTextBox(LineLayoutText line_layout_item)
     : line_layout_item_(line_layout_item) {}
 
@@ -74,29 +63,40 @@
 
 // ----
 
+LegacyAbstractInlineTextBox::InlineToLegacyAbstractInlineTextBoxHashMap*
+    LegacyAbstractInlineTextBox::g_abstract_inline_text_box_map_ = nullptr;
+
 scoped_refptr<AbstractInlineTextBox> LegacyAbstractInlineTextBox::GetOrCreate(
     LineLayoutText line_layout_text,
     InlineTextBox* inline_text_box) {
   if (!inline_text_box)
     return nullptr;
 
+  if (!g_abstract_inline_text_box_map_) {
+    g_abstract_inline_text_box_map_ =
+        new InlineToLegacyAbstractInlineTextBoxHashMap();
+  }
+
   InlineToLegacyAbstractInlineTextBoxHashMap::const_iterator it =
-      GetAbstractInlineTextBoxMap().find(inline_text_box);
-  if (it != GetAbstractInlineTextBoxMap().end())
+      g_abstract_inline_text_box_map_->find(inline_text_box);
+  if (it != g_abstract_inline_text_box_map_->end())
     return it->value;
 
   scoped_refptr<AbstractInlineTextBox> obj = base::AdoptRef(
       new LegacyAbstractInlineTextBox(line_layout_text, inline_text_box));
-  GetAbstractInlineTextBoxMap().Set(inline_text_box, obj);
+  g_abstract_inline_text_box_map_->Set(inline_text_box, obj);
   return obj;
 }
 
 void LegacyAbstractInlineTextBox::WillDestroy(InlineTextBox* inline_text_box) {
+  if (!g_abstract_inline_text_box_map_)
+    return;
+
   InlineToLegacyAbstractInlineTextBoxHashMap::const_iterator it =
-      GetAbstractInlineTextBoxMap().find(inline_text_box);
-  if (it != GetAbstractInlineTextBoxMap().end()) {
+      g_abstract_inline_text_box_map_->find(inline_text_box);
+  if (it != g_abstract_inline_text_box_map_->end()) {
     it->value->Detach();
-    GetAbstractInlineTextBoxMap().erase(inline_text_box);
+    g_abstract_inline_text_box_map_->erase(inline_text_box);
   }
 }
 
diff --git a/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.h b/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.h
index 26c3f98..a77dd37c 100644
--- a/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.h
+++ b/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.h
@@ -132,7 +132,12 @@
   bool IsLineBreak() const final;
   bool NeedsTrailingSpace() const final;
 
-  Persistent<InlineTextBox> inline_text_box_;
+  InlineTextBox* inline_text_box_;
+
+  typedef HashMap<InlineTextBox*, scoped_refptr<AbstractInlineTextBox>>
+      InlineToLegacyAbstractInlineTextBoxHashMap;
+  static InlineToLegacyAbstractInlineTextBoxHashMap*
+      g_abstract_inline_text_box_map_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/line/inline_box.cc b/third_party/blink/renderer/core/layout/line/inline_box.cc
index aa01e12..51891cf 100644
--- a/third_party/blink/renderer/core/layout/line/inline_box.cc
+++ b/third_party/blink/renderer/core/layout/line/inline_box.cc
@@ -39,20 +39,23 @@
 
 struct SameSizeAsInlineBox : DisplayItemClient {
   ~SameSizeAsInlineBox() override = default;
-  UntracedMember<void*> untraced_members[1];
-  Member<void*> members[3];
+  void* a[4];
   LayoutPoint b;
   LayoutUnit c;
   uint32_t bitfields;
+#if DCHECK_IS_ON()
+  bool f;
+#endif
 };
 
 ASSERT_SIZE(InlineBox, SameSizeAsInlineBox);
 
-void InlineBox::Trace(Visitor* visitor) const {
-  visitor->Trace(next_);
-  visitor->Trace(prev_);
-  visitor->Trace(parent_);
+#if DCHECK_IS_ON()
+InlineBox::~InlineBox() {
+  if (!has_bad_parent_ && parent_)
+    parent_->SetHasBadChildList();
 }
+#endif
 
 DISABLE_CFI_PERF
 void InlineBox::Destroy() {
@@ -64,6 +67,8 @@
     // TODO(crbug.com/619630): Make this fast.
     line_layout_item_.SlowSetPaintingLayerNeedsRepaint();
   }
+
+  delete this;
 }
 
 void InlineBox::Remove(MarkLineBoxes mark_line_boxes) {
@@ -71,6 +76,15 @@
     Parent()->RemoveChild(this, mark_line_boxes);
 }
 
+void* InlineBox::operator new(size_t sz) {
+  return WTF::Partitions::LayoutPartition()->Alloc(
+      sz, WTF_HEAP_PROFILER_TYPE_NAME(InlineBox));
+}
+
+void InlineBox::operator delete(void* ptr) {
+  WTF::Partitions::LayoutPartition()->Free(ptr);
+}
+
 const char* InlineBox::BoxName() const {
   return "InlineBox";
 }
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 346a27d..4bec348 100644
--- a/third_party/blink/renderer/core/layout/line/inline_box.h
+++ b/third_party/blink/renderer/core/layout/line/inline_box.h
@@ -42,15 +42,9 @@
 
 // InlineBox represents a rectangle that occurs on a line.  It corresponds to
 // some LayoutObject (i.e., it represents a portion of that LayoutObject).
-class CORE_EXPORT InlineBox : public GarbageCollected<InlineBox>,
-                              public DisplayItemClient {
+class CORE_EXPORT InlineBox : public DisplayItemClient {
  public:
-  InlineBox(LineLayoutItem obj)
-      : next_(nullptr),
-        prev_(nullptr),
-        parent_(nullptr),
-        line_layout_item_(obj),
-        logical_width_() {}
+  InlineBox(LineLayoutItem obj) : line_layout_item_(obj), logical_width_() {}
 
   InlineBox(LineLayoutItem item,
             LayoutPoint top_left,
@@ -73,7 +67,7 @@
 
   InlineBox(const InlineBox&) = delete;
   InlineBox& operator=(const InlineBox&) = delete;
-  virtual void Trace(Visitor*) const;
+  ~InlineBox() override;
 
   virtual void Destroy();
 
@@ -110,6 +104,10 @@
                            LayoutUnit line_top,
                            LayoutUnit line_bottom);
 
+  // InlineBoxes are allocated out of the rendering partition.
+  void* operator new(size_t);
+  void operator delete(void*);
+
 #if DCHECK_IS_ON()
   void ShowTreeForThis() const;
   void ShowLineTreeForThis() const;
@@ -197,6 +195,9 @@
   LineLayoutItem GetLineLayoutItem() const { return line_layout_item_; }
 
   InlineFlowBox* Parent() const {
+#if DCHECK_IS_ON()
+    DCHECK(!has_bad_parent_);
+#endif
     return parent_;
   }
 
@@ -457,10 +458,10 @@
  private:
   void SetLineLayoutItemShouldDoFullPaintInvalidationIfNeeded();
 
-  Member<InlineBox> next_;  // The next element on the same line as us.
-  Member<InlineBox> prev_;  // The previous element on the same line as us.
+  InlineBox* next_ = nullptr;  // The next element on the same line as us.
+  InlineBox* prev_ = nullptr;  // The previous element on the same line as us.
 
-  Member<InlineFlowBox> parent_;  // The box that contains us.
+  InlineFlowBox* parent_ = nullptr;  // The box that contains us.
   LineLayoutItem line_layout_item_;
 
  protected:
@@ -496,8 +497,22 @@
 
  private:
   InlineBoxBitfields bitfields_;
+
+#if DCHECK_IS_ON()
+  bool has_bad_parent_ = false;
+#endif
 };
 
+#if !DCHECK_IS_ON()
+inline InlineBox::~InlineBox() {}
+#endif
+
+#if DCHECK_IS_ON()
+inline void InlineBox::SetHasBadParent() {
+  has_bad_parent_ = true;
+}
+#endif
+
 // Allow equality comparisons of InlineBox's by reference or pointer,
 // interchangeably.
 DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES(InlineBox)
diff --git a/third_party/blink/renderer/core/layout/line/inline_flow_box.cc b/third_party/blink/renderer/core/layout/line/inline_flow_box.cc
index 520085f..f98ae0fa 100644
--- a/third_party/blink/renderer/core/layout/line/inline_flow_box.cc
+++ b/third_party/blink/renderer/core/layout/line/inline_flow_box.cc
@@ -47,24 +47,17 @@
 namespace blink {
 
 struct SameSizeAsInlineFlowBox : public InlineBox {
-  void* pointers[1];
-  Member<void*> members[4];
+  void* pointers[5];
   uint32_t bitfields : 23;
 };
 
 ASSERT_SIZE(InlineFlowBox, SameSizeAsInlineFlowBox);
 
-void InlineFlowBox::Trace(Visitor* visitor) const {
-  visitor->Trace(first_child_);
-  visitor->Trace(last_child_);
-  visitor->Trace(prev_line_box_);
-  visitor->Trace(next_line_box_);
-  InlineBox::Trace(visitor);
-}
-
 #if DCHECK_IS_ON()
-void InlineFlowBox::Destroy() {
-  InlineBox::Destroy();
+InlineFlowBox::~InlineFlowBox() {
+  if (!has_bad_child_list_)
+    for (InlineBox* child = FirstChild(); child; child = child->NextOnLine())
+      child->SetHasBadParent();
 }
 #endif
 
diff --git a/third_party/blink/renderer/core/layout/line/inline_flow_box.h b/third_party/blink/renderer/core/layout/line/inline_flow_box.h
index 6e0684de..00fd78be 100644
--- a/third_party/blink/renderer/core/layout/line/inline_flow_box.h
+++ b/third_party/blink/renderer/core/layout/line/inline_flow_box.h
@@ -39,8 +39,8 @@
 
 struct GlyphOverflow;
 
-typedef HeapHashMap<Member<const InlineTextBox>,
-                    std::pair<Vector<const SimpleFontData*>, GlyphOverflow>>
+typedef HashMap<const InlineTextBox*,
+                std::pair<Vector<const SimpleFontData*>, GlyphOverflow>>
     GlyphOverflowAndFallbackFontsMap;
 
 class InlineFlowBox : public InlineBox {
@@ -61,6 +61,10 @@
         line_break_bidi_status_last_strong_(WTF::unicode::kLeftToRight),
         line_break_bidi_status_last_(WTF::unicode::kLeftToRight),
         is_first_after_page_break_(false)
+#if DCHECK_IS_ON()
+        ,
+        has_bad_child_list_(false)
+#endif
   {
     // Internet Explorer and Firefox always create a marker for list items, even
     // when the list-style-type is none.  We do not make a marker in the
@@ -76,10 +80,8 @@
     has_text_descendants_ = has_text_children_;
   }
 
-  void Trace(Visitor*) const override;
-
 #if DCHECK_IS_ON()
-  void Destroy() override;
+  ~InlineFlowBox() override;
 
   void DumpLineTreeAndMark(StringBuilder&,
                            const InlineBox* = nullptr,
@@ -467,14 +469,14 @@
 
   bool IsInlineFlowBox() const final { return true; }
 
-  Member<InlineBox> first_child_;
-  Member<InlineBox> last_child_;
+  InlineBox* first_child_;
+  InlineBox* last_child_;
 
   // The next/previous box that also uses our LayoutObject.
   // RootInlineBox, a subclass of this class, uses these fields for
   // next/previous RootInlineBox.
-  Member<InlineFlowBox> prev_line_box_;
-  Member<InlineFlowBox> next_line_box_;
+  InlineFlowBox* prev_line_box_;
+  InlineFlowBox* next_line_box_;
 
  private:
   unsigned include_logical_left_edge_ : 1;
@@ -502,6 +504,11 @@
   unsigned is_first_after_page_break_ : 1;
 
 // End of RootInlineBox-specific members.
+
+#if DCHECK_IS_ON()
+ private:
+  unsigned has_bad_child_list_ : 1;
+#endif
 };
 
 template <>
@@ -509,6 +516,12 @@
   static bool AllowFrom(const InlineBox& box) { return box.IsInlineFlowBox(); }
 };
 
+inline void InlineFlowBox::SetHasBadChildList() {
+#if DCHECK_IS_ON()
+  has_bad_child_list_ = true;
+#endif
+}
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LINE_INLINE_FLOW_BOX_H_
diff --git a/third_party/blink/renderer/core/layout/line/inline_iterator.h b/third_party/blink/renderer/core/layout/line/inline_iterator.h
index 1a7dab8..022d840 100644
--- a/third_party/blink/renderer/core/layout/line/inline_iterator.h
+++ b/third_party/blink/renderer/core/layout/line/inline_iterator.h
@@ -41,7 +41,7 @@
   BidiIsolatedRun(LineLayoutItem object,
                   unsigned position,
                   LineLayoutItem& root,
-                  BidiRun* run_to_replace,
+                  BidiRun& run_to_replace,
                   unsigned char level)
       : object(object),
         root(root),
@@ -49,11 +49,9 @@
         position(position),
         level(level) {}
 
-  void Trace(Visitor* visitor) const { visitor->Trace(run_to_replace); }
-
   LineLayoutItem object;
   LineLayoutItem root;
-  Member<BidiRun> run_to_replace;
+  BidiRun& run_to_replace;
   unsigned position;
   unsigned char level;
 };
@@ -602,7 +600,7 @@
     BidiContext* context,
     TextDirection direction) const {
   DCHECK(context);
-  BidiRun* new_trailing_run = MakeGarbageCollected<BidiRun>(
+  BidiRun* new_trailing_run = new BidiRun(
       context->Override(), context->Level(), start, stop,
       run->line_layout_item_, WTF::unicode::kOtherNeutral, context->Dir());
   if (direction == TextDirection::kLtr)
@@ -663,15 +661,15 @@
     unsigned pos,
     LineLayoutItem root) {
   DCHECK(obj);
-  BidiRun* isolated_run = MakeGarbageCollected<BidiRun>(
-      resolver.Context()->Override(), resolver.Context()->Level(), pos, pos,
-      obj, resolver.Dir(), resolver.Context()->Dir());
+  BidiRun* isolated_run =
+      new BidiRun(resolver.Context()->Override(), resolver.Context()->Level(),
+                  pos, pos, obj, resolver.Dir(), resolver.Context()->Dir());
   resolver.Runs().AddRun(isolated_run);
   // FIXME: isolatedRuns() could be a hash of object->run and then we could
   // cheaply ASSERT here that we didn't create multiple objects for the same
   // inline.
   resolver.IsolatedRuns().push_back(BidiIsolatedRun(
-      obj, pos, root, isolated_run, resolver.Context()->Level()));
+      obj, pos, root, *isolated_run, resolver.Context()->Level()));
   return isolated_run;
 }
 
@@ -679,9 +677,9 @@
                                  int end,
                                  LineLayoutItem obj,
                                  InlineBidiResolver& resolver) {
-  return MakeGarbageCollected<BidiRun>(
-      resolver.Context()->Override(), resolver.Context()->Level(), start, end,
-      obj, resolver.Dir(), resolver.Context()->Dir());
+  return new BidiRun(resolver.Context()->Override(),
+                     resolver.Context()->Level(), start, end, obj,
+                     resolver.Dir(), resolver.Context()->Dir());
 }
 
 enum AppendRunBehavior { kAppendingFakeRun, kAppendingRunsForObject };
diff --git a/third_party/blink/renderer/core/layout/line/inline_text_box.cc b/third_party/blink/renderer/core/layout/line/inline_text_box.cc
index 9f0f3c2e..21ea87e 100644
--- a/third_party/blink/renderer/core/layout/line/inline_text_box.cc
+++ b/third_party/blink/renderer/core/layout/line/inline_text_box.cc
@@ -49,31 +49,19 @@
 struct SameSizeAsInlineTextBox : public InlineBox {
   unsigned variables[1];
   uint16_t variables2[2];
-  Member<void*> members[2];
+  void* pointers[2];
 };
 
 ASSERT_SIZE(InlineTextBox, SameSizeAsInlineTextBox);
 
-typedef HeapHashMap<Member<const InlineTextBox>, LayoutRect>
-    InlineTextBoxOverflowMap;
-InlineTextBoxOverflowMap& GetTextBoxesWithOverflow() {
-  DEFINE_STATIC_LOCAL(Persistent<InlineTextBoxOverflowMap>,
-                      text_boxes_with_overflow,
-                      (MakeGarbageCollected<InlineTextBoxOverflowMap>()));
-  return *text_boxes_with_overflow;
-}
-
-void InlineTextBox::Trace(Visitor* visitor) const {
-  visitor->Trace(prev_text_box_);
-  visitor->Trace(next_text_box_);
-  InlineBox::Trace(visitor);
-}
+typedef WTF::HashMap<const InlineTextBox*, LayoutRect> InlineTextBoxOverflowMap;
+static InlineTextBoxOverflowMap* g_text_boxes_with_overflow;
 
 void InlineTextBox::Destroy() {
   LegacyAbstractInlineTextBox::WillDestroy(this);
 
-  if (!KnownToHaveNoOverflow())
-    GetTextBoxesWithOverflow().erase(this);
+  if (!KnownToHaveNoOverflow() && g_text_boxes_with_overflow)
+    g_text_boxes_with_overflow->erase(this);
   InlineBox::Destroy();
 }
 
@@ -89,11 +77,11 @@
 }
 
 LayoutRect InlineTextBox::LogicalOverflowRect() const {
-  if (KnownToHaveNoOverflow())
+  if (KnownToHaveNoOverflow() || !g_text_boxes_with_overflow)
     return LogicalFrameRect();
 
-  const auto& it = GetTextBoxesWithOverflow().find(this);
-  if (it != GetTextBoxesWithOverflow().end())
+  const auto& it = g_text_boxes_with_overflow->find(this);
+  if (it != g_text_boxes_with_overflow->end())
     return it->value;
 
   return LogicalFrameRect();
@@ -102,7 +90,9 @@
 void InlineTextBox::SetLogicalOverflowRect(const LayoutRect& rect) {
   DCHECK(!KnownToHaveNoOverflow());
   DCHECK(rect != LogicalFrameRect());
-  GetTextBoxesWithOverflow().Set(this, rect);
+  if (!g_text_boxes_with_overflow)
+    g_text_boxes_with_overflow = new InlineTextBoxOverflowMap;
+  g_text_boxes_with_overflow->Set(this, rect);
 }
 
 PhysicalRect InlineTextBox::PhysicalOverflowRect() const {
@@ -116,9 +106,9 @@
 void InlineTextBox::Move(const LayoutSize& delta) {
   InlineBox::Move(delta);
 
-  if (!KnownToHaveNoOverflow()) {
-    const auto& it = GetTextBoxesWithOverflow().find(this);
-    if (it != GetTextBoxesWithOverflow().end())
+  if (!KnownToHaveNoOverflow() && g_text_boxes_with_overflow) {
+    const auto& it = g_text_boxes_with_overflow->find(this);
+    if (it != g_text_boxes_with_overflow->end())
       it->value.Move(IsHorizontal() ? delta : delta.TransposedSize());
   }
 }
@@ -745,8 +735,8 @@
 
   SetLogicalWidth(logical_width);
 
-  if (!KnownToHaveNoOverflow())
-    GetTextBoxesWithOverflow().erase(this);
+  if (!KnownToHaveNoOverflow() && g_text_boxes_with_overflow)
+    g_text_boxes_with_overflow->erase(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/line/inline_text_box.h b/third_party/blink/renderer/core/layout/line/inline_text_box.h
index e511701..e3353cf 100644
--- a/third_party/blink/renderer/core/layout/line/inline_text_box.h
+++ b/third_party/blink/renderer/core/layout/line/inline_text_box.h
@@ -49,13 +49,11 @@
     SetIsText(true);
   }
 
-  void Trace(Visitor*) const override;
-
   LineLayoutText GetLineLayoutItem() const {
     return LineLayoutText(InlineBox::GetLineLayoutItem());
   }
 
-  void Destroy() override;
+  void Destroy() final;
 
   InlineTextBox* PrevForSameLayoutObject() const { return prev_text_box_; }
   InlineTextBox* NextForSameLayoutObject() const { return next_text_box_; }
@@ -223,8 +221,8 @@
 
  private:
   // The next/previous box that also uses our LayoutObject.
-  Member<InlineTextBox> prev_text_box_;
-  Member<InlineTextBox> next_text_box_;
+  InlineTextBox* prev_text_box_ = nullptr;
+  InlineTextBox* next_text_box_ = nullptr;
 
   int start_;
   uint16_t len_;
diff --git a/third_party/blink/renderer/core/layout/line/inline_text_box_test.cc b/third_party/blink/renderer/core/layout/line/inline_text_box_test.cc
index a7e74fa..69caeb4f 100644
--- a/third_party/blink/renderer/core/layout/line/inline_text_box_test.cc
+++ b/third_party/blink/renderer/core/layout/line/inline_text_box_test.cc
@@ -16,16 +16,12 @@
   TestInlineTextBox(LineLayoutItem item) : InlineTextBox(item, 0, 0) {
     SetHasVirtualLogicalHeight();
   }
-  void Destroy() override {
-    InlineTextBox::Destroy();
-    GetLineLayoutItem().GetLayoutObject()->Destroy();
-  }
 
   static TestInlineTextBox* Create(Document& document, const String& string) {
     Text* node = document.createTextNode(string);
-    LayoutText* text = MakeGarbageCollected<LayoutText>(node, string.Impl());
+    LayoutText* text = new LayoutText(node, string.Impl());
     text->SetStyle(document.GetStyleResolver().CreateComputedStyle());
-    return MakeGarbageCollected<TestInlineTextBox>(LineLayoutItem(text));
+    return new TestInlineTextBox(LineLayoutItem(text));
   }
 
   LayoutUnit VirtualLogicalHeight() const override { return logical_height_; }
@@ -83,8 +79,6 @@
 
   // Ensure it's still movable correctly.
   MoveAndTest(box, move, frame, overflow);
-
-  box->Destroy();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/line/line_box_list.cc b/third_party/blink/renderer/core/layout/line/line_box_list.cc
index c333ac1c..ed92984 100644
--- a/third_party/blink/renderer/core/layout/line/line_box_list.cc
+++ b/third_party/blink/renderer/core/layout/line/line_box_list.cc
@@ -40,12 +40,6 @@
 
 namespace blink {
 
-template <typename InlineBoxType>
-void InlineBoxList<InlineBoxType>::Trace(Visitor* visitor) const {
-  visitor->Trace(first_);
-  visitor->Trace(last_);
-}
-
 #if DCHECK_IS_ON()
 template <typename InlineBoxType>
 void InlineBoxList<InlineBoxType>::AssertIsEmpty() {
diff --git a/third_party/blink/renderer/core/layout/line/line_box_list.h b/third_party/blink/renderer/core/layout/line/line_box_list.h
index a65d74dc..a91eb99 100644
--- a/third_party/blink/renderer/core/layout/line/line_box_list.h
+++ b/third_party/blink/renderer/core/layout/line/line_box_list.h
@@ -32,7 +32,6 @@
 #include "base/dcheck_is_on.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/layout/api/hit_test_action.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 namespace blink {
@@ -53,7 +52,6 @@
 
  public:
   InlineBoxList() : first_(nullptr), last_(nullptr) {}
-  void Trace(Visitor*) const;
 
 #if DCHECK_IS_ON()
   // Owners should check this on destructor. This class does not implement
@@ -136,8 +134,8 @@
   // For block flows, each box represents the root inline box for a line in the
   // paragraph.
   // For inline flows, each box represents a portion of that inline.
-  Member<InlineBoxType> first_;
-  Member<InlineBoxType> last_;
+  InlineBoxType* first_ = nullptr;
+  InlineBoxType* last_ = nullptr;
 };
 
 extern template class CORE_EXTERN_TEMPLATE_EXPORT InlineBoxList<InlineFlowBox>;
diff --git a/third_party/blink/renderer/core/layout/line/root_inline_box.cc b/third_party/blink/renderer/core/layout/line/root_inline_box.cc
index 54187317..3d77295 100644
--- a/third_party/blink/renderer/core/layout/line/root_inline_box.cc
+++ b/third_party/blink/renderer/core/layout/line/root_inline_box.cc
@@ -40,21 +40,14 @@
 
 struct SameSizeAsRootInlineBox : public InlineFlowBox {
   unsigned unsigned_variable;
-  void* pointers[2];
-  UntracedMember<void*> members[1];
+  void* pointers[3];
   LayoutUnit layout_variables[6];
 };
 
 ASSERT_SIZE(RootInlineBox, SameSizeAsRootInlineBox);
 
-typedef HeapHashMap<Member<const RootInlineBox>, Member<EllipsisBox>>
-    EllipsisBoxMap;
-
-EllipsisBoxMap& GetEllipsisBoxMap() {
-  DEFINE_STATIC_LOCAL(Persistent<EllipsisBoxMap>, ellipsis_box_map,
-                      (MakeGarbageCollected<EllipsisBoxMap>()));
-  return *ellipsis_box_map;
-}
+typedef WTF::HashMap<const RootInlineBox*, EllipsisBox*> EllipsisBoxMap;
+static EllipsisBoxMap* g_ellipsis_box_map = nullptr;
 
 RootInlineBox::RootInlineBox(LineLayoutItem block)
     : InlineFlowBox(block), line_break_pos_(0), line_break_obj_(nullptr) {
@@ -68,7 +61,7 @@
 
 void RootInlineBox::DetachEllipsisBox() {
   if (HasEllipsisBox()) {
-    EllipsisBox* box = GetEllipsisBoxMap().Take(this);
+    EllipsisBox* box = g_ellipsis_box_map->Take(this);
     box->SetParent(nullptr);
     box->Destroy();
     SetHasEllipsisBox(false);
@@ -127,11 +120,13 @@
   // Create an ellipsis box if we don't already have one. If we already have one
   // we're just here to blank out (truncate) the text boxes.
   if (!*found_box) {
-    EllipsisBox* ellipsis_box = MakeGarbageCollected<EllipsisBox>(
+    EllipsisBox* ellipsis_box = new EllipsisBox(
         GetLineLayoutItem(), ellipsis_str, this, ellipsis_width,
         LogicalHeight(), Location(), !PrevRootBox(), IsHorizontal());
 
-    GetEllipsisBoxMap().insert(this, ellipsis_box);
+    if (!g_ellipsis_box_map)
+      g_ellipsis_box_map = new EllipsisBoxMap();
+    g_ellipsis_box_map->insert(this, ellipsis_box);
     SetHasEllipsisBox(true);
   }
 
@@ -514,7 +509,7 @@
 EllipsisBox* RootInlineBox::GetEllipsisBox() const {
   if (!HasEllipsisBox())
     return nullptr;
-  return GetEllipsisBoxMap().at(this);
+  return g_ellipsis_box_map->at(this);
 }
 
 void RootInlineBox::RemoveLineBoxFromLayoutObject() {
@@ -755,7 +750,7 @@
 }
 
 void RootInlineBox::CollectLeafBoxesInLogicalOrder(
-    HeapVector<Member<InlineBox>>& leaf_boxes_in_logical_order,
+    Vector<InlineBox*>& leaf_boxes_in_logical_order,
     CustomInlineBoxRangeReverse custom_reverse_implementation) const {
   InlineBox* leaf = FirstLeafChild();
 
@@ -786,24 +781,22 @@
   if (!(min_level % 2))
     ++min_level;
 
-  HeapVector<Member<InlineBox>>::iterator end =
-      leaf_boxes_in_logical_order.end();
+  Vector<InlineBox*>::iterator end = leaf_boxes_in_logical_order.end();
   while (min_level <= max_level) {
-    HeapVector<Member<InlineBox>>::iterator it =
-        leaf_boxes_in_logical_order.begin();
+    Vector<InlineBox*>::iterator it = leaf_boxes_in_logical_order.begin();
     while (it != end) {
       while (it != end) {
         if ((*it)->BidiLevel() >= min_level)
           break;
         ++it;
       }
-      HeapVector<Member<InlineBox>>::iterator first = it;
+      Vector<InlineBox*>::iterator first = it;
       while (it != end) {
         if ((*it)->BidiLevel() < min_level)
           break;
         ++it;
       }
-      HeapVector<Member<InlineBox>>::iterator last = it;
+      Vector<InlineBox*>::iterator last = it;
       if (custom_reverse_implementation)
         (*custom_reverse_implementation)(first, last);
       else
@@ -814,7 +807,7 @@
 }
 
 const InlineBox* RootInlineBox::GetLogicalStartNonPseudoBox() const {
-  HeapVector<Member<InlineBox>> leaf_boxes_in_logical_order;
+  Vector<InlineBox*> leaf_boxes_in_logical_order;
   CollectLeafBoxesInLogicalOrder(leaf_boxes_in_logical_order);
   for (InlineBox* box : leaf_boxes_in_logical_order) {
     if (box->GetLineLayoutItem().NonPseudoNode())
@@ -824,7 +817,7 @@
 }
 
 const InlineBox* RootInlineBox::GetLogicalEndNonPseudoBox() const {
-  HeapVector<Member<InlineBox>> leaf_boxes_in_logical_order;
+  Vector<InlineBox*> leaf_boxes_in_logical_order;
   CollectLeafBoxesInLogicalOrder(leaf_boxes_in_logical_order);
   for (wtf_size_t i = leaf_boxes_in_logical_order.size(); i > 0; --i) {
     if (leaf_boxes_in_logical_order[i - 1]
diff --git a/third_party/blink/renderer/core/layout/line/root_inline_box.h b/third_party/blink/renderer/core/layout/line/root_inline_box.h
index 14c859d..5db881e 100644
--- a/third_party/blink/renderer/core/layout/line/root_inline_box.h
+++ b/third_party/blink/renderer/core/layout/line/root_inline_box.h
@@ -48,10 +48,10 @@
   void DetachEllipsisBox();
 
   RootInlineBox* NextRootBox() const {
-    return static_cast<RootInlineBox*>(next_line_box_.Get());
+    return static_cast<RootInlineBox*>(next_line_box_);
   }
   RootInlineBox* PrevRootBox() const {
-    return static_cast<RootInlineBox*>(prev_line_box_.Get());
+    return static_cast<RootInlineBox*>(prev_line_box_);
   }
 
   void Move(const LayoutSize&) final;
@@ -158,15 +158,13 @@
 
   void AppendFloat(LayoutBox* floating_box) {
     DCHECK(!IsDirty());
-    if (floats_) {
+    if (floats_)
       floats_->push_back(floating_box);
-    } else {
-      floats_ =
-          std::make_unique<Vector<UntracedMember<LayoutBox>>>(1, floating_box);
-    }
+    else
+      floats_ = std::make_unique<Vector<LayoutBox*>>(1, floating_box);
   }
 
-  Vector<UntracedMember<LayoutBox>>* FloatsPtr() {
+  Vector<LayoutBox*>* FloatsPtr() {
     DCHECK(!IsDirty());
     return floats_.get();
   }
@@ -207,10 +205,10 @@
   }
 
   typedef void (*CustomInlineBoxRangeReverse)(
-      HeapVector<Member<InlineBox>>::iterator first,
-      HeapVector<Member<InlineBox>>::iterator last);
+      Vector<InlineBox*>::iterator first,
+      Vector<InlineBox*>::iterator last);
   void CollectLeafBoxesInLogicalOrder(
-      HeapVector<Member<InlineBox>>&,
+      Vector<InlineBox*>&,
       CustomInlineBoxRangeReverse custom_reverse_implementation =
           nullptr) const;
 
@@ -233,7 +231,7 @@
 
   // Floats hanging off the line are pushed into this vector during layout. It
   // is only good for as long as the line has not been marked dirty.
-  std::unique_ptr<Vector<UntracedMember<LayoutBox>>> floats_;
+  std::unique_ptr<Vector<LayoutBox*>> floats_;
 
   LayoutUnit line_top_;
   LayoutUnit line_bottom_;
diff --git a/third_party/blink/renderer/core/layout/list_marker.cc b/third_party/blink/renderer/core/layout/list_marker.cc
index 5a510e0..398cc5f3 100644
--- a/third_party/blink/renderer/core/layout/list_marker.cc
+++ b/third_party/blink/renderer/core/layout/list_marker.cc
@@ -125,10 +125,10 @@
   }
 }
 
-void ListMarker::UpdateMarkerText(LayoutObject& marker, LayoutText* text) {
+void ListMarker::UpdateMarkerText(LayoutObject& marker) {
   DCHECK_EQ(Get(&marker), this);
-  DCHECK(text);
   DCHECK_EQ(marker_text_type_, kUnresolved);
+  LayoutText* const text = To<LayoutText>(marker.SlowFirstChild());
   StringBuilder marker_text_builder;
   marker_text_type_ =
       MarkerText(marker, &marker_text_builder, kWithPrefixSuffix);
@@ -137,11 +137,6 @@
   DCHECK_NE(marker_text_type_, kUnresolved);
 }
 
-void ListMarker::UpdateMarkerText(LayoutObject& marker) {
-  DCHECK_EQ(Get(&marker), this);
-  UpdateMarkerText(marker, To<LayoutText>(marker.SlowFirstChild()));
-}
-
 ListMarker::MarkerTextType ListMarker::MarkerText(
     const LayoutObject& marker,
     StringBuilder* text,
@@ -262,7 +257,7 @@
           LayoutListMarkerImage::CreateAnonymous(&marker.GetDocument());
       if (marker.IsLayoutNGListMarker())
         image->SetIsLayoutNGObjectForListMarkerImage(true);
-      ComputedStyle* image_style =
+      scoped_refptr<ComputedStyle> image_style =
           marker.GetDocument()
               .GetStyleResolver()
               .CreateAnonymousStyleWithDisplay(marker.StyleRef(),
@@ -283,29 +278,21 @@
     return;
   }
 
-  // Create a LayoutText in it.
-  LayoutText* text = nullptr;
   // |text_style| should be as same as style propagated in
   // |LayoutObject::PropagateStyleToAnonymousChildren()| to avoid unexpected
   // full layout due by style difference. See http://crbug.com/980399
-  ComputedStyle* text_style =
+  scoped_refptr<ComputedStyle> text_style =
       marker.GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
           marker.StyleRef(), marker.StyleRef().Display());
-  if (child) {
-    if (child->IsText()) {
-      text = To<LayoutText>(child);
-      text->SetStyle(text_style);
-    } else {
-      child->Destroy();
-      child = nullptr;
-    }
-  }
-  if (!child) {
-    text = LayoutText::CreateEmptyAnonymous(marker.GetDocument(), text_style,
-                                            LegacyLayout::kAuto);
-    marker.AddChild(text);
-    marker_text_type_ = kUnresolved;
-  }
+  if (IsA<LayoutText>(child))
+    return child->SetStyle(text_style);
+  if (child)
+    child->Destroy();
+
+  auto* const new_text = LayoutText::CreateEmptyAnonymous(
+      marker.GetDocument(), text_style, LegacyLayout::kAuto);
+  marker.AddChild(new_text);
+  marker_text_type_ = kUnresolved;
 }
 
 LayoutObject* ListMarker::SymbolMarkerLayoutText(
diff --git a/third_party/blink/renderer/core/layout/list_marker.h b/third_party/blink/renderer/core/layout/list_marker.h
index e9ed1b3..9523773 100644
--- a/third_party/blink/renderer/core/layout/list_marker.h
+++ b/third_party/blink/renderer/core/layout/list_marker.h
@@ -90,7 +90,6 @@
                             StringBuilder*,
                             MarkerTextFormat) const;
   void UpdateMarkerText(LayoutObject&);
-  void UpdateMarkerText(LayoutObject&, LayoutText*);
 
   void ListStyleTypeChanged(LayoutObject&);
   void OrdinalValueChanged(LayoutObject&);
diff --git a/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.cc b/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.cc
index e2c44bd..aee79c33 100644
--- a/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.cc
+++ b/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.cc
@@ -615,8 +615,8 @@
 
 MultiColumnFragmentainerGroupList::MultiColumnFragmentainerGroupList(
     LayoutMultiColumnSet& column_set)
-    : column_set_(&column_set) {
-  Append(MultiColumnFragmentainerGroup(*column_set_));
+    : column_set_(column_set) {
+  Append(MultiColumnFragmentainerGroup(column_set_));
 }
 
 // An explicit empty destructor of MultiColumnFragmentainerGroupList should be
@@ -631,7 +631,7 @@
 
 MultiColumnFragmentainerGroup&
 MultiColumnFragmentainerGroupList::AddExtraGroup() {
-  Append(MultiColumnFragmentainerGroup(*column_set_));
+  Append(MultiColumnFragmentainerGroup(column_set_));
   return Last();
 }
 
diff --git a/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h b/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h
index dd65564..67866cd 100644
--- a/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h
+++ b/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h
@@ -180,7 +180,7 @@
 
   unsigned UnclampedActualColumnCount() const;
 
-  const UntracedMember<const LayoutMultiColumnSet> column_set_;
+  const LayoutMultiColumnSet* const column_set_;
 
   LayoutUnit logical_top_;
   LayoutUnit logical_top_in_flow_thread_;
@@ -243,7 +243,7 @@
   void Shrink(wtf_size_t size) { groups_.Shrink(size); }
 
  private:
-  UntracedMember<LayoutMultiColumnSet> column_set_;
+  LayoutMultiColumnSet& column_set_;
 
   Vector<MultiColumnFragmentainerGroup, 1> groups_;
 };
diff --git a/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group_test.cc b/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group_test.cc
index a58d231d..ed3dea2 100644
--- a/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group_test.cc
+++ b/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group_test.cc
@@ -27,15 +27,16 @@
   static int GroupCount(const MultiColumnFragmentainerGroupList&);
 
  private:
-  Persistent<LayoutMultiColumnFlowThread> flow_thread_;
-  Persistent<LayoutMultiColumnSet> column_set_;
+  LayoutMultiColumnFlowThread* flow_thread_;
+  LayoutMultiColumnSet* column_set_;
 };
 
 void MultiColumnFragmentainerGroupTest::SetUp() {
   RenderingTest::SetUp();
-  ComputedStyle* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style =
+      GetDocument().GetStyleResolver().CreateComputedStyle();
   flow_thread_ = LayoutMultiColumnFlowThread::CreateAnonymous(
-      GetDocument(), *style, /* needs_paint_layer */ true);
+      GetDocument(), *style.get(), /* needs_paint_layer */ true);
   column_set_ = LayoutMultiColumnSet::CreateAnonymous(*flow_thread_,
                                                       *flow_thread_->Style());
 }
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc
index 7e8ef4d..dad70ce 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc
+++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc
@@ -90,7 +90,6 @@
 }
 
 void CustomLayoutChild::Trace(Visitor* visitor) const {
-  visitor->Trace(node_);
   visitor->Trace(style_map_);
   visitor->Trace(token_);
   ScriptWrappable::Trace(visitor);
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc
index c6f80df3f..60cecbc6 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc
@@ -13,7 +13,7 @@
 CustomLayoutFragment::CustomLayoutFragment(
     CustomLayoutChild* child,
     CustomLayoutToken* token,
-    const NGLayoutResult* layout_result,
+    scoped_refptr<const NGLayoutResult> layout_result,
     const LogicalSize& size,
     const base::Optional<LayoutUnit> baseline,
     v8::Isolate* isolate)
@@ -56,7 +56,6 @@
 void CustomLayoutFragment::Trace(Visitor* visitor) const {
   visitor->Trace(child_);
   visitor->Trace(token_);
-  visitor->Trace(layout_result_);
   visitor->Trace(layout_worklet_world_v8_data_);
   ScriptWrappable::Trace(visitor);
 }
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h
index a44ef2d..40438b03 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h
@@ -37,7 +37,7 @@
  public:
   CustomLayoutFragment(CustomLayoutChild*,
                        CustomLayoutToken*,
-                       const NGLayoutResult*,
+                       scoped_refptr<const NGLayoutResult>,
                        const LogicalSize& size,
                        const base::Optional<LayoutUnit> baseline,
                        v8::Isolate*);
@@ -83,7 +83,7 @@
   // that the last layout on the child wasn't with the same inputs, and force a
   // layout again.
 
-  Member<const NGLayoutResult> layout_result_;
+  scoped_refptr<const NGLayoutResult> layout_result_;
 
   // The inline and block size on this object should never change.
   const double inline_size_;
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc
index eac194b..9609cd0 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc
+++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.cc
@@ -135,8 +135,7 @@
   if (child.IsLayoutNGCustom())
     builder.SetCustomLayoutData(std::move(constraint_data_));
   auto space = builder.ToConstraintSpace();
-  auto* result =
-      To<NGBlockNode>(child).Layout(space, nullptr /* break_token */);
+  auto result = To<NGBlockNode>(child).Layout(space, nullptr /* break_token */);
 
   NGBoxFragment fragment(parent_space.GetWritingDirection(),
                          To<NGPhysicalBoxFragment>(result->PhysicalFragment()));
diff --git a/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc
index 43533c6b..3cb3d8dd 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.cc
@@ -77,7 +77,7 @@
   return MinMaxSizesResult(sizes, depends_on_block_constraints);
 }
 
-const NGLayoutResult* NGCustomLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGCustomLayoutAlgorithm::Layout() {
   DCHECK(!BreakToken());
 
   if (!Node().IsCustomLayoutLoaded())
@@ -201,7 +201,7 @@
   return NGBlockLayoutAlgorithm(params_).ComputeMinMaxSizes(input);
 }
 
-const NGLayoutResult* NGCustomLayoutAlgorithm::FallbackLayout() {
+scoped_refptr<const NGLayoutResult> NGCustomLayoutAlgorithm::FallbackLayout() {
   return NGBlockLayoutAlgorithm(params_).Layout();
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h
index 23750ef..36b2a30 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h
@@ -22,12 +22,12 @@
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override;
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 
  private:
   void AddAnyOutOfFlowPositionedChildren(NGLayoutInputNode* child);
   MinMaxSizesResult FallbackMinMaxSizes(const MinMaxSizesFloatInput&) const;
-  const NGLayoutResult* FallbackLayout();
+  scoped_refptr<const NGLayoutResult> FallbackLayout();
 
   const NGLayoutAlgorithmParams& params_;
 };
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion.cc b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion.cc
index 9f19e1f..d0d4e64 100644
--- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion.cc
+++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion.cc
@@ -3,14 +3,9 @@
 // found in the LICENSE file.
 
 #include "third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion.h"
-#include "third_party/blink/renderer/core/layout/layout_box.h"
 
 namespace blink {
 
-void NGExclusionShapeData::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_box);
-}
-
 bool NGExclusion::operator==(const NGExclusion& other) const {
   return type == other.type && rect == other.rect &&
          shape_data == other.shape_data;
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion.h b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion.h
index 17a17dd..a174b70 100644
--- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion.h
+++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion.h
@@ -8,46 +8,35 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/layout/ng/geometry/ng_bfc_rect.h"
 #include "third_party/blink/renderer/core/style/computed_style_constants.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
 
 namespace blink {
 
 class LayoutBox;
 
-struct CORE_EXPORT NGExclusionShapeData final
-    : public GarbageCollected<NGExclusionShapeData> {
+struct CORE_EXPORT NGExclusionShapeData {
   NGExclusionShapeData(const LayoutBox* layout_box,
                        const NGBoxStrut& margins,
                        const NGBoxStrut& shape_insets)
       : layout_box(layout_box), margins(margins), shape_insets(shape_insets) {}
-  NGExclusionShapeData(const NGExclusionShapeData& other)
-      : layout_box(other.layout_box),
-        margins(other.margins),
-        shape_insets(other.shape_insets) {}
 
-  void Trace(Visitor*) const;
-
-  Member<const LayoutBox> layout_box;
+  const LayoutBox* layout_box;
   const NGBoxStrut margins;
   const NGBoxStrut shape_insets;
 };
 
 // Struct that represents an exclusion. This currently is just a float but
 // we've named it an exclusion to potentially support other types in the future.
-struct CORE_EXPORT NGExclusion final : public GarbageCollected<NGExclusion> {
-  NGExclusion(const NGBfcRect& rect,
-              const EFloat type,
-              const NGExclusionShapeData* shape_data)
-      : rect(rect), type(type), shape_data(std::move(shape_data)) {}
-
-  static const NGExclusion* Create(const NGBfcRect& rect,
-                                   const EFloat type,
-                                   NGExclusionShapeData* shape_data = nullptr) {
-    return MakeGarbageCollected<NGExclusion>(rect, type, std::move(shape_data));
+struct CORE_EXPORT NGExclusion : public RefCounted<NGExclusion> {
+  static scoped_refptr<const NGExclusion> Create(
+      const NGBfcRect& rect,
+      const EFloat type,
+      std::unique_ptr<NGExclusionShapeData> shape_data = nullptr) {
+    return base::AdoptRef(new NGExclusion(rect, type, std::move(shape_data)));
   }
 
-  const NGExclusion* CopyWithOffset(const NGBfcDelta& offset_delta) const {
+  scoped_refptr<const NGExclusion> CopyWithOffset(
+      const NGBfcDelta& offset_delta) const {
     if (!offset_delta.line_offset_delta && !offset_delta.block_offset_delta)
       return this;
 
@@ -55,24 +44,28 @@
     new_rect.start_offset += offset_delta;
     new_rect.end_offset += offset_delta;
 
-    return MakeGarbageCollected<NGExclusion>(
+    return base::AdoptRef(new NGExclusion(
         new_rect, type,
-        shape_data ? MakeGarbageCollected<NGExclusionShapeData>(*shape_data)
-                   : nullptr);
+        shape_data ? std::make_unique<NGExclusionShapeData>(
+                         shape_data->layout_box, shape_data->margins,
+                         shape_data->shape_insets)
+                   : nullptr));
   }
 
-  void Trace(Visitor* visitor) const { visitor->Trace(shape_data); }
-
   const NGBfcRect rect;
   const EFloat type;
   bool is_past_other_exclusions = false;
-  const Member<const NGExclusionShapeData> shape_data;
+  const std::unique_ptr<NGExclusionShapeData> shape_data;
 
   bool operator==(const NGExclusion& other) const;
   bool operator!=(const NGExclusion& other) const { return !(*this == other); }
-};
 
-using NGExclusionPtrArray = HeapVector<Member<const NGExclusion>>;
+ private:
+  NGExclusion(const NGBfcRect& rect,
+              const EFloat type,
+              std::unique_ptr<NGExclusionShapeData> shape_data)
+      : rect(rect), type(type), shape_data(std::move(shape_data)) {}
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc
index c32f27e..4fa49a4f 100644
--- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc
+++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.cc
@@ -18,16 +18,16 @@
 // they are always produced in the order.
 void InsertClosedArea(
     const NGExclusionSpaceInternal::NGClosedArea area,
-    HeapVector<NGExclusionSpaceInternal::NGClosedArea, 4>& areas) {
-  if (areas.IsEmpty()) {
-    areas.emplace_back(area);
+    Vector<NGExclusionSpaceInternal::NGClosedArea, 4>* areas) {
+  if (areas->IsEmpty()) {
+    areas->emplace_back(area);
     return;
   }
 
   // We go backwards through the list as there is a higher probability that a
   // new area will be at the end of the list.
-  for (wtf_size_t i = areas.size(); i--;) {
-    const NGExclusionSpaceInternal::NGClosedArea& other = areas.at(i);
+  for (wtf_size_t i = areas->size(); i--;) {
+    const NGExclusionSpaceInternal::NGClosedArea& other = areas->at(i);
     if (other.opportunity.rect.BlockStartOffset() <=
         area.opportunity.rect.BlockStartOffset()) {
 #if DCHECK_IS_ON()
@@ -42,7 +42,7 @@
       }
 #endif
 
-      areas.insert(i + 1, area);
+      areas->insert(i + 1, area);
       return;
     }
   }
@@ -56,13 +56,14 @@
   // When a subsequent float gets placed, it might create a closed-off area at
   // LayoutUnit::Min(), and should be inserted at the front of the areas list.
   DCHECK_EQ(area.opportunity.rect.BlockStartOffset(), LayoutUnit::Min());
-  areas.push_front(area);
+  areas->push_front(area);
 }
 
 // Returns true if there is at least one edge between block_start and block_end.
-bool HasSolidEdges(const Vector<NGExclusionSpaceInternal::NGShelfEdge>& edges,
-                   LayoutUnit block_start,
-                   LayoutUnit block_end) {
+bool HasSolidEdges(
+    const Vector<NGExclusionSpaceInternal::NGShelfEdge, 1>& edges,
+    LayoutUnit block_start,
+    LayoutUnit block_end) {
   // If there aren't any adjacent exclusions, we must be the initial shelf.
   // This always has "solid" edges on either side.
   if (edges.IsEmpty())
@@ -81,9 +82,9 @@
 // to the given out_edges vector.
 // edges will be invalid after this call.
 void CollectSolidEdges(
-    Vector<NGExclusionSpaceInternal::NGShelfEdge>* edges,
+    Vector<NGExclusionSpaceInternal::NGShelfEdge, 1>* edges,
     LayoutUnit block_offset,
-    Vector<NGExclusionSpaceInternal::NGShelfEdge>* out_edges) {
+    Vector<NGExclusionSpaceInternal::NGShelfEdge, 1>* out_edges) {
   *out_edges = std::move(*edges);
   for (auto* it = out_edges->begin(); it != out_edges->end();) {
     if ((*it).block_end <= block_offset) {
@@ -126,7 +127,7 @@
   return NGLayoutOpportunity(
       NGBfcRect(start_offset, end_offset),
       other.shape_exclusions
-          ? MakeGarbageCollected<NGShapeExclusions>(*other.shape_exclusions)
+          ? base::AdoptRef(new NGShapeExclusions(*other.shape_exclusions))
           : nullptr);
 }
 
@@ -149,14 +150,14 @@
   return NGLayoutOpportunity(
       NGBfcRect(start_offset, end_offset),
       shelf.has_shape_exclusions
-          ? MakeGarbageCollected<NGShapeExclusions>(*shelf.shape_exclusions)
+          ? base::AdoptRef(new NGShapeExclusions(*shelf.shape_exclusions))
           : nullptr);
 }
 
 }  // namespace
 
 NGExclusionSpaceInternal::NGExclusionSpaceInternal()
-    : exclusions_(MakeGarbageCollected<NGExclusionPtrArray>()) {}
+    : exclusions_(base::MakeRefCounted<NGExclusionPtrArray>()) {}
 
 NGExclusionSpaceInternal::NGExclusionSpaceInternal(
     const NGExclusionSpaceInternal& other)
@@ -172,6 +173,9 @@
   other.derived_geometry_ = nullptr;
 }
 
+NGExclusionSpaceInternal::NGExclusionSpaceInternal(
+    NGExclusionSpaceInternal&&) noexcept = default;
+
 NGExclusionSpaceInternal& NGExclusionSpaceInternal::operator=(
     const NGExclusionSpaceInternal& other) {
   exclusions_ = other.exclusions_;
@@ -185,6 +189,9 @@
   return *this;
 }
 
+NGExclusionSpaceInternal& NGExclusionSpaceInternal::operator=(
+    NGExclusionSpaceInternal&&) noexcept = default;
+
 NGExclusionSpaceInternal::DerivedGeometry::DerivedGeometry(
     LayoutUnit block_offset_limit,
     bool track_shape_exclusions)
@@ -195,23 +202,23 @@
                         track_shape_exclusions_);
 }
 
-void NGExclusionSpaceInternal::Add(const NGExclusion* exclusion) {
-  DCHECK_LE(num_exclusions_, exclusions_->size());
+void NGExclusionSpaceInternal::Add(scoped_refptr<const NGExclusion> exclusion) {
+  DCHECK_LE(num_exclusions_, exclusions_->data.size());
 
   bool already_exists = false;
 
-  if (num_exclusions_ < exclusions_->size()) {
-    if (*exclusion == *exclusions_->at(num_exclusions_)) {
+  if (num_exclusions_ < exclusions_->data.size()) {
+    if (*exclusion == *exclusions_->data.at(num_exclusions_)) {
       // We might be adding an exclusion seen in a previous layout pass.
       already_exists = true;
     } else {
       // Perform a copy-on-write if the number of exclusions has gone out of
       // sync.
-      NGExclusionPtrArray* exclusions =
-          MakeGarbageCollected<NGExclusionPtrArray>();
-      exclusions->AppendRange(exclusions_->begin(),
-                              exclusions_->begin() + num_exclusions_);
-      exclusions_ = exclusions;
+      scoped_refptr<NGExclusionPtrArray> exclusions =
+          base::MakeRefCounted<NGExclusionPtrArray>();
+      exclusions->data.AppendRange(exclusions_->data.begin(),
+                                   exclusions_->data.begin() + num_exclusions_);
+      std::swap(exclusions_, exclusions);
     }
   }
 
@@ -226,7 +233,7 @@
 
   // We can safely mutate the exclusion here as an exclusion will never be
   // reused if this invariant doesn't hold.
-  const_cast<NGExclusion*>(exclusion)->is_past_other_exclusions =
+  const_cast<NGExclusion*>(exclusion.get())->is_past_other_exclusions =
       exclusion_block_offset >= left_clear_offset_ &&
       exclusion_block_offset >= right_clear_offset_;
 
@@ -244,7 +251,7 @@
     derived_geometry_->Add(*exclusion);
 
   if (!already_exists)
-    exclusions_->emplace_back(std::move(exclusion));
+    exclusions_->data.emplace_back(std::move(exclusion));
   num_exclusions_++;
 }
 
@@ -379,14 +386,13 @@
                   /* start_offset */ {shelf.line_left, shelf.block_offset},
                   /* end_offset */ {shelf.line_right,
                                     exclusion.rect.BlockStartOffset()}),
-              shelf.has_shape_exclusions
-                  ? MakeGarbageCollected<NGShapeExclusions>(
-                        *shelf.shape_exclusions)
-                  : nullptr);
+              shelf.has_shape_exclusions ? base::AdoptRef(new NGShapeExclusions(
+                                               *shelf.shape_exclusions))
+                                         : nullptr);
 
           InsertClosedArea(NGClosedArea(opportunity, shelf.line_left_edges,
                                         shelf.line_right_edges),
-                           areas_);
+                           &areas_);
         }
       }
 
@@ -654,12 +660,12 @@
 
   // Re-build the geometry if it isn't present.
   if (!derived_geometry_) {
-    DCHECK_LE(num_exclusions_, exclusions_->size());
+    DCHECK_LE(num_exclusions_, exclusions_->data.size());
     DCHECK_GE(num_exclusions_, 1u);
 
-    const auto* begin = exclusions_->begin();
+    const auto* begin = exclusions_->data.begin();
     const auto* end = begin + num_exclusions_;
-    DCHECK_LE(end, exclusions_->end());
+    DCHECK_LE(end, exclusions_->data.end());
 
     // Find the first exclusion whose block-start offset is "after" the
     // |block_offset_limit|.
@@ -690,7 +696,7 @@
     }
 
     // Add all the exclusions below the block-offset limit.
-    derived_geometry_ = MakeGarbageCollected<DerivedGeometry>(
+    derived_geometry_ = std::make_unique<DerivedGeometry>(
         block_offset_limit, track_shape_exclusions_);
     for (; it < end; ++it)
       derived_geometry_->Add(**it);
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
index abf4e4d14..402a6661 100644
--- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
+++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h
@@ -18,22 +18,25 @@
 
 namespace blink {
 
-typedef HeapVector<NGLayoutOpportunity, 8> LayoutOpportunityVector;
+typedef Vector<NGLayoutOpportunity, 8> LayoutOpportunityVector;
+typedef base::RefCountedData<WTF::Vector<scoped_refptr<const NGExclusion>>>
+    NGExclusionPtrArray;
 
 // This class is an implementation detail. For use of the exclusion space,
 // see NGExclusionSpace below. NGExclusionSpace was designed to be cheap
 // to construct and cheap to copy if empty.
-class CORE_EXPORT NGExclusionSpaceInternal final
-    : public GarbageCollected<NGExclusionSpaceInternal> {
+class CORE_EXPORT NGExclusionSpaceInternal {
+  USING_FAST_MALLOC(NGExclusionSpaceInternal);
+
  public:
   NGExclusionSpaceInternal();
   NGExclusionSpaceInternal(const NGExclusionSpaceInternal&);
   NGExclusionSpaceInternal(NGExclusionSpaceInternal&&) noexcept;
   NGExclusionSpaceInternal& operator=(const NGExclusionSpaceInternal&);
   NGExclusionSpaceInternal& operator=(NGExclusionSpaceInternal&&) noexcept;
-  ~NGExclusionSpaceInternal() = default;
+  ~NGExclusionSpaceInternal() {}
 
-  void Add(const NGExclusion* exclusion);
+  void Add(scoped_refptr<const NGExclusion> exclusion);
 
   NGLayoutOpportunity FindLayoutOpportunity(
       const NGBfcOffset& offset,
@@ -95,8 +98,8 @@
   // Pre-initializes the exclusions vector to something used in a previous
   // layout pass, however keeps the number of exclusions as zero.
   void PreInitialize(const NGExclusionSpaceInternal& other) {
-    DCHECK(exclusions_->IsEmpty());
-    DCHECK_GT(other.exclusions_->size(), 0u);
+    DCHECK(exclusions_->data.IsEmpty());
+    DCHECK_GT(other.exclusions_->data.size(), 0u);
 
     exclusions_ = other.exclusions_;
   }
@@ -111,7 +114,7 @@
     // Iterate through all the exclusions which were added by the layout, and
     // update the DerivedGeometry.
     for (wtf_size_t i = other.num_exclusions_; i < num_exclusions_; ++i) {
-      const NGExclusion& exclusion = *exclusions_->at(i);
+      const NGExclusion& exclusion = *exclusions_->data.at(i);
 
       // If we come across an exclusion with shape data, we opt-out of this
       // optimization.
@@ -143,7 +146,8 @@
     // layout result.
     for (wtf_size_t i = previous_input ? previous_input->num_exclusions_ : 0;
          i < previous_output.num_exclusions_; ++i) {
-      Add(previous_output.exclusions_->at(i)->CopyWithOffset(offset_delta));
+      Add(previous_output.exclusions_->data.at(i)->CopyWithOffset(
+          offset_delta));
     }
   }
 
@@ -157,8 +161,8 @@
       const NGExclusionSpaceInternal& other) const {
     DCHECK_EQ(num_exclusions_, other.num_exclusions_);
     for (wtf_size_t i = 0; i < num_exclusions_; ++i) {
-      const auto& exclusion = *exclusions_->at(i);
-      const auto& other_exclusion = *other.exclusions_->at(i);
+      const auto& exclusion = *exclusions_->data.at(i);
+      const auto& other_exclusion = *other.exclusions_->data.at(i);
       DCHECK(exclusion.rect == other_exclusion.rect);
       DCHECK_EQ(exclusion.type, other_exclusion.type);
       DCHECK_EQ((bool)exclusion.shape_data, (bool)other_exclusion.shape_data);
@@ -166,11 +170,6 @@
   }
 #endif
 
-  void Trace(Visitor* visitor) const {
-    visitor->Trace(exclusions_);
-    visitor->Trace(derived_geometry_);
-  }
-
   // This struct represents the side of a float against the "edge" of a shelf.
   struct NGShelfEdge {
     NGShelfEdge(LayoutUnit block_start, LayoutUnit block_end)
@@ -220,7 +219,7 @@
           line_left(LayoutUnit::Min()),
           line_right(LayoutUnit::Max()),
           shape_exclusions(track_shape_exclusions
-                               ? MakeGarbageCollected<NGShapeExclusions>()
+                               ? base::AdoptRef(new NGShapeExclusions)
                                : nullptr),
           has_shape_exclusions(false) {}
 
@@ -232,27 +231,26 @@
           line_left_edges(other.line_left_edges),
           line_right_edges(other.line_right_edges),
           shape_exclusions(other.shape_exclusions
-                               ? MakeGarbageCollected<NGShapeExclusions>(
-                                     *other.shape_exclusions)
+                               ? base::AdoptRef(new NGShapeExclusions(
+                                     *other.shape_exclusions))
                                : nullptr),
           has_shape_exclusions(other.has_shape_exclusions) {}
 
-    void Trace(Visitor* visitor) const { visitor->Trace(shape_exclusions); }
+    NGShelf(NGShelf&& other) noexcept = default;
+    NGShelf& operator=(NGShelf&& other) noexcept = default;
 
     LayoutUnit block_offset;
     LayoutUnit line_left;
     LayoutUnit line_right;
 
-    // TODO(crbug.com/1195345): restore inline buffer removed in
-    // https://crrev.com/c/2801713
-    Vector<NGShelfEdge> line_left_edges;
-    Vector<NGShelfEdge> line_right_edges;
+    Vector<NGShelfEdge, 1> line_left_edges;
+    Vector<NGShelfEdge, 1> line_right_edges;
 
     // shape_exclusions contains all the floats which sit below this shelf. The
     // has_shape_exclusions member will be true if shape_exclusions contains an
     // exclusion with shape-outside specified (and therefore should be copied
     // to any layout opportunity).
-    Member<NGShapeExclusions> shape_exclusions;
+    scoped_refptr<NGShapeExclusions> shape_exclusions;
     bool has_shape_exclusions;
   };
 
@@ -291,20 +289,16 @@
 
    public:
     NGClosedArea(NGLayoutOpportunity opportunity,
-                 const Vector<NGShelfEdge>& line_left_edges,
-                 const Vector<NGShelfEdge>& line_right_edges)
+                 const Vector<NGShelfEdge, 1>& line_left_edges,
+                 const Vector<NGShelfEdge, 1>& line_right_edges)
         : opportunity(opportunity),
           line_left_edges(line_left_edges),
           line_right_edges(line_right_edges) {}
 
-    void Trace(Visitor* visitor) const { visitor->Trace(opportunity); }
-
     const NGLayoutOpportunity opportunity;
 
-    // TODO(crbug.com/1195345): restore inline buffer removed in
-    // https://crrev.com/c/2801713
-    const Vector<NGShelfEdge> line_left_edges;
-    const Vector<NGShelfEdge> line_right_edges;
+    const Vector<NGShelfEdge, 1> line_left_edges;
+    const Vector<NGShelfEdge, 1> line_right_edges;
   };
 
  private:
@@ -317,7 +311,7 @@
   //
   // num_exclusions_ is how many exclusions *this* instance of an exclusion
   // space has, which may differ to the number of exclusions in the Vector.
-  Member<NGExclusionPtrArray> exclusions_;
+  scoped_refptr<NGExclusionPtrArray> exclusions_;
   wtf_size_t num_exclusions_ = 0;
 
   // These members are used for keeping track of the "lowest" offset for each
@@ -354,8 +348,9 @@
   // exclusion space in the copy-chain is used for answering queries. Only when
   // we trigger a (rare) re-layout case will we need to rebuild the
   // derived_geometry_ data-structure.
-  struct CORE_EXPORT DerivedGeometry final
-      : public GarbageCollected<DerivedGeometry> {
+  struct CORE_EXPORT DerivedGeometry {
+    USING_FAST_MALLOC(DerivedGeometry);
+
    public:
     // |block_offset_limit| represents the highest block-offset for which the
     // geometry is valid. |FindLayoutOpportunity| and |AllLayoutOpportunities|
@@ -368,6 +363,7 @@
     // when an exclusion with a shape is added we rebuilt the geometry to track
     // this.
     DerivedGeometry(LayoutUnit block_offset_limit, bool track_shape_exclusions);
+    DerivedGeometry(DerivedGeometry&& o) noexcept = default;
 
     void Add(const NGExclusion& exclusion);
 
@@ -385,11 +381,6 @@
                                        const LayoutUnit available_inline_size,
                                        const LambdaFunc&) const;
 
-    void Trace(Visitor* visitor) const {
-      visitor->Trace(shelves_);
-      visitor->Trace(areas_);
-    }
-
     // See |NGShelf| for a broad description of what shelves are. We always
     // begin with one, which has the internal value of:
     // {
@@ -398,14 +389,14 @@
     //   line_right: LayoutUnit::Max(),
     // }
     //
-    HeapVector<NGShelf, 4> shelves_;
+    Vector<NGShelf, 4> shelves_;
 
     // See |NGClosedArea| for a broad description of what closed-off areas are.
     //
     // Floats always align their block-start edges. We exploit this property by
     // keeping a list of closed-off areas. Once a closed-off area has been
     // created, it can never change.
-    HeapVector<NGClosedArea, 4> areas_;
+    Vector<NGClosedArea, 4> areas_;
 
     // This represents the highest block-offset for which the geometry is valid
     // for. If |NGExclusionSpaceInternal::GetDerivedGeometry| is called with a
@@ -421,7 +412,7 @@
       LayoutUnit block_offset_limit) const;
 
   // See DerivedGeometry struct description.
-  mutable Member<DerivedGeometry> derived_geometry_;
+  mutable std::unique_ptr<DerivedGeometry> derived_geometry_ = nullptr;
 };
 
 // The exclusion space represents all of the exclusions within a block
@@ -435,24 +426,23 @@
  public:
   NGExclusionSpace() = default;
   NGExclusionSpace(const NGExclusionSpace& other)
-      : exclusion_space_(other.exclusion_space_
-                             ? MakeGarbageCollected<NGExclusionSpaceInternal>(
-                                   *other.exclusion_space_)
-                             : nullptr) {}
+      : exclusion_space_(other.exclusion_space_ ? new NGExclusionSpaceInternal(
+                                                      *other.exclusion_space_)
+                                                : nullptr) {}
   NGExclusionSpace(NGExclusionSpace&& other) noexcept = default;
 
   NGExclusionSpace& operator=(const NGExclusionSpace& other) {
     exclusion_space_ = other.exclusion_space_
-                           ? MakeGarbageCollected<NGExclusionSpaceInternal>(
+                           ? std::make_unique<NGExclusionSpaceInternal>(
                                  *other.exclusion_space_)
                            : nullptr;
     return *this;
   }
   NGExclusionSpace& operator=(NGExclusionSpace&& other) = default;
 
-  void Add(const NGExclusion* exclusion) {
+  void Add(scoped_refptr<const NGExclusion> exclusion) {
     if (!exclusion_space_)
-      exclusion_space_ = MakeGarbageCollected<NGExclusionSpaceInternal>();
+      exclusion_space_ = std::make_unique<NGExclusionSpaceInternal>();
     exclusion_space_->Add(std::move(exclusion));
   }
 
@@ -518,7 +508,7 @@
     if (!other.exclusion_space_)
       return;
 
-    exclusion_space_ = MakeGarbageCollected<NGExclusionSpaceInternal>();
+    exclusion_space_ = std::make_unique<NGExclusionSpaceInternal>();
     exclusion_space_->PreInitialize(*other.exclusion_space_);
   }
 
@@ -583,11 +573,12 @@
 
     if (!new_output.exclusion_space_) {
       new_output.exclusion_space_ =
-          MakeGarbageCollected<NGExclusionSpaceInternal>();
+          std::make_unique<NGExclusionSpaceInternal>();
     }
 
     new_output.exclusion_space_->MergeExclusionSpaces(
-        offset_delta, *old_output.exclusion_space_, old_input.exclusion_space_);
+        offset_delta, *old_output.exclusion_space_,
+        old_input.exclusion_space_.get());
 
     return new_output;
   }
@@ -610,19 +601,14 @@
       exclusion_space_->CheckSameForSimplifiedLayout(*other.exclusion_space_);
   }
 #endif
-  void Trace(Visitor* visitor) const { visitor->Trace(exclusion_space_); }
 
  private:
-  mutable Member<NGExclusionSpaceInternal> exclusion_space_;
+  mutable std::unique_ptr<NGExclusionSpaceInternal> exclusion_space_;
 };
 
 }  // namespace blink
 
 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
     blink::NGExclusionSpaceInternal::NGShelfEdge)
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGExclusionSpaceInternal::NGShelf)
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGExclusionSpaceInternal::NGClosedArea)
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_EXCLUSIONS_NG_EXCLUSION_SPACE_H_
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h b/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h
index 97c168ce..58734340 100644
--- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h
+++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h
@@ -19,19 +19,14 @@
 // calling FindLayoutOpportunity, or AllLayoutOpportunities.
 //
 // Its coordinates are relative to the BFC.
-struct CORE_EXPORT NGLayoutOpportunity final {
-  DISALLOW_NEW();
-
- public:
+struct CORE_EXPORT NGLayoutOpportunity {
   NGLayoutOpportunity()
       : rect(NGBfcOffset(LayoutUnit::Min(), LayoutUnit::Min()),
              NGBfcOffset(LayoutUnit::Max(), LayoutUnit::Max())) {}
-  explicit NGLayoutOpportunity(
+  NGLayoutOpportunity(
       const NGBfcRect& rect,
-      const NGShapeExclusions* shape_exclusions = nullptr)
-      : rect(rect), shape_exclusions(shape_exclusions) {}
-
-  void Trace(Visitor* visitor) const { visitor->Trace(shape_exclusions); }
+      scoped_refptr<const NGShapeExclusions> shape_exclusions = nullptr)
+      : rect(rect), shape_exclusions(std::move(shape_exclusions)) {}
 
   // Rectangle in BFC coordinates that represents this opportunity.
   NGBfcRect rect;
@@ -39,11 +34,11 @@
   // The shape exclusions hold all of the adjacent exclusions which may affect
   // the line layout opportunity when queried. May be null if no shapes are
   // present.
-  Member<const NGShapeExclusions> shape_exclusions;
+  scoped_refptr<const NGShapeExclusions> shape_exclusions;
 
   // Returns if the opportunity has any shapes which may affect a line layout
   // opportunity.
-  bool HasShapeExclusions() const { return shape_exclusions; }
+  bool HasShapeExclusions() const { return shape_exclusions.get(); }
 
   // Returns if the given delta (relative to the start of the opportunity) will
   // be below any shapes.
@@ -73,6 +68,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::NGLayoutOpportunity)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_EXCLUSIONS_NG_LAYOUT_OPPORTUNITY_H_
diff --git a/third_party/blink/renderer/core/layout/ng/exclusions/ng_shape_exclusions.h b/third_party/blink/renderer/core/layout/ng/exclusions/ng_shape_exclusions.h
index 936c09dd..2b91cf5 100644
--- a/third_party/blink/renderer/core/layout/ng/exclusions/ng_shape_exclusions.h
+++ b/third_party/blink/renderer/core/layout/ng/exclusions/ng_shape_exclusions.h
@@ -8,6 +8,7 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion.h"
 #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
+#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
@@ -19,19 +20,14 @@
 // This struct can belong to either a NGShelf within the exclusion space, or on
 // NGLayoutOpportunity. Outside these classes normal code shouldn't interact
 // with this class.
-class CORE_EXPORT NGShapeExclusions
-    : public GarbageCollected<NGShapeExclusions> {
+class CORE_EXPORT NGShapeExclusions : public RefCounted<NGShapeExclusions> {
  public:
   NGShapeExclusions() {}
   NGShapeExclusions(const NGShapeExclusions& other)
       : line_left_shapes(other.line_left_shapes),
         line_right_shapes(other.line_right_shapes) {}
-  void Trace(Visitor* visitor) const {
-    visitor->Trace(line_left_shapes);
-    visitor->Trace(line_right_shapes);
-  }
-  NGExclusionPtrArray line_left_shapes;
-  NGExclusionPtrArray line_right_shapes;
+  Vector<scoped_refptr<const NGExclusion>> line_left_shapes;
+  Vector<scoped_refptr<const NGExclusion>> line_right_shapes;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.cc b/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.cc
index 731b511..9a8a2b8 100644
--- a/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.cc
+++ b/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.cc
@@ -107,8 +107,7 @@
   NGLayoutAlgorithmParams params(node, fragment_geometry, constraint_space);
   DevtoolsFlexInfo flex_info;
   NGFlexLayoutAlgorithm flex_algorithm(params, &flex_info);
-  auto* new_result = flex_algorithm.Layout();
-  ALLOW_UNUSED_LOCAL(new_result);
+  auto new_result = flex_algorithm.Layout();
 
 #if DCHECK_IS_ON()
   MinMaxSizes new_min_max_sizes = IntrinsicLogicalWidths();
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_child_iterator.cc b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_child_iterator.cc
index d6ebe3c8..6272d011 100644
--- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_child_iterator.cc
+++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_child_iterator.cc
@@ -31,6 +31,8 @@
                        return c1.order < c2.order;
                      });
   }
+
+  iterator_ = children_.begin();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_child_iterator.h b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_child_iterator.h
index 77c6099..36b3018 100644
--- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_child_iterator.h
+++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_child_iterator.h
@@ -27,27 +27,22 @@
 
   // Returns the next block node which should be laid out.
   NGBlockNode NextChild() {
-    DCHECK(position_ <= children_.size());
-    if (position_ == children_.size())
+    if (iterator_ == children_.end())
       return nullptr;
-    return children_[position_++].child;
+
+    return (*iterator_++).child;
   }
 
   struct ChildWithOrder {
     DISALLOW_NEW();
-
-   public:
     ChildWithOrder(NGBlockNode child, int order) : child(child), order(order) {}
-    void Trace(Visitor* visitor) const { visitor->Trace(child); }
-
     NGBlockNode child;
     int order;
   };
 
  private:
-  // |children_| cannot be modified except in ctor;
-  HeapVector<ChildWithOrder, 4> children_;
-  wtf_size_t position_ = 0;
+  Vector<ChildWithOrder, 4> children_;
+  Vector<ChildWithOrder, 4>::const_iterator iterator_;
 };
 
 }  // namespace blink
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 729662e..7363469 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
@@ -6,6 +6,7 @@
 
 #include <memory>
 #include "base/optional.h"
+#include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/layout/flexible_box_algorithm.h"
 #include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
 #include "third_party/blink/renderer/core/layout/layout_box.h"
@@ -543,7 +544,7 @@
     auto IntrinsicBlockSizeFunc = [&]() -> LayoutUnit {
       if (!calculated_intrinsic_block_size) {
         NGConstraintSpace child_space = BuildSpaceForIntrinsicBlockSize(child);
-        const NGLayoutResult* layout_result =
+        scoped_refptr<const NGLayoutResult> layout_result =
             child.Layout(child_space, /* break_token */ nullptr);
         calculated_intrinsic_block_size = layout_result->IntrinsicBlockSize();
       }
@@ -868,8 +869,8 @@
   return content_size_suggestion;
 }
 
-const NGLayoutResult* NGFlexLayoutAlgorithm::Layout() {
-  if (auto* result = LayoutInternal())
+scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
+  if (auto result = LayoutInternal())
     return result;
 
   // We may have aborted layout due to a child changing scrollbars, relayout
@@ -877,7 +878,7 @@
   return RelayoutIgnoringChildScrollbarChanges();
 }
 
-const NGLayoutResult*
+scoped_refptr<const NGLayoutResult>
 NGFlexLayoutAlgorithm::RelayoutIgnoringChildScrollbarChanges() {
   DCHECK(!ignore_child_scrollbar_changes_);
   DCHECK(!layout_info_for_devtools_);
@@ -890,7 +891,7 @@
   return algorithm.Layout();
 }
 
-const NGLayoutResult* NGFlexLayoutAlgorithm::LayoutInternal() {
+scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::LayoutInternal() {
   // Freezing the scrollbars for the sub-tree shouldn't be strictly necessary,
   // but we do this just in case we trigger an unstable layout.
   base::Optional<PaintLayerScrollableArea::FreezeScrollbarsScope>
@@ -1297,7 +1298,7 @@
   // We prefer a baseline from a child with baseline alignment, and no
   // auto-margins in the cross axis (even if we have to synthesize the
   // baseline).
-  if (FlexLayoutAlgorithm::AlignmentForChild(Style(), *flex_item.style_) ==
+  if (FlexLayoutAlgorithm::AlignmentForChild(Style(), flex_item.style_) ==
           ItemPosition::kBaseline &&
       !flex_item.HasAutoMarginsInCrossAxis()) {
     container_builder_.SetBaseline(baseline_offset);
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 5aff18d4f..ec96f71e 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
@@ -27,11 +27,11 @@
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override;
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 
  private:
-  const NGLayoutResult* RelayoutIgnoringChildScrollbarChanges();
-  const NGLayoutResult* LayoutInternal();
+  scoped_refptr<const NGLayoutResult> RelayoutIgnoringChildScrollbarChanges();
+  scoped_refptr<const NGLayoutResult> LayoutInternal();
 
   bool DoesItemCrossSizeComputeToAuto(const NGBlockNode& child) const;
   bool IsItemFlexBasisDefinite(const NGBlockNode& child) const;
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm_test.cc
index d9eb2c5..9056eca 100644
--- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm_test.cc
@@ -46,7 +46,8 @@
       LogicalSize(LayoutUnit(100), kIndefiniteSize));
   NGBlockNode box(GetDocument().body()->GetLayoutBox());
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(box, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(box, space);
   EXPECT_EQ(PhysicalSize(84, 22), fragment->Size());
   ASSERT_EQ(1u, fragment->Children().size());
   fragment = To<NGPhysicalBoxFragment>(fragment->Children()[0].get());
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.cc
index a9187ec3..d0791c1 100644
--- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.cc
+++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.cc
@@ -30,6 +30,8 @@
                        return c1.order < c2.order;
                      });
   }
+
+  iterator_ = children_.begin();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h
index b365631..440e4a8 100644
--- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h
+++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h
@@ -27,28 +27,23 @@
 
   // Returns the next block node which should be laid out.
   NGBlockNode NextChild() {
-    DCHECK(position_ <= children_.size());
-    if (position_ == children_.size())
+    if (iterator_ == children_.end())
       return nullptr;
-    return children_[position_++].child;
+
+    return (*iterator_++).child;
   }
 
   struct ChildWithOrder {
     DISALLOW_NEW();
-
-   public:
     ChildWithOrder(NGBlockNode child, int order) : child(child), order(order) {}
-    void Trace(Visitor* visitor) const { visitor->Trace(child); }
-
     NGBlockNode child;
     int order;
   };
 
  protected:
   virtual void Setup(const NGBlockNode node);
-  // |children_| cannot be modified after |Setup()|.
-  HeapVector<ChildWithOrder, 4> children_;
-  wtf_size_t position_ = 0;
+  Vector<ChildWithOrder, 4> children_;
+  Vector<ChildWithOrder, 4>::const_iterator iterator_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
index 615db604..0fe619f 100644
--- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
@@ -69,12 +69,12 @@
   }
 }
 
-const NGLayoutResult* NGGridLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGGridLayoutAlgorithm::Layout() {
   PaintLayerScrollableArea::DelayScrollOffsetClampScope delay_clamp_scope;
 
   // Measure items.
   GridItems grid_items;
-  HeapVector<GridItemData> out_of_flow_items;
+  Vector<GridItemData> out_of_flow_items;
   ConstructAndAppendGridItems(&grid_items, &out_of_flow_items);
 
   const auto& container_style = Style();
@@ -615,10 +615,6 @@
   }
 }
 
-void NGGridLayoutAlgorithm::GridItemData::Trace(Visitor* visitor) const {
-  visitor->Trace(node);
-}
-
 NGGridLayoutAlgorithm::GridItems::Iterator
 NGGridLayoutAlgorithm::GridItems::begin() {
   return Iterator(&item_data, reordered_item_indices.begin());
@@ -803,7 +799,7 @@
   auto BlockContributionSize = [&]() -> LayoutUnit {
     DCHECK(!is_parallel_with_track_direction);
 
-    const NGLayoutResult* result;
+    scoped_refptr<const NGLayoutResult> result;
     if (!is_parallel && space.AvailableSize().inline_size == kIndefiniteSize) {
       // If we are orthogonal grid-item, resolving against an indefinite size,
       // set our inline-size to our max content-contribution size.
@@ -1007,7 +1003,7 @@
 
 void NGGridLayoutAlgorithm::ConstructAndAppendGridItems(
     GridItems* grid_items,
-    HeapVector<GridItemData>* out_of_flow_items) const {
+    Vector<GridItemData>* out_of_flow_items) const {
   DCHECK(grid_items);
   NGGridChildIterator iterator(Node());
   for (NGBlockNode child = iterator.NextChild(); child;
@@ -1473,7 +1469,7 @@
 
     const NGConstraintSpace space = CreateConstraintSpaceForMeasure(
         *grid_geometry, grid_item, track_direction);
-    const NGLayoutResult* result = grid_item.node.Layout(space);
+    scoped_refptr<const NGLayoutResult> result = grid_item.node.Layout(space);
 
     NGBoxFragment fragment(
         grid_item.node.Style().GetWritingDirection(),
@@ -2910,7 +2906,7 @@
     const NGConstraintSpace space = CreateConstraintSpaceForLayout(
         grid_geometry, grid_item, &containing_grid_area);
 
-    const NGLayoutResult* result = grid_item.node.Layout(space);
+    scoped_refptr<const NGLayoutResult> result = grid_item.node.Layout(space);
     const auto& physical_fragment =
         To<NGPhysicalBoxFragment>(result->PhysicalFragment());
     NGBoxFragment logical_fragment(grid_item.node.Style().GetWritingDirection(),
@@ -3010,7 +3006,7 @@
 void NGGridLayoutAlgorithm::PlaceOutOfFlowItems(
     const NGGridLayoutAlgorithmTrackCollection& column_track_collection,
     const NGGridLayoutAlgorithmTrackCollection& row_track_collection,
-    const HeapVector<GridItemData>& out_of_flow_items,
+    const Vector<GridItemData>& out_of_flow_items,
     const GridGeometry& grid_geometry,
     LayoutUnit block_size) {
   const LogicalSize fragment_size(container_builder_.InlineSize(), block_size);
@@ -3051,7 +3047,7 @@
   // At this point, we'll have a list of OOF candidates from any inflow children
   // of the grid (which have been propagated up). These might have an assigned
   // 'grid-area', so we need to assign their correct 'containing block rect'.
-  HeapVector<NGLogicalOutOfFlowPositionedNode>* out_of_flow_descendants =
+  Vector<NGLogicalOutOfFlowPositionedNode>* out_of_flow_descendants =
       container_builder_.MutableOutOfFlowPositionedCandidates();
   DCHECK(out_of_flow_descendants);
 
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
index 385e689d..16881226 100644
--- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
@@ -103,8 +103,6 @@
         const NGGridLayoutAlgorithmTrackCollection& track_collection,
         const NGGridPlacement& grid_placement);
 
-    void Trace(Visitor* visitor) const;
-
     const NGBlockNode node;
     GridArea resolved_position;
 
@@ -141,9 +139,8 @@
     class Iterator
         : public std::iterator<std::input_iterator_tag, GridItemData> {
       STACK_ALLOCATED();
-
      public:
-      Iterator(HeapVector<GridItemData>* item_data,
+      Iterator(Vector<GridItemData>* item_data,
                Vector<wtf_size_t>::const_iterator current_index)
           : item_data_(item_data), current_index_(current_index) {
         DCHECK(item_data_);
@@ -170,7 +167,7 @@
       }
 
      private:
-      HeapVector<GridItemData>* item_data_;
+      Vector<GridItemData>* item_data_;
       Vector<wtf_size_t>::const_iterator current_index_;
     };
 
@@ -181,13 +178,11 @@
 
     bool IsEmpty() const;
 
-    void Trace(Visitor* visitor) const { visitor->Trace(item_data); }
-
     // Grid items are appended to |item_data_| in the same order provided by
     // |NGGridChildIterator|, which iterates over its children in order-modified
     // document order; we want to keep such order since auto-placement and
     // painting order rely on it later in the algorithm.
-    HeapVector<GridItemData> item_data;
+    Vector<GridItemData> item_data;
     Vector<wtf_size_t> reordered_item_indices;
   };
 
@@ -280,7 +275,7 @@
 
   explicit NGGridLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override;
 
@@ -309,7 +304,7 @@
 
   void ConstructAndAppendGridItems(
       GridItems* grid_items,
-      HeapVector<GridItemData>* out_of_flow_items = nullptr) const;
+      Vector<GridItemData>* out_of_flow_items = nullptr) const;
   GridItemData MeasureGridItem(const NGBlockNode node) const;
 
   void BuildBlockTrackCollections(
@@ -416,7 +411,7 @@
   void PlaceOutOfFlowItems(
       const NGGridLayoutAlgorithmTrackCollection& column_track_collection,
       const NGGridLayoutAlgorithmTrackCollection& row_track_collection,
-      const HeapVector<GridItemData>& out_of_flow_items,
+      const Vector<GridItemData>& out_of_flow_items,
       const GridGeometry& grid_geometry,
       LayoutUnit block_size);
 
@@ -466,7 +461,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGGridLayoutAlgorithm::GridItemData)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_LAYOUT_ALGORITHM_H_
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc
index 0a59c76c..b602ce9 100644
--- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc
@@ -46,8 +46,7 @@
   void BuildGridItemsAndTrackCollections(
       const NGGridLayoutAlgorithm& algorithm) {
     // Measure items.
-    algorithm.ConstructAndAppendGridItems(&items_->grid_items_,
-                                          &items_->out_of_flow_items_);
+    algorithm.ConstructAndAppendGridItems(&grid_items_, &out_of_flow_items_);
 
     NGGridPlacement grid_placement(
         algorithm.Style(), algorithm.ComputeAutomaticRepetitions(kForColumns),
@@ -57,7 +56,7 @@
     NGGridBlockTrackCollection column_block_track_collection(kForColumns);
     NGGridBlockTrackCollection row_block_track_collection(kForRows);
     algorithm.BuildBlockTrackCollections(
-        &items_->grid_items_, &column_block_track_collection,
+        &grid_items_, &column_block_track_collection,
         &row_block_track_collection, &grid_placement);
 
     // Build algorithm track collections from the block track collections.
@@ -71,11 +70,11 @@
 
     // Cache track span properties for grid items.
     algorithm.CacheGridItemsTrackSpanProperties(column_track_collection_,
-                                                &items_->grid_items_);
+                                                &grid_items_);
     algorithm.CacheGridItemsTrackSpanProperties(row_track_collection_,
-                                                &items_->grid_items_);
+                                                &grid_items_);
 
-    for (auto& grid_item : items_->grid_items_) {
+    for (auto& grid_item : grid_items_) {
       grid_item.ComputeSetIndices(column_track_collection_);
       grid_item.ComputeSetIndices(row_track_collection_);
     }
@@ -87,11 +86,11 @@
     bool unused;
     algorithm.ComputeUsedTrackSizes(
         NGGridLayoutAlgorithm::SizingConstraint::kLayout, grid_geometry_,
-        &column_track_collection_, &items_->grid_items_, &unused);
+        &column_track_collection_, &grid_items_, &unused);
     // Resolve block size.
     algorithm.ComputeUsedTrackSizes(
         NGGridLayoutAlgorithm::SizingConstraint::kLayout, grid_geometry_,
-        &row_track_collection_, &items_->grid_items_, &unused);
+        &row_track_collection_, &grid_items_, &unused);
   }
 
   NGGridLayoutAlgorithmTrackCollection& TrackCollection(
@@ -103,7 +102,7 @@
   LayoutUnit BaseRowSizeForChild(const NGGridLayoutAlgorithm& algorithm,
                                  wtf_size_t index) {
     LayoutUnit offset, size;
-    algorithm.ComputeGridItemOffsetAndSize(items_->grid_items_.item_data[index],
+    algorithm.ComputeGridItemOffsetAndSize(grid_items_.item_data[index],
                                            grid_geometry_.row_geometry,
                                            kForRows, &offset, &size);
     return size;
@@ -111,11 +110,11 @@
 
   // Helper methods to access private data on NGGridLayoutAlgorithm. This class
   // is a friend of NGGridLayoutAlgorithm but the individual tests are not.
-  wtf_size_t GridItemCount() { return items_->grid_items_.item_data.size(); }
+  wtf_size_t GridItemCount() { return grid_items_.item_data.size(); }
 
   Vector<GridArea> GridItemGridAreas(const NGGridLayoutAlgorithm& algorithm) {
     Vector<GridArea> results;
-    for (const auto& item : items_->grid_items_.item_data)
+    for (const auto& item : grid_items_.item_data)
       results.push_back(item.resolved_position);
     return results;
   }
@@ -125,8 +124,7 @@
       TrackSpanProperties::PropertyId property) {
     Vector<wtf_size_t> results;
     for (wtf_size_t i = 0; i < GridItemCount(); ++i) {
-      if (items_->grid_items_.item_data[i].column_span_properties.HasProperty(
-              property))
+      if (grid_items_.item_data[i].column_span_properties.HasProperty(property))
         results.push_back(i);
     }
     return results;
@@ -137,8 +135,7 @@
       TrackSpanProperties::PropertyId property) {
     Vector<wtf_size_t> results;
     for (wtf_size_t i = 0; i < GridItemCount(); ++i) {
-      if (items_->grid_items_.item_data[i].row_span_properties.HasProperty(
-              property))
+      if (grid_items_.item_data[i].row_span_properties.HasProperty(property))
         results.push_back(i);
     }
     return results;
@@ -170,7 +167,8 @@
     return growth_limits;
   }
 
-  const NGPhysicalBoxFragment* RunBlockLayoutAlgorithm(Element* element) {
+  scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
+      Element* element) {
     NGBlockNode container(element->GetLayoutBox());
     NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
         {WritingMode::kHorizontalTb, TextDirection::kLtr},
@@ -179,8 +177,8 @@
   }
 
   String DumpFragmentTree(Element* element) {
-    auto* fragment = RunBlockLayoutAlgorithm(element);
-    return DumpFragmentTree(fragment);
+    auto fragment = RunBlockLayoutAlgorithm(element);
+    return DumpFragmentTree(fragment.get());
   }
 
   String DumpFragmentTree(const blink::NGPhysicalBoxFragment* fragment) {
@@ -192,18 +190,8 @@
     return fragment->DumpFragmentTree(flags);
   }
 
-  struct GCedGridItems final : public GarbageCollected<GCedGridItems> {
-   public:
-    NGGridLayoutAlgorithm::GridItems grid_items_;
-    HeapVector<NGGridLayoutAlgorithm::GridItemData> out_of_flow_items_;
-
-    void Trace(Visitor* visitor) const {
-      visitor->Trace(grid_items_);
-      visitor->Trace(out_of_flow_items_);
-    }
-  };
-
-  Persistent<GCedGridItems> items_ = MakeGarbageCollected<GCedGridItems>();
+  NGGridLayoutAlgorithm::GridItems grid_items_;
+  Vector<NGGridLayoutAlgorithm::GridItemData> out_of_flow_items_;
 
   NGGridLayoutAlgorithmTrackCollection column_track_collection_;
   NGGridLayoutAlgorithmTrackCollection row_track_collection_;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h b/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h
index ed0bf91..7c1e5c4d 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h
@@ -6,7 +6,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_LAYOUT_NG_TEXT_H_
 
 #include "third_party/blink/renderer/core/layout/layout_text.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_span.h"
 
 namespace blink {
 
@@ -29,22 +28,17 @@
     return true;
   }
 
-  void Trace(Visitor* visitor) const override {
-    visitor->Trace(inline_items_);
-    LayoutText::Trace(visitor);
-  }
-
  private:
-  const NGInlineItemSpan* GetNGInlineItems() const final {
+  const base::span<NGInlineItem>* GetNGInlineItems() const final {
     NOT_DESTROYED();
     return &inline_items_;
   }
-  NGInlineItemSpan* GetNGInlineItems() final {
+  base::span<NGInlineItem>* GetNGInlineItems() final {
     NOT_DESTROYED();
     return &inline_items_;
   }
 
-  NGInlineItemSpan inline_items_;
+  base::span<NGInlineItem> inline_items_;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_fragment.h b/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_fragment.h
index 6d66470..f75edc56 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_fragment.h
@@ -6,7 +6,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_LAYOUT_NG_TEXT_FRAGMENT_H_
 
 #include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_span.h"
 
 namespace blink {
 
@@ -27,17 +26,12 @@
     return true;
   }
 
-  void Trace(Visitor* visitor) const override {
-    visitor->Trace(inline_items_);
-    LayoutTextFragment::Trace(visitor);
-  }
-
  private:
-  const NGInlineItemSpan* GetNGInlineItems() const final {
+  const base::span<NGInlineItem>* GetNGInlineItems() const final {
     NOT_DESTROYED();
     return &inline_items_;
   }
-  NGInlineItemSpan* GetNGInlineItems() final {
+  base::span<NGInlineItem>* GetNGInlineItems() final {
     NOT_DESTROYED();
     return &inline_items_;
   }
@@ -48,7 +42,7 @@
     LayoutText::InsertedIntoTree();
   }
 
-  NGInlineItemSpan inline_items_;
+  base::span<NGInlineItem> inline_items_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h b/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h
index a8c8b86..4edb839 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h
@@ -51,7 +51,7 @@
 
   const NGFragmentItem* fragment_item_;
   // |root_box_fragment_| owns |fragment_item_|.
-  Persistent<const NGPhysicalBoxFragment> root_box_fragment_;
+  scoped_refptr<const NGPhysicalBoxFragment> root_box_fragment_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position_test.cc
index f667167..527e426 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position_test.cc
@@ -55,7 +55,7 @@
   }
 
   Persistent<Element> container_;
-  Persistent<const LayoutBlockFlow> context_;
+  const LayoutBlockFlow* context_;
 };
 
 #define TEST_CARET(caret, fragment_, type_, offset_)                         \
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
index 12786ed..4dbe00b 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
@@ -21,15 +21,13 @@
 namespace {
 
 struct SameSizeAsNGFragmentItem {
-  Member<void*> member;
-  union {
-    NGFragmentItem::TextItem text_;
-    NGFragmentItem::GeneratedTextItem generated_text_;
-    NGFragmentItem::LineItem line_;
-    NGFragmentItem::BoxItem box_;
-  };
+  struct {
+    void* pointer;
+    NGTextOffset text_offset;
+  } type_data;
   PhysicalRect rect;
   NGInkOverflow ink_overflow;
+  void* pointer;
   wtf_size_t sizes[2];
   unsigned flags;
 };
@@ -136,11 +134,8 @@
   DCHECK_EQ(IsFormattingContextRoot(), box.IsFormattingContextRoot());
 }
 
-// |type_| will be re-initialized in another constructor called inside
-// this one.
 NGFragmentItem::NGFragmentItem(NGLogicalLineItem&& line_item,
-                               WritingMode writing_mode)
-    : type_(0) {
+                               WritingMode writing_mode) {
   DCHECK(line_item.CanCreateFragmentItem());
 
   if (line_item.inline_item) {
@@ -370,13 +365,11 @@
     : box_fragment(other.box_fragment->PostLayout()),
       descendants_count(other.descendants_count) {}
 
-NGFragmentItem::BoxItem::BoxItem(const NGPhysicalBoxFragment* box_fragment,
-                                 wtf_size_t descendants_count)
-    : box_fragment(box_fragment), descendants_count(descendants_count) {}
-
-void NGFragmentItem::BoxItem::Trace(Visitor* visitor) const {
-  visitor->Trace(box_fragment);
-}
+NGFragmentItem::BoxItem::BoxItem(
+    scoped_refptr<const NGPhysicalBoxFragment> box_fragment,
+    wtf_size_t descendants_count)
+    : box_fragment(std::move(box_fragment)),
+      descendants_count(descendants_count) {}
 
 const NGPhysicalBoxFragment* NGFragmentItem::BoxItem::PostLayout() const {
   if (box_fragment)
@@ -406,10 +399,8 @@
 }
 
 inline LayoutBox* NGFragmentItem::MutableInkOverflowOwnerBox() {
-  if (Type() == kBox) {
-    return DynamicTo<LayoutBox>(
-        const_cast<LayoutObject*>(layout_object_.Get()));
-  }
+  if (Type() == kBox)
+    return DynamicTo<LayoutBox>(const_cast<LayoutObject*>(layout_object_));
   return nullptr;
 }
 
@@ -910,15 +901,6 @@
   return inline_offset <= size.inline_size / 2 ? StartOffset() : EndOffset();
 }
 
-void NGFragmentItem::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_object_);
-  // Looking up Type() inside Trace() here is safe since |type_| is const.
-  if (Type() == kLine)
-    visitor->Trace(line_);
-  else if (Type() == kBox)
-    visitor->Trace(box_);
-}
-
 std::ostream& operator<<(std::ostream& ostream, const NGFragmentItem& item) {
   ostream << "{";
   switch (item.Type()) {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
index 3a30e151..45e9ea7 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
@@ -15,7 +15,6 @@
 #include "third_party/blink/renderer/core/layout/ng/ng_ink_overflow.h"
 #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h"
 #include "third_party/blink/renderer/platform/graphics/paint/display_item_client.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/transforms/affine_transform.h"
 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
 
@@ -41,13 +40,10 @@
 //
 // This class consumes less memory than a full fragment, and can be stored in a
 // flat list (NGFragmentItems) for easier and faster traversal.
-class CORE_EXPORT NGFragmentItem final {
-  DISALLOW_NEW();
-
+class CORE_EXPORT NGFragmentItem {
  public:
   // Represents regular text that exists in the DOM.
   struct TextItem {
-    DISALLOW_NEW();
     scoped_refptr<const ShapeResultView> shape_result;
     // TODO(kojii): |text_offset| should match to the offset in |shape_result|.
     // Consider if we should remove them, or if keeping them is easier.
@@ -59,26 +55,21 @@
   };
   // Represents text generated by the layout engine, e.g., hyphen or ellipsis.
   struct GeneratedTextItem {
-    DISALLOW_NEW();
     scoped_refptr<const ShapeResultView> shape_result;
     String text;
   };
   // A start marker of a line box.
   struct LineItem {
-    DISALLOW_NEW();
-
-   public:
-    void Trace(Visitor* visitor) const { visitor->Trace(line_box_fragment); }
-    Member<const NGPhysicalLineBoxFragment> line_box_fragment;
+    scoped_refptr<const NGPhysicalLineBoxFragment> line_box_fragment;
     wtf_size_t descendants_count;
   };
   // Represents a box fragment appeared in a line. This includes inline boxes
   // (e.g., <span>text</span>) and atomic inlines.
   struct BoxItem {
-    DISALLOW_NEW();
     // This copy constructor looks up the "post-layout" fragment.
     BoxItem(const BoxItem&);
-    BoxItem(const NGPhysicalBoxFragment*, wtf_size_t descendants_count);
+    BoxItem(scoped_refptr<const NGPhysicalBoxFragment>,
+            wtf_size_t descendants_count);
 
     // If this item is an inline box, its children are stored as following
     // items. |descendants_count_| has the number of such items.
@@ -87,9 +78,7 @@
     // as children of |box_fragment|.
     const NGPhysicalBoxFragment* PostLayout() const;
 
-    void Trace(Visitor*) const;
-
-    Member<const NGPhysicalBoxFragment> box_fragment;
+    scoped_refptr<const NGPhysicalBoxFragment> box_fragment;
     wtf_size_t descendants_count;
   };
 
@@ -173,7 +162,7 @@
   }
   const LayoutObject* GetLayoutObject() const { return layout_object_; }
   LayoutObject* GetMutableLayoutObject() const {
-    return const_cast<LayoutObject*>(layout_object_.Get());
+    return const_cast<LayoutObject*>(layout_object_);
   }
   bool IsLayoutObjectDestroyedOrMoved() const { return !layout_object_; }
   void LayoutObjectWillBeDestroyed() const;
@@ -235,7 +224,7 @@
   // Returns |NGPhysicalBoxFragment| if one is associated with this item.
   const NGPhysicalBoxFragment* BoxFragment() const {
     if (Type() == kBox)
-      return box_.box_fragment;
+      return box_.box_fragment.get();
     return nullptr;
   }
   const NGPhysicalBoxFragment* PostLayoutBoxFragment() const {
@@ -254,7 +243,7 @@
   // this function. See |InlineBreakToken()| for example.
   const NGPhysicalLineBoxFragment* LineBoxFragment() const {
     if (Type() == kLine)
-      return line_.line_box_fragment;
+      return line_.line_box_fragment.get();
     return nullptr;
   }
 
@@ -294,12 +283,11 @@
 
    private:
     friend class NGFragmentItem;
-    explicit MutableForPainting(const NGFragmentItem& item)
+    MutableForPainting(const NGFragmentItem& item)
         : item_(const_cast<NGFragmentItem&>(item)) {}
 
     NGFragmentItem& item_;
   };
-
   MutableForPainting GetMutableForPainting() const {
     return MutableForPainting(*this);
   }
@@ -448,8 +436,6 @@
   // Get a description of |this| for the debug purposes.
   String ToString() const;
 
-  void Trace(Visitor*) const;
-
  private:
   FRIEND_TEST_ALL_PREFIXES(NGFragmentItemTest, CopyMove);
   FRIEND_TEST_ALL_PREFIXES(NGFragmentItemTest, SelfPaintingInlineBox);
@@ -495,12 +481,11 @@
   void RecalcInkOverflow(const NGInlineCursor& cursor,
                          PhysicalRect* self_and_contents_rect_out);
 
-  Member<const LayoutObject> layout_object_;
+  const LayoutObject* layout_object_;
 
   // TODO(kojii): We can make them sub-classes if we need to make the vector of
   // pointers. Sub-classing from DisplayItemClient prohibits copying and that we
   // cannot create a vector of this class.
-  GC_PLUGIN_IGNORE("crbug.com/1146383")
   union {
     TextItem text_;
     SVGTextItem svg_text_;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc
index 17ee1d1..9a27993 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc
@@ -105,6 +105,8 @@
   // Test moving a line item.
   NGFragmentItem move_of_line(std::move(copy_of_line));
   EXPECT_EQ(move_of_line.LineBoxFragment(), line_item->LineBoxFragment());
+  // After the move, the source fragment should be released.
+  EXPECT_EQ(copy_of_line.LineBoxFragment(), nullptr);
   EXPECT_TRUE(move_of_line.IsInkOverflowComputed());
 
   // To test moving ink overflow, add an ink overflow to |move_of_line|.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
index 37822d94..473e34b 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc
@@ -42,10 +42,10 @@
 NGFragmentItems::NGFragmentItems(NGFragmentItemsBuilder* builder)
     : text_content_(std::move(builder->text_content_)),
       first_line_text_content_(std::move(builder->first_line_text_content_)),
-      const_size_(builder->items_.size()),
+      size_(builder->items_.size()),
       size_of_earlier_fragments_(0) {
   NGFragmentItemsBuilder::ItemWithOffsetList& source_items = builder->items_;
-  for (wtf_size_t i = 0; i < const_size_; ++i) {
+  for (wtf_size_t i = 0; i < size_; ++i) {
     // Call the move constructor to move without |AddRef|. Items in
     // |NGFragmentItemsBuilder| are not used after |this| was constructed.
     new (&items_[i]) NGFragmentItem(std::move(source_items[i].item));
@@ -55,9 +55,9 @@
 NGFragmentItems::NGFragmentItems(const NGFragmentItems& other)
     : text_content_(other.text_content_),
       first_line_text_content_(other.first_line_text_content_),
-      const_size_(other.const_size_),
+      size_(other.size_),
       size_of_earlier_fragments_(other.size_of_earlier_fragments_) {
-  for (wtf_size_t i = 0; i < const_size_; ++i) {
+  for (wtf_size_t i = 0; i < size_; ++i) {
     const auto& other_item = other.items_[i];
     new (&items_[i]) NGFragmentItem(other_item);
 
@@ -71,7 +71,7 @@
 }
 
 NGFragmentItems::~NGFragmentItems() {
-  for (unsigned i = 0; i < const_size_; ++i)
+  for (unsigned i = 0; i < size_; ++i)
     items_[i].~NGFragmentItem();
 }
 
@@ -81,7 +81,7 @@
 }
 
 void NGFragmentItems::FinalizeAfterLayout(
-    const HeapVector<Member<const NGLayoutResult>, 1>& results) {
+    const Vector<scoped_refptr<const NGLayoutResult>, 1>& results) {
 #if DCHECK_IS_ON()
   if (!RuntimeEnabledFeatures::LayoutNGBlockFragmentationEnabled()) {
     for (const auto& result : results) {
@@ -95,9 +95,7 @@
     wtf_size_t fragment_id;
     wtf_size_t item_index;
   };
-  HeapHashMap<Member<const LayoutObject>, LastItem> last_items;
-  ClearCollectionScope<HeapHashMap<Member<const LayoutObject>, LastItem>>
-      clear_scope(&last_items);
+  HashMap<const LayoutObject*, LastItem> last_items;
   wtf_size_t item_index = 0;
   for (const auto& result : results) {
     const auto& fragment =
@@ -393,9 +391,4 @@
 }
 #endif
 
-void NGFragmentItems::Trace(Visitor* visitor) const {
-  for (const NGFragmentItem& item : Items())
-    visitor->Trace(item);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h
index ad22719..2164812c 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h
@@ -18,25 +18,23 @@
 //
 // During the layout phase, descendants of the inline formatting context is
 // transformed to a flat list of |NGFragmentItem| and stored in this class.
-class CORE_EXPORT NGFragmentItems final {
-  DISALLOW_NEW();
-
+class CORE_EXPORT NGFragmentItems {
  public:
   NGFragmentItems(const NGFragmentItems& other);
   explicit NGFragmentItems(NGFragmentItemsBuilder* builder);
   ~NGFragmentItems();
 
-  wtf_size_t Size() const { return const_size_; }
+  wtf_size_t Size() const { return size_; }
 
   using Span = base::span<const NGFragmentItem>;
-  Span Items() const { return base::make_span(ItemsData(), const_size_); }
+  Span Items() const { return base::make_span(ItemsData(), size_); }
   bool Equals(const Span& span) const {
     return ItemsData() == span.data() && Size() == span.size();
   }
   bool IsSubSpan(const Span& span) const;
 
   const NGFragmentItem& front() const {
-    CHECK_GE(const_size_, 1u);
+    CHECK_GE(size_, 1u);
     return items_[0];
   }
 
@@ -58,9 +56,7 @@
   wtf_size_t SizeOfEarlierFragments() const {
     return size_of_earlier_fragments_;
   }
-  wtf_size_t EndItemIndex() const {
-    return size_of_earlier_fragments_ + const_size_;
-  }
+  wtf_size_t EndItemIndex() const { return size_of_earlier_fragments_ + size_; }
   bool HasItemIndex(wtf_size_t index) const {
     return index >= SizeOfEarlierFragments() && index < EndItemIndex();
   }
@@ -68,7 +64,7 @@
   // Associate |NGFragmentItem|s with |LayoutObject|s and finalize the items
   // (set which ones are the first / last for the LayoutObject).
   static void FinalizeAfterLayout(
-      const HeapVector<Member<const NGLayoutResult>, 1>& results);
+      const Vector<scoped_refptr<const NGLayoutResult>, 1>& results);
 
   // Disassociate |NGFragmentItem|s with |LayoutObject|s. And more.
   static void ClearAssociatedFragments(LayoutObject* container);
@@ -99,8 +95,6 @@
   void CheckAllItemsAreValid() const;
 #endif
 
-  void Trace(Visitor*) const;
-
  private:
   const NGFragmentItem* ItemsData() const { return items_; }
 
@@ -114,12 +108,19 @@
   String text_content_;
   String first_line_text_content_;
 
-  const wtf_size_t const_size_;
+  wtf_size_t size_;
 
   // Total size of |NGFragmentItem| in earlier fragments when block fragmented.
   // 0 for the first |NGFragmentItems|.
   mutable wtf_size_t size_of_earlier_fragments_;
 
+  // Semantically, |items_| is a flexible array of |scoped_refptr<const
+  // NGFragmentItem>|, but |scoped_refptr| has non-trivial destruction which
+  // causes an error in clang. Declare as a flexible array of |NGFragmentItem*|
+  // instead. Please see |ItemsData()|.
+  static_assert(
+      sizeof(NGFragmentItem*) == sizeof(scoped_refptr<const NGFragmentItem>),
+      "scoped_refptr must be the size of a pointer for |ItemsData()| to work");
   NGFragmentItem items_[0];
 };
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
index 8088e91..f7a4d53d 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc
@@ -37,7 +37,15 @@
     items_.ReserveInitialCapacity(estimated_item_count);
 }
 
-NGFragmentItemsBuilder::~NGFragmentItemsBuilder() = default;
+NGFragmentItemsBuilder::~NGFragmentItemsBuilder() {
+  ReleaseCurrentLogicalLineItems();
+
+  // Delete leftovers that were associated, but were not added.
+  for (const auto& i : line_items_map_) {
+    if (i.value != line_items_pool_)
+      delete i.value;
+  }
+}
 
 void NGFragmentItemsBuilder::AddLogicalLineItemsPool(
     NGLogicalLineItems* line_items) {
@@ -53,6 +61,8 @@
   if (current_line_items_ == line_items_pool_) {
     DCHECK(is_line_items_pool_acquired_);
     is_line_items_pool_acquired_ = false;
+  } else {
+    delete current_line_items_;
   }
   current_line_items_ = nullptr;
 }
@@ -75,7 +85,7 @@
   }
   MoveCurrentLogicalLineItemsToMap();
   DCHECK(!current_line_items_);
-  current_line_items_ = MakeGarbageCollected<NGLogicalLineItems>();
+  current_line_items_ = new NGLogicalLineItems();
   return current_line_items_;
 }
 
@@ -211,7 +221,8 @@
   }
 
   DCHECK(items_.IsEmpty());
-  const wtf_size_t estimated_size = items.Items().size();
+  const NGFragmentItems::Span source_items = items.Items();
+  const wtf_size_t estimated_size = source_items.size();
   items_.ReserveCapacity(estimated_size);
 
   // Convert offsets to logical. The logic is opposite to |ConvertToPhysical|.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
index 2c35a02..53a8b890 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h
@@ -115,15 +115,13 @@
     const NGFragmentItem& operator*() const { return item; }
     const NGFragmentItem* operator->() const { return &item; }
 
-    void Trace(Visitor* visitor) const { visitor->Trace(item); }
-
     NGFragmentItem item;
     LogicalOffset offset;
   };
 
   // Give an inline size, the allocation of this vector is hot. "128" is
   // heuristic. Usually 10-40, some wikipedia pages have >64 items.
-  using ItemWithOffsetList = HeapVector<ItemWithOffset, 128>;
+  using ItemWithOffsetList = Vector<ItemWithOffset, 128>;
 
   // Find |LogicalOffset| of the first |NGFragmentItem| for |LayoutObject|.
   base::Optional<LogicalOffset> LogicalOffsetFor(const LayoutObject&) const;
@@ -158,8 +156,7 @@
   NGLogicalLineItems* current_line_items_ = nullptr;
   const NGPhysicalFragment* current_line_fragment_ = nullptr;
 
-  HeapHashMap<const NGPhysicalFragment*, Member<NGLogicalLineItems>>
-      line_items_map_;
+  HashMap<const NGPhysicalFragment*, NGLogicalLineItems*> line_items_map_;
   NGLogicalLineItems* line_items_pool_ = nullptr;
 
   NGInlineNode node_;
@@ -175,7 +172,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGFragmentItemsBuilder::ItemWithOffset)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_FRAGMENT_ITEMS_BUILDER_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder_test.cc
index edaad62..69cbb87 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder_test.cc
@@ -39,8 +39,7 @@
       cursor.Current()->LineBoxFragment();
 
   NGInlineNode inline_node(container);
-  NGLogicalLineItems* line_items_pool =
-      MakeGarbageCollected<NGLogicalLineItems>();
+  NGLogicalLineItems line_items_pool;
   {
     // First test emulates what |NGBlockLayoutAlgorithm| does, which loops
     // following calls for each line:
@@ -49,7 +48,7 @@
     // 3. |AddLine|.
     NGFragmentItemsBuilder items_builder(
         inline_node, {WritingMode::kHorizontalTb, TextDirection::kLtr});
-    items_builder.AddLogicalLineItemsPool(line_items_pool);
+    items_builder.AddLogicalLineItemsPool(&line_items_pool);
     NGLogicalLineItems* line_items1 = items_builder.AcquireLogicalLineItems();
     items_builder.AssociateLogicalLineItems(line_items1, *line_fragment1);
     items_builder.AddLine(*line_fragment1, LogicalOffset());
@@ -58,7 +57,7 @@
     items_builder.AddLine(*line_fragment2, LogicalOffset());
 
     // In this case, we should reuse one |NGLogicalLineItems| instance.
-    EXPECT_EQ(line_items1, line_items_pool);
+    EXPECT_EQ(line_items1, &line_items_pool);
     EXPECT_EQ(line_items1, line_items2);
 
     const auto& items = items_builder.Items(PhysicalSize());
@@ -72,7 +71,7 @@
     // box.
     NGFragmentItemsBuilder items_builder(
         inline_node, {WritingMode::kHorizontalTb, TextDirection::kLtr});
-    items_builder.AddLogicalLineItemsPool(line_items_pool);
+    items_builder.AddLogicalLineItemsPool(&line_items_pool);
     NGLogicalLineItems* line_items1 = items_builder.AcquireLogicalLineItems();
     items_builder.AssociateLogicalLineItems(line_items1, *line_fragment1);
     NGLogicalLineItems* line_items2 = items_builder.AcquireLogicalLineItems();
@@ -80,7 +79,7 @@
 
     // Because |AcquireLogicalLineItems| without |AddLine|, new instances should
     // be allocated for line 2.
-    EXPECT_EQ(line_items1, line_items_pool);
+    EXPECT_EQ(line_items1, &line_items_pool);
     EXPECT_NE(line_items1, line_items2);
 
     items_builder.AddLine(*line_fragment1, LogicalOffset());
@@ -95,7 +94,7 @@
     // to the container box in the reverse order.
     NGFragmentItemsBuilder items_builder(
         inline_node, {WritingMode::kHorizontalTb, TextDirection::kLtr});
-    items_builder.AddLogicalLineItemsPool(line_items_pool);
+    items_builder.AddLogicalLineItemsPool(&line_items_pool);
     NGLogicalLineItems* line_items1 = items_builder.AcquireLogicalLineItems();
     items_builder.AssociateLogicalLineItems(line_items1, *line_fragment1);
     NGLogicalLineItems* line_items2 = items_builder.AcquireLogicalLineItems();
@@ -103,7 +102,7 @@
 
     // Because |AcquireLogicalLineItems| without |AddLine|, new instances should
     // be allocated for line 2.
-    EXPECT_EQ(line_items1, line_items_pool);
+    EXPECT_EQ(line_items1, &line_items_pool);
     EXPECT_NE(line_items1, line_items2);
 
     // Add lines in the reverse order.
@@ -118,7 +117,7 @@
     // Custom layout may not add all line boxes.
     NGFragmentItemsBuilder items_builder(
         inline_node, {WritingMode::kHorizontalTb, TextDirection::kLtr});
-    items_builder.AddLogicalLineItemsPool(line_items_pool);
+    items_builder.AddLogicalLineItemsPool(&line_items_pool);
     NGLogicalLineItems* line_items1 = items_builder.AcquireLogicalLineItems();
     items_builder.AssociateLogicalLineItems(line_items1, *line_fragment1);
     NGLogicalLineItems* line_items2 = items_builder.AcquireLogicalLineItems();
@@ -126,7 +125,7 @@
 
     // Because |AcquireLogicalLineItems| without |AddLine|, new instances should
     // be allocated for line 2.
-    EXPECT_EQ(line_items1, line_items_pool);
+    EXPECT_EQ(line_items1, &line_items_pool);
     EXPECT_NE(line_items1, line_items2);
 
     // Add line2, but not line1.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
index a0f62823..fdb982e 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc
@@ -646,7 +646,8 @@
     DCHECK_GT(end, start);
     NGLogicalLineItem* child = &(*line_box)[start];
     DCHECK(box_data.item->ShouldCreateBoxFragment());
-    const NGLayoutResult* box_fragment = box_data.CreateBoxFragment(line_box);
+    scoped_refptr<const NGLayoutResult> box_fragment =
+        box_data.CreateBoxFragment(line_box);
     if (child->IsPlaceholder()) {
       child->layout_result = std::move(box_fragment);
       child->rect = box_data.rect;
@@ -664,7 +665,8 @@
   box_data_list_.clear();
 }
 
-const NGLayoutResult* NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
+scoped_refptr<const NGLayoutResult>
+NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
     NGLogicalLineItems* line_box) {
   DCHECK(item);
   DCHECK(item->Style());
@@ -699,8 +701,7 @@
 
     if (child.out_of_flow_positioned_box) {
       DCHECK(item->GetLayoutObject()->IsLayoutInline());
-      NGBlockNode oof_box(
-          To<LayoutBox>(child.out_of_flow_positioned_box.Get()));
+      NGBlockNode oof_box(To<LayoutBox>(child.out_of_flow_positioned_box));
 
       // child.offset is the static position wrt. the linebox. As we are adding
       // this as a child of an inline level fragment, we adjust the static
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
index 4dd12324..fcb4ae67 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h
@@ -40,7 +40,7 @@
  public:
   unsigned fragment_start = 0;
   const NGInlineItem* item = nullptr;
-  Persistent<const ComputedStyle> style;
+  const ComputedStyle* style = nullptr;
 
   // Points to style->GetFont(), or |scaled_font| in an SVG <text>.
   const Font* font;
@@ -273,7 +273,7 @@
 
     void UpdateFragmentEdges(Vector<BoxData, 4>& list);
 
-    const NGLayoutResult* CreateBoxFragment(NGLogicalLineItems*);
+    scoped_refptr<const NGLayoutResult> CreateBoxFragment(NGLogicalLineItems*);
   };
 
   Vector<NGInlineBoxState, 4> stack_;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
index 8c8a6128..e97cebd 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
@@ -12,7 +12,7 @@
 namespace {
 
 struct SameSizeAsNGInlineBreakToken : NGBreakToken {
-  Member<const ComputedStyle> style_;
+  scoped_refptr<const ComputedStyle> style_;
   unsigned numbers[2];
 };
 
@@ -34,6 +34,8 @@
   flags_ = flags;
 }
 
+NGInlineBreakToken::~NGInlineBreakToken() = default;
+
 #if DCHECK_IS_ON()
 
 String NGInlineBreakToken::ToString() const {
@@ -48,9 +50,4 @@
 
 #endif  // DCHECK_IS_ON()
 
-void NGInlineBreakToken::Trace(Visitor* visitor) const {
-  visitor->Trace(style_);
-  NGBreakToken::Trace(visitor);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
index 3485a6d..3104236 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
@@ -27,19 +27,21 @@
   // Creates a break token for a node which did fragment, and can potentially
   // produce more fragments.
   // Takes ownership of the state_stack.
-  static NGInlineBreakToken* Create(
+  static scoped_refptr<NGInlineBreakToken> Create(
       NGInlineNode node,
       const ComputedStyle* style,
       unsigned item_index,
       unsigned text_offset,
       unsigned flags /* NGInlineBreakTokenFlags */) {
-    return MakeGarbageCollected<NGInlineBreakToken>(
-        PassKey(), node, style, item_index, text_offset, flags);
+    return base::AdoptRef(new NGInlineBreakToken(
+        PassKey(), node, style, item_index, text_offset, flags));
   }
 
+  ~NGInlineBreakToken() override;
+
   // The style at the end of this break token. The next line should start with
   // this style.
-  const ComputedStyle* Style() const { return style_; }
+  const ComputedStyle* Style() const { return style_.get(); }
 
   unsigned ItemIndex() const {
     return item_index_;
@@ -77,10 +79,8 @@
   String ToString() const override;
 #endif
 
-  void Trace(Visitor*) const override;
-
  private:
-  Member<const ComputedStyle> style_;
+  scoped_refptr<const ComputedStyle> style_;
   unsigned item_index_;
   unsigned text_offset_;
 };
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.cc
index ef9d86c..3821f38 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.cc
@@ -11,11 +11,11 @@
 namespace {
 
 struct SameSizeAsNGInlineChildLayoutContext {
-  NGLogicalLineItems* line_items_;
+  NGLogicalLineItems line_items_;
   base::Optional<NGInlineLayoutStateStack> box_states_;
   void* pointers[2];
   unsigned number;
-  HeapVector<Member<const NGBlockBreakToken>> propagated_float_break_tokens_;
+  Vector<scoped_refptr<const NGBlockBreakToken>> propagated_float_break_tokens_;
 };
 
 static_assert(
@@ -26,13 +26,12 @@
 
 }  // namespace
 
-NGInlineChildLayoutContext::NGInlineChildLayoutContext()
-    : logical_line_items_(MakeGarbageCollected<NGLogicalLineItems>()) {}
+NGInlineChildLayoutContext::NGInlineChildLayoutContext() = default;
 NGInlineChildLayoutContext::~NGInlineChildLayoutContext() = default;
 
 NGInlineLayoutStateStack*
 NGInlineChildLayoutContext::BoxStatesIfValidForItemIndex(
-    const HeapVector<NGInlineItem>& items,
+    const Vector<NGInlineItem>& items,
     unsigned item_index) {
   if (box_states_.has_value() && items_ == &items && item_index_ == item_index)
     return &*box_states_;
@@ -44,7 +43,7 @@
 }
 
 void NGInlineChildLayoutContext::PropagateBreakToken(
-    const NGBlockBreakToken* token) {
+    scoped_refptr<const NGBlockBreakToken> token) {
   propagated_float_break_tokens_.push_back(token);
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h
index 39b6a88a..82cd170a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h
@@ -32,12 +32,12 @@
     DCHECK(!items_builder_ || !builder);
     items_builder_ = builder;
     if (builder)
-      builder->AddLogicalLineItemsPool(logical_line_items_);
+      builder->AddLogicalLineItemsPool(&logical_line_items_);
   }
 
   // Returns an instance of |NGLogicalLineItems|. This is reused when laying out
   // the next line.
-  NGLogicalLineItems* LogicalLineItems() { return logical_line_items_; }
+  NGLogicalLineItems* LogicalLineItems() { return &logical_line_items_; }
 
   // Returns the NGInlineLayoutStateStack in this context.
   bool HasBoxStates() const { return box_states_.has_value(); }
@@ -50,35 +50,34 @@
   // To determine this, callers must call |SetItemIndex| to set the end of the
   // current line.
   NGInlineLayoutStateStack* BoxStatesIfValidForItemIndex(
-      const HeapVector<NGInlineItem>& items,
+      const Vector<NGInlineItem>& items,
       unsigned item_index);
-  void SetItemIndex(const HeapVector<NGInlineItem>& items,
-                    unsigned item_index) {
+  void SetItemIndex(const Vector<NGInlineItem>& items, unsigned item_index) {
     items_ = &items;
     item_index_ = item_index;
   }
 
-  const HeapVector<Member<const NGBlockBreakToken>>& PropagatedBreakTokens()
+  const Vector<scoped_refptr<const NGBlockBreakToken>>& PropagatedBreakTokens()
       const {
     return propagated_float_break_tokens_;
   }
   void ClearPropagatedBreakTokens();
-  void PropagateBreakToken(const NGBlockBreakToken*);
+  void PropagateBreakToken(scoped_refptr<const NGBlockBreakToken>);
 
  private:
   // TODO(kojii): Probably better to own |NGInlineChildLayoutContext|. While we
   // transit, allocating separately is easier.
   NGFragmentItemsBuilder* items_builder_ = nullptr;
 
-  NGLogicalLineItems* logical_line_items_;
+  NGLogicalLineItems logical_line_items_;
 
   base::Optional<NGInlineLayoutStateStack> box_states_;
 
   // The items and its index this context is set up for.
-  const HeapVector<NGInlineItem>* items_ = nullptr;
+  const Vector<NGInlineItem>* items_ = nullptr;
   unsigned item_index_ = 0;
 
-  HeapVector<Member<const NGBlockBreakToken>> propagated_float_break_tokens_;
+  Vector<scoped_refptr<const NGBlockBreakToken>> propagated_float_break_tokens_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
index f2c835df..1339361 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
@@ -9,7 +9,6 @@
 #include "third_party/blink/renderer/core/layout/layout_block_flow.h"
 #include "third_party/blink/renderer/core/layout/layout_text.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_span.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
@@ -375,7 +374,7 @@
       return 0;
     }
     const NGTextOffset offset = TextOffset();
-    auto* const item = std::find_if(
+    const auto& item = std::find_if(
         items->begin(), items->end(), [offset](const NGInlineItem& item) {
           return item.StartOffset() <= offset.start &&
                  item.EndOffset() >= offset.end;
@@ -388,7 +387,7 @@
     DCHECK(GetLayoutObject()->ContainingNGBlockFlow());
     const LayoutBlockFlow& block_flow =
         *GetLayoutObject()->ContainingNGBlockFlow();
-    const HeapVector<NGInlineItem> items =
+    const Vector<NGInlineItem> items =
         block_flow.GetNGInlineNodeData()->ItemsData(UsesFirstLineStyle()).items;
     const LayoutObject* const layout_object = GetLayoutObject();
     const auto* const item = std::find_if(
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
index 598846e6..342dbc2 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
@@ -7,6 +7,7 @@
 
 #include <unicode/ubidi.h>
 
+#include "base/containers/span.h"
 #include "base/dcheck_is_on.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/editing/forward.h"
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc
index 12643796..5d6394c 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc
@@ -1245,7 +1245,7 @@
 
   // Test cursors rooted at |NGFragmentItems|.
   // They can enumerate fragments only in the specified fragmentainer.
-  HeapVector<Member<const NGPhysicalBoxFragment>> fragments;
+  Vector<const NGPhysicalBoxFragment*> fragments;
   for (const NGPhysicalBoxFragment& fragment :
        block_flow->PhysicalFragments()) {
     DCHECK(fragment.HasItems());
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc
index 10de260c..262e2ff 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc
@@ -15,8 +15,7 @@
 namespace {
 
 struct SameSizeAsNGInlineItem {
-  void* pointers[1];
-  UntracedMember<void*> members[1];
+  void* pointers[2];
   unsigned integers[3];
   unsigned bit_fields : 32;
 };
@@ -147,7 +146,7 @@
 }
 
 void NGInlineItem::SetSegmentData(const RunSegmenter::RunSegmenterRange& range,
-                                  HeapVector<NGInlineItem>* items) {
+                                  Vector<NGInlineItem>* items) {
   unsigned segment_data = NGInlineItemSegment::PackSegmentData(range);
   for (NGInlineItem& item : *items) {
     if (item.Type() == NGInlineItem::kText)
@@ -164,7 +163,7 @@
 // @param end_offset The exclusive end offset to set.
 // @param level The level to set.
 // @return The index of the next item.
-unsigned NGInlineItem::SetBidiLevel(HeapVector<NGInlineItem>& items,
+unsigned NGInlineItem::SetBidiLevel(Vector<NGInlineItem>& items,
                                     unsigned index,
                                     unsigned end_offset,
                                     UBiDiLevel level) {
@@ -204,8 +203,7 @@
 }
 
 const Font& NGInlineItem::FontWithSVGScaling() const {
-  if (const auto* svg_text =
-          DynamicTo<LayoutSVGInlineText>(layout_object_.Get())) {
+  if (const auto* svg_text = DynamicTo<LayoutSVGInlineText>(layout_object_)) {
     DCHECK(RuntimeEnabledFeatures::SVGTextNGEnabled());
     // We don't need to care about StyleVariant(). SVG 1.1 doesn't support
     // ::first-line.
@@ -226,7 +224,7 @@
 // @param items The list of NGInlineItem.
 // @param index The index to split.
 // @param offset The offset to split at.
-void NGInlineItem::Split(HeapVector<NGInlineItem>& items,
+void NGInlineItem::Split(Vector<NGInlineItem>& items,
                          unsigned index,
                          unsigned offset) {
   DCHECK_GT(offset, items[index].start_offset_);
@@ -237,12 +235,4 @@
   items[index + 1].start_offset_ = offset;
 }
 
-void NGInlineItem::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_object_);
-}
-
-void NGInlineItemsData::Trace(Visitor* visitor) const {
-  visitor->Trace(items);
-  visitor->Trace(offset_mapping);
-}
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h
index 51044b3d..45840f3 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h
@@ -102,13 +102,13 @@
   // optimization if this is false.
   bool ShouldCreateBoxFragment() const {
     if (Type() == kOpenTag || Type() == kCloseTag)
-      return To<LayoutInline>(layout_object_.Get())->ShouldCreateBoxFragment();
+      return To<LayoutInline>(layout_object_)->ShouldCreateBoxFragment();
     DCHECK_EQ(Type(), kAtomicInline);
     return false;
   }
   void SetShouldCreateBoxFragment() {
     DCHECK(Type() == kOpenTag || Type() == kCloseTag);
-    To<LayoutInline>(layout_object_.Get())->SetShouldCreateBoxFragment();
+    To<LayoutInline>(layout_object_)->SetShouldCreateBoxFragment();
   }
 
   unsigned StartOffset() const { return start_offset_; }
@@ -214,12 +214,12 @@
     is_end_collapsible_newline_ = is_newline;
   }
 
-  static void Split(HeapVector<NGInlineItem>&, unsigned index, unsigned offset);
+  static void Split(Vector<NGInlineItem>&, unsigned index, unsigned offset);
 
   // RunSegmenter properties.
   unsigned SegmentData() const { return segment_data_; }
   static void SetSegmentData(const RunSegmenter::RunSegmenterRange& range,
-                             HeapVector<NGInlineItem>* items);
+                             Vector<NGInlineItem>* items);
 
   RunSegmenter::RunSegmenterRange CreateRunSegmenterRange() const {
     return NGInlineItemSegment::UnpackSegmentData(start_offset_, end_offset_,
@@ -237,7 +237,7 @@
       shape_result_ = nullptr;
     bidi_level_ = level;
   }
-  static unsigned SetBidiLevel(HeapVector<NGInlineItem>&,
+  static unsigned SetBidiLevel(Vector<NGInlineItem>&,
                                unsigned index,
                                unsigned end_offset,
                                UBiDiLevel);
@@ -247,15 +247,13 @@
 
   String ToString() const;
 
-  void Trace(Visitor* visitor) const;
-
  private:
   void ComputeBoxProperties();
 
   unsigned start_offset_;
   unsigned end_offset_;
   scoped_refptr<const ShapeResult> shape_result_;
-  Member<LayoutObject> layout_object_;
+  LayoutObject* layout_object_;
 
   NGInlineItemType type_;
   unsigned text_type_ : 3;          // NGTextType
@@ -284,15 +282,14 @@
 
 // Represents a text content with a list of NGInlineItem. A node may have an
 // additional NGInlineItemsData for ::first-line pseudo element.
-struct CORE_EXPORT NGInlineItemsData
-    : public GarbageCollected<NGInlineItemsData> {
+struct CORE_EXPORT NGInlineItemsData {
+  USING_FAST_MALLOC(NGInlineItemsData);
+
  public:
-  NGInlineItemsData() = default;
-  virtual ~NGInlineItemsData() = default;
   // Text content for all inline items represented by a single NGInlineNode.
   // Encoded either as UTF-16 or latin-1 depending on the content.
   String text_content;
-  HeapVector<NGInlineItem> items;
+  Vector<NGInlineItem> items;
 
   // Cache RunSegmenter segments when at least one item has multiple runs.
   // Set to nullptr when all items has only single run, which is common case for
@@ -301,7 +298,7 @@
   std::unique_ptr<NGInlineItemSegments> segments;
 
   // The DOM to text content offset mapping of this inline node.
-  Member<NGOffsetMapping> offset_mapping;
+  std::unique_ptr<NGOffsetMapping> offset_mapping;
 
   bool IsValidOffset(unsigned index, unsigned offset) const {
     return index < items.size() && items[index].IsValidOffset(offset);
@@ -317,12 +314,8 @@
   // Get a list of |kOpenTag| that are open at |size|.
   using OpenTagItems = Vector<const NGInlineItem*, 16>;
   void GetOpenTagItems(wtf_size_t size, OpenTagItems* open_items) const;
-
-  virtual void Trace(Visitor* visitor) const;
 };
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::NGInlineItem)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_ITEM_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc
index 67dce83..e05524c 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc
@@ -40,9 +40,4 @@
 }
 #endif
 
-void NGInlineItemResult::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_result);
-  visitor->Trace(positioned_float);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h
index 98bc7066..5b1c0f1 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h
@@ -47,8 +47,6 @@
     hyphen_shape_result = nullptr;
   }
 
-  void Trace(Visitor* visitor) const;
-
   // The NGInlineItem and its index.
   const NGInlineItem* item;
   unsigned item_index;
@@ -77,12 +75,12 @@
   scoped_refptr<const ShapeResult> hyphen_shape_result;
 
   // NGLayoutResult for atomic inline items.
-  Member<const NGLayoutResult> layout_result;
+  scoped_refptr<const NGLayoutResult> layout_result;
 
   // NGPositionedFloat for floating inline items. Should only be present for
   // positioned floats (not unpositioned). It indicates where it was placed
   // within the BFC.
-  Member<NGPositionedFloat> positioned_float = nullptr;
+  base::Optional<NGPositionedFloat> positioned_float;
 
   // Margins, borders, and padding for open tags.
   // Margins are set for atomic inlines too.
@@ -154,10 +152,8 @@
 };
 
 // Represents a set of NGInlineItemResult that form a line box.
-using NGInlineItemResults = HeapVector<NGInlineItemResult, 32>;
+using NGInlineItemResults = Vector<NGInlineItemResult, 32>;
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::NGInlineItemResult)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_ITEM_RESULT_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_segment.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_segment.cc
index 981349c..238c856 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_segment.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_segment.cc
@@ -206,8 +206,7 @@
                    NGInlineItemSegment(end_offset, segment.segment_data_));
 }
 
-void NGInlineItemSegments::ComputeItemIndex(
-    const HeapVector<NGInlineItem>& items) {
+void NGInlineItemSegments::ComputeItemIndex(const Vector<NGInlineItem>& items) {
   DCHECK_EQ(items.back().EndOffset(), EndOffset());
   unsigned segment_index = 0;
   const NGInlineItemSegment* segment = segments_.begin();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_segment.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_segment.h
index a50e5a4..4f4cee81 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_segment.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_segment.h
@@ -98,7 +98,7 @@
                                       unsigned segment_index);
 
   // Compute an internal items-to-segments index for faster access.
-  void ComputeItemIndex(const HeapVector<NGInlineItem>& items);
+  void ComputeItemIndex(const Vector<NGInlineItem>& items);
 
   // Iterates |RunSegmenterRange| for the given offsets.
   class Iterator {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_span.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_span.h
deleted file mode 100644
index 2a0beaed..0000000
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_span.h
+++ /dev/null
@@ -1,67 +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.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_ITEM_SPAN_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_ITEM_SPAN_H_
-
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h"
-
-namespace blink {
-
-// |NGInlineItemSpan| performs like base::span<NGInlineItem> but stores a
-// pointer to |NGInlineItemsData|, not |HeapVector<NGInlineItem>| in
-// |NGInlineItemsData|, to keep it alive. |HeapVector<NGInlineItem>| allocated
-// in |NGInlineItemsData| is deleted in |NGInlineItemsData|'s destructor even if
-// there is any pointer to the vector, and storing a pointer to it can cause
-// use-after-free bugs.
-struct NGInlineItemSpan final {
-  DISALLOW_NEW();
-
- public:
-  NGInlineItemSpan() = default;
-
-  void SetItems(NGInlineItemsData* data, size_t begin, size_t size) {
-    SECURITY_DCHECK(begin < data->items.size());
-    SECURITY_DCHECK(begin_ + size_ <= data->items.size());
-    data_ = data;
-    begin_ = begin;
-    size_ = size;
-  }
-  void Clear() {
-    data_ = nullptr;
-    begin_ = 0;
-    size_ = 0;
-  }
-
-  bool empty() const { return size_ == 0; }
-  size_t size() const { return size_; }
-
-  const NGInlineItem& front() const {
-    CHECK(!empty());
-    SECURITY_DCHECK(begin_ < data_->items.size());
-    return data_->items[begin_];
-  }
-
-  const NGInlineItem* begin() const {
-    SECURITY_DCHECK(begin_ < data_->items.size());
-    return data_->items.begin() + begin_;
-  }
-  const NGInlineItem* end() const {
-    SECURITY_DCHECK(begin_ + size_ <= data_->items.size());
-    return begin() + size_;
-  }
-
-  void Trace(Visitor* visitor) const { visitor->Trace(data_); }
-
- private:
-  Member<NGInlineItemsData> data_;
-  size_t begin_ = 0;
-  size_t size_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(NGInlineItemSpan);
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_ITEM_SPAN_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
index 73b608b..71a44bb 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -9,7 +9,6 @@
 #include "third_party/blink/renderer/core/layout/layout_inline.h"
 #include "third_party/blink/renderer/core/layout/layout_text.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_span.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h"
@@ -125,7 +124,7 @@
                                  after_style);
 }
 
-inline NGInlineItem& AppendItem(HeapVector<NGInlineItem>* items,
+inline NGInlineItem& AppendItem(Vector<NGInlineItem>* items,
                                 NGInlineItem::NGInlineItemType type,
                                 unsigned start,
                                 unsigned end,
@@ -176,7 +175,7 @@
 // Find the last item to compute collapsing with. Opaque items such as
 // open/close or bidi controls are ignored.
 // Returns nullptr if there were no previous items.
-NGInlineItem* LastItemToCollapseWith(HeapVector<NGInlineItem>* items) {
+NGInlineItem* LastItemToCollapseWith(Vector<NGInlineItem>* items) {
   for (auto it = items->rbegin(); it != items->rend(); it++) {
     NGInlineItem& item = *it;
     if (item.EndCollapseType() != NGInlineItem::kOpaqueToCollapsing)
@@ -217,7 +216,7 @@
 
 template <typename OffsetMappingBuilder>
 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::BoxInfo::
-    SetShouldCreateBoxFragment(HeapVector<NGInlineItem>* items) {
+    SetShouldCreateBoxFragment(Vector<NGInlineItem>* items) {
   DCHECK(!should_create_box_fragment);
   should_create_box_fragment = true;
   (*items)[item_index].SetShouldCreateBoxFragment();
@@ -1319,12 +1318,6 @@
 void NGInlineItemsBuilderTemplate<
     NGOffsetMappingBuilder>::UpdateShouldCreateBoxFragment(LayoutInline*) {}
 
-template <typename OffsetMappingBuilder>
-void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::BidiContext::Trace(
-    Visitor* visitor) const {
-  visitor->Trace(node);
-}
-
 template class CORE_TEMPLATE_EXPORT
     NGInlineItemsBuilderTemplate<EmptyOffsetMappingBuilder>;
 template class CORE_TEMPLATE_EXPORT
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
index ac2649a0..d0354cf7 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
@@ -45,7 +45,7 @@
  public:
   // Create a builder that appends items to |items|.
   NGInlineItemsBuilderTemplate(LayoutBlockFlow* block_flow,
-                               HeapVector<NGInlineItem>* items)
+                               Vector<NGInlineItem>* items)
       : block_flow_(block_flow), items_(items) {}
   ~NGInlineItemsBuilderTemplate();
 
@@ -144,23 +144,11 @@
   void ClearNeedsLayout(LayoutObject*);
   void UpdateShouldCreateBoxFragment(LayoutInline*);
 
-  // In public to modify VectorTraits<BidiContext> in WTF namespace.
-  struct BidiContext {
-    DISALLOW_NEW();
-
-   public:
-    void Trace(Visitor*) const;
-
-    Member<LayoutObject> node;
-    UChar enter;
-    UChar exit;
-  };
-
  private:
   static bool NeedsBoxInfo();
 
   LayoutBlockFlow* const block_flow_;
-  HeapVector<NGInlineItem>* items_;
+  Vector<NGInlineItem>* items_;
   StringBuilder text_;
 
   // |mapping_builder_| builds the whitespace-collapsed offset mapping
@@ -179,11 +167,16 @@
 
     BoxInfo(unsigned item_index, const NGInlineItem& item);
     bool ShouldCreateBoxFragmentForChild(const BoxInfo& child) const;
-    void SetShouldCreateBoxFragment(HeapVector<NGInlineItem>* items);
+    void SetShouldCreateBoxFragment(Vector<NGInlineItem>* items);
   };
   Vector<BoxInfo> boxes_;
 
-  HeapVector<BidiContext> bidi_context_;
+  struct BidiContext {
+    LayoutObject* node;
+    UChar enter;
+    UChar exit;
+  };
+  Vector<BidiContext> bidi_context_;
 
   bool has_bidi_controls_ = false;
   bool has_ruby_ = false;
@@ -272,9 +265,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGInlineItemsBuilder::BidiContext)
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGInlineItemsBuilderForOffsetMapping::BidiContext)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_ITEMS_BUILDER_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
index 1e59233..0b66c5b 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
@@ -31,14 +31,11 @@
     style_ = GetDocument().GetStyleResolver().CreateComputedStyle();
     block_flow_ = LayoutBlockFlow::CreateAnonymous(&GetDocument(), style_,
                                                    LegacyLayout::kAuto);
-    items_ = MakeGarbageCollected<HeapVector<NGInlineItem>>();
-    anonymous_objects_ =
-        MakeGarbageCollected<HeapVector<Member<LayoutObject>>>();
-    anonymous_objects_->push_back(block_flow_);
+    anonymous_objects_.push_back(block_flow_);
   }
 
   void TearDown() override {
-    for (LayoutObject* anonymous_object : *anonymous_objects_)
+    for (LayoutObject* anonymous_object : anonymous_objects_)
       anonymous_object->Destroy();
     NGLayoutTest::TearDown();
   }
@@ -49,10 +46,10 @@
     style_->SetWhiteSpace(whitespace);
   }
 
-  ComputedStyle* GetStyle(EWhiteSpace whitespace) {
+  scoped_refptr<ComputedStyle> GetStyle(EWhiteSpace whitespace) {
     if (whitespace == EWhiteSpace::kNormal)
       return style_;
-    ComputedStyle* style(
+    scoped_refptr<ComputedStyle> style(
         GetDocument().GetStyleResolver().CreateComputedStyle());
     style->SetWhiteSpace(whitespace);
     return style;
@@ -64,36 +61,36 @@
 
   void AppendText(const String& text, NGInlineItemsBuilder* builder) {
     LayoutText* layout_text = LayoutText::CreateEmptyAnonymous(
-        GetDocument(), style_, LegacyLayout::kAuto);
-    anonymous_objects_->push_back(layout_text);
+        GetDocument(), style_.get(), LegacyLayout::kAuto);
+    anonymous_objects_.push_back(layout_text);
     builder->AppendText(text, layout_text);
   }
 
   void AppendAtomicInline(NGInlineItemsBuilder* builder) {
     LayoutBlockFlow* layout_block_flow = LayoutBlockFlow::CreateAnonymous(
         &GetDocument(), style_, LegacyLayout::kAuto);
-    anonymous_objects_->push_back(layout_block_flow);
+    anonymous_objects_.push_back(layout_block_flow);
     builder->AppendAtomicInline(layout_block_flow);
   }
 
   void AppendRubyRun(NGInlineItemsBuilder* builder) {
-    LayoutNGRubyRun* ruby_run = MakeGarbageCollected<LayoutNGRubyRun>();
+    LayoutNGRubyRun* ruby_run = new LayoutNGRubyRun();
     ruby_run->SetDocumentForAnonymous(&GetDocument());
     ruby_run->SetStyle(style_);
-    anonymous_objects_->push_back(ruby_run);
+    anonymous_objects_.push_back(ruby_run);
     builder->AppendAtomicInline(ruby_run);
   }
 
   struct Input {
     const String text;
     EWhiteSpace whitespace = EWhiteSpace::kNormal;
-    Persistent<LayoutText> layout_text;
+    LayoutText* layout_text = nullptr;
   };
 
   const String& TestAppend(Vector<Input> inputs) {
-    items_->clear();
-    HeapVector<Member<LayoutText>> anonymous_objects;
-    NGInlineItemsBuilder builder(GetLayoutBlockFlow(), items_);
+    items_.clear();
+    Vector<LayoutText*> anonymous_objects;
+    NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items_);
     for (Input& input : inputs) {
       if (!input.layout_text) {
         input.layout_text = LayoutText::CreateEmptyAnonymous(
@@ -128,8 +125,8 @@
 
   void ValidateItems() {
     unsigned current_offset = 0;
-    for (unsigned i = 0; i < items_->size(); i++) {
-      const NGInlineItem& item = items_->at(i);
+    for (unsigned i = 0; i < items_.size(); i++) {
+      const NGInlineItem& item = items_[i];
       EXPECT_EQ(current_offset, item.StartOffset());
       EXPECT_LE(item.StartOffset(), item.EndOffset());
       current_offset = item.EndOffset();
@@ -139,27 +136,25 @@
 
   void CheckReuseItemsProducesSameResult(Vector<Input> inputs,
                                          bool has_bidi_controls) {
-    NGInlineNodeData& fake_data = *MakeGarbageCollected<NGInlineNodeData>();
+    NGInlineNodeData fake_data;
     fake_data.text_content = text_;
     fake_data.is_bidi_enabled_ = has_bidi_controls;
 
-    HeapVector<NGInlineItem> reuse_items;
+    Vector<NGInlineItem> reuse_items;
     NGInlineItemsBuilder reuse_builder(GetLayoutBlockFlow(), &reuse_items);
-    NGInlineItemsData* data = MakeGarbageCollected<NGInlineItemsData>();
-    data->items = *items_;
     for (Input& input : inputs) {
       // Collect items for this LayoutObject.
       DCHECK(input.layout_text);
-      for (size_t i = 0; i != data->items.size();) {
-        if (data->items[i].GetLayoutObject() == input.layout_text) {
-          size_t begin = i;
-          i++;
-          while (i < data->items.size() &&
-                 data->items[i].GetLayoutObject() == input.layout_text)
-            i++;
-          input.layout_text->SetInlineItems(data, begin, i - begin);
+      for (NGInlineItem* item = items_.begin(); item != items_.end();) {
+        if (item->GetLayoutObject() == input.layout_text) {
+          NGInlineItem* begin = item;
+          for (++item; item != items_.end(); ++item) {
+            if (item->GetLayoutObject() != input.layout_text)
+              break;
+          }
+          input.layout_text->SetInlineItems(begin, item);
         } else {
-          ++i;
+          ++item;
         }
       }
 
@@ -177,11 +172,11 @@
     EXPECT_EQ(text_, reuse_text);
   }
 
-  Persistent<LayoutBlockFlow> block_flow_;
-  Persistent<HeapVector<NGInlineItem>> items_;
+  LayoutBlockFlow* block_flow_ = nullptr;
+  Vector<NGInlineItem> items_;
   String text_;
-  Persistent<ComputedStyle> style_;
-  Persistent<HeapVector<Member<LayoutObject>>> anonymous_objects_;
+  scoped_refptr<ComputedStyle> style_;
+  Vector<LayoutObject*> anonymous_objects_;
 };
 
 #define TestWhitespaceValue(expected_text, input, whitespace) \
@@ -320,7 +315,7 @@
 
 TEST_F(NGInlineItemsBuilderTest, CollapseZeroWidthSpaceAndNewLineAtEnd) {
   EXPECT_EQ(String(u"\u200B"), TestAppend(u"\u200B\n"));
-  EXPECT_EQ(NGInlineItem::kNotCollapsible, items_->at(0).EndCollapseType());
+  EXPECT_EQ(NGInlineItem::kNotCollapsible, items_[0].EndCollapseType());
 }
 
 #if SEGMENT_BREAK_TRANSFORMATION_FOR_EAST_ASIAN_WIDTH
@@ -342,7 +337,7 @@
 #endif
 
 TEST_F(NGInlineItemsBuilderTest, OpaqueToSpaceCollapsing) {
-  NGInlineItemsBuilder builder(GetLayoutBlockFlow(), items_);
+  NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items_);
   AppendText("Hello ", &builder);
   builder.AppendOpaque(NGInlineItem::kBidiControl,
                        kFirstStrongIsolateCharacter);
@@ -354,7 +349,7 @@
 }
 
 TEST_F(NGInlineItemsBuilderTest, CollapseAroundReplacedElement) {
-  NGInlineItemsBuilder builder(GetLayoutBlockFlow(), items_);
+  NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items_);
   AppendText("Hello ", &builder);
   AppendAtomicInline(&builder);
   AppendText(" World", &builder);
@@ -362,33 +357,33 @@
 }
 
 TEST_F(NGInlineItemsBuilderTest, CollapseNewlineAfterObject) {
-  NGInlineItemsBuilder builder(GetLayoutBlockFlow(), items_);
+  NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items_);
   AppendAtomicInline(&builder);
   AppendText("\n", &builder);
   AppendAtomicInline(&builder);
   EXPECT_EQ(String(u"\uFFFC \uFFFC"), builder.ToString());
-  EXPECT_EQ(3u, items_->size());
-  EXPECT_ITEM_OFFSET(items_->at(0), NGInlineItem::kAtomicInline, 0u, 1u);
-  EXPECT_ITEM_OFFSET(items_->at(1), NGInlineItem::kText, 1u, 2u);
-  EXPECT_ITEM_OFFSET(items_->at(2), NGInlineItem::kAtomicInline, 2u, 3u);
+  EXPECT_EQ(3u, items_.size());
+  EXPECT_ITEM_OFFSET(items_[0], NGInlineItem::kAtomicInline, 0u, 1u);
+  EXPECT_ITEM_OFFSET(items_[1], NGInlineItem::kText, 1u, 2u);
+  EXPECT_ITEM_OFFSET(items_[2], NGInlineItem::kAtomicInline, 2u, 3u);
 }
 
 TEST_F(NGInlineItemsBuilderTest, AppendEmptyString) {
   EXPECT_EQ("", TestAppend(""));
-  EXPECT_EQ(1u, items_->size());
-  EXPECT_ITEM_OFFSET(items_->at(0), NGInlineItem::kText, 0u, 0u);
+  EXPECT_EQ(1u, items_.size());
+  EXPECT_ITEM_OFFSET(items_[0], NGInlineItem::kText, 0u, 0u);
 }
 
 TEST_F(NGInlineItemsBuilderTest, NewLines) {
   SetWhiteSpace(EWhiteSpace::kPre);
   EXPECT_EQ("apple\norange\ngrape\n", TestAppend("apple\norange\ngrape\n"));
-  EXPECT_EQ(6u, items_->size());
-  EXPECT_EQ(NGInlineItem::kText, items_->at(0).Type());
-  EXPECT_EQ(NGInlineItem::kControl, items_->at(1).Type());
-  EXPECT_EQ(NGInlineItem::kText, items_->at(2).Type());
-  EXPECT_EQ(NGInlineItem::kControl, items_->at(3).Type());
-  EXPECT_EQ(NGInlineItem::kText, items_->at(4).Type());
-  EXPECT_EQ(NGInlineItem::kControl, items_->at(5).Type());
+  EXPECT_EQ(6u, items_.size());
+  EXPECT_EQ(NGInlineItem::kText, items_[0].Type());
+  EXPECT_EQ(NGInlineItem::kControl, items_[1].Type());
+  EXPECT_EQ(NGInlineItem::kText, items_[2].Type());
+  EXPECT_EQ(NGInlineItem::kControl, items_[3].Type());
+  EXPECT_EQ(NGInlineItem::kText, items_[4].Type());
+  EXPECT_EQ(NGInlineItem::kControl, items_[5].Type());
 }
 
 TEST_F(NGInlineItemsBuilderTest, IgnorablePre) {
@@ -404,20 +399,20 @@
                  "orange"
                  "\n"
                  "grape"));
-  EXPECT_EQ(5u, items_->size());
-  EXPECT_ITEM_OFFSET(items_->at(0), NGInlineItem::kText, 0u, 5u);
-  EXPECT_ITEM_OFFSET(items_->at(1), NGInlineItem::kControl, 5u, 6u);
-  EXPECT_ITEM_OFFSET(items_->at(2), NGInlineItem::kText, 6u, 12u);
-  EXPECT_ITEM_OFFSET(items_->at(3), NGInlineItem::kControl, 12u, 13u);
-  EXPECT_ITEM_OFFSET(items_->at(4), NGInlineItem::kText, 13u, 18u);
+  EXPECT_EQ(5u, items_.size());
+  EXPECT_ITEM_OFFSET(items_[0], NGInlineItem::kText, 0u, 5u);
+  EXPECT_ITEM_OFFSET(items_[1], NGInlineItem::kControl, 5u, 6u);
+  EXPECT_ITEM_OFFSET(items_[2], NGInlineItem::kText, 6u, 12u);
+  EXPECT_ITEM_OFFSET(items_[3], NGInlineItem::kControl, 12u, 13u);
+  EXPECT_ITEM_OFFSET(items_[4], NGInlineItem::kText, 13u, 18u);
 }
 
 TEST_F(NGInlineItemsBuilderTest, Empty) {
-  HeapVector<NGInlineItem> items;
+  Vector<NGInlineItem> items;
   NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
-  ComputedStyle* block_style =
-      GetDocument().GetStyleResolver().CreateComputedStyle();
-  builder.EnterBlock(block_style);
+  scoped_refptr<ComputedStyle> block_style(
+      GetDocument().GetStyleResolver().CreateComputedStyle());
+  builder.EnterBlock(block_style.get());
   builder.ExitBlock();
 
   EXPECT_EQ("", builder.ToString());
@@ -456,13 +451,13 @@
 }
 
 TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) {
-  HeapVector<NGInlineItem> items;
+  Vector<NGInlineItem> items;
   NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
-  ComputedStyle* block_style =
-      GetDocument().GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> block_style(
+      GetDocument().GetStyleResolver().CreateComputedStyle());
   block_style->SetUnicodeBidi(UnicodeBidi::kBidiOverride);
   block_style->SetDirection(TextDirection::kRtl);
-  builder.EnterBlock(block_style);
+  builder.EnterBlock(block_style.get());
   AppendText("Hello", &builder);
   builder.ExitBlock();
 
@@ -477,8 +472,9 @@
 static LayoutInline* CreateLayoutInline(
     Document* document,
     void (*initialize_style)(ComputedStyle*)) {
-  ComputedStyle* style = document->GetStyleResolver().CreateComputedStyle();
-  initialize_style(style);
+  scoped_refptr<ComputedStyle> style(
+      document->GetStyleResolver().CreateComputedStyle());
+  initialize_style(style.get());
   LayoutInline* const node = LayoutInline::CreateAnonymous(document);
   node->SetModifiedStyleOutsideStyleRecalc(
       std::move(style), LayoutObject::ApplyStyleChanges::kNo);
@@ -487,7 +483,7 @@
 }
 
 TEST_F(NGInlineItemsBuilderTest, BidiIsolate) {
-  HeapVector<NGInlineItem> items;
+  Vector<NGInlineItem> items;
   NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
   AppendText("Hello ", &builder);
   LayoutInline* const isolate_rtl =
@@ -512,7 +508,7 @@
 }
 
 TEST_F(NGInlineItemsBuilderTest, BidiIsolateOverride) {
-  HeapVector<NGInlineItem> items;
+  Vector<NGInlineItem> items;
   NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
   AppendText("Hello ", &builder);
   LayoutInline* const isolate_override_rtl =
@@ -537,7 +533,7 @@
 }
 
 TEST_F(NGInlineItemsBuilderTest, HasRuby) {
-  HeapVector<NGInlineItem> items;
+  Vector<NGInlineItem> items;
   NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
   EXPECT_FALSE(HasRuby(builder)) << "has_ruby_ should be false initially.";
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index 119c4d11..890822d 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -134,7 +134,7 @@
   // Check if the box states in NGChildLayoutContext is valid for this line.
   // If the previous line was ::first-line, always rebuild because box states
   // have ::first-line styles.
-  const HeapVector<NGInlineItem>& items = line_info.ItemsData().items;
+  const Vector<NGInlineItem>& items = line_info.ItemsData().items;
   if (!break_token->UseFirstLineStyle()) {
     box_states_ =
         context_->BoxStatesIfValidForItemIndex(items, break_token->ItemIndex());
@@ -286,7 +286,7 @@
       has_out_of_flow_positioned_items = true;
     } else if (item.Type() == NGInlineItem::kFloating) {
       if (item_result.positioned_float) {
-        if (const NGLayoutResult* layout_result =
+        if (scoped_refptr<const NGLayoutResult> layout_result =
                 item_result.positioned_float->layout_result) {
           line_box->AddChild(std::move(layout_result),
                              item_result.positioned_float->bfc_offset,
@@ -713,25 +713,24 @@
     // If this is an empty inline, all floats are positioned during the
     // PositionLeadingFloats step.
     if (child.unpositioned_float) {
-      NGPositionedFloat* positioned_float = PositionFloat(
+      NGPositionedFloat positioned_float = PositionFloat(
           origin_bfc_block_offset, child.unpositioned_float, exclusion_space);
-      if (positioned_float->need_break_before) {
+      if (positioned_float.need_break_before) {
         // We decided to break before the float. No fragment here. Create a
         // break token and propagate it to the block container.
-        NGBlockNode float_node(To<LayoutBox>(child.unpositioned_float.Get()));
-        auto* break_before = NGBlockBreakToken::CreateBreakBefore(
+        NGBlockNode float_node(To<LayoutBox>(child.unpositioned_float));
+        auto break_before = NGBlockBreakToken::CreateBreakBefore(
             float_node, /* is_forced_break */ false);
-        context_->PropagateBreakToken(break_before);
+        context_->PropagateBreakToken(std::move(break_before));
         continue;
       } else {
         // If the float broke inside, we need to propagate the break token to
         // the block container, so that we'll resume in the next fragmentainer.
-        if (const NGBreakToken* token =
-                positioned_float->layout_result->PhysicalFragment()
-                    .BreakToken())
-          context_->PropagateBreakToken(To<NGBlockBreakToken>(token));
-        child.layout_result = std::move(positioned_float->layout_result);
-        child.bfc_offset = positioned_float->bfc_offset;
+        if (scoped_refptr<const NGBreakToken> token =
+                positioned_float.layout_result->PhysicalFragment().BreakToken())
+          context_->PropagateBreakToken(To<NGBlockBreakToken>(token.get()));
+        child.layout_result = std::move(positioned_float.layout_result);
+        child.bfc_offset = positioned_float.bfc_offset;
         child.unpositioned_float = nullptr;
       }
     }
@@ -934,7 +933,7 @@
   return content_size;
 }
 
-const NGLayoutResult* NGInlineLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGInlineLayoutAlgorithm::Layout() {
   NGExclusionSpace initial_exclusion_space(ConstraintSpace().ExclusionSpace());
 
   const bool is_empty_inline = Node().IsEmptyInline();
@@ -1105,9 +1104,9 @@
 
     // Propagate any break tokens for floats that we fragmented before or inside
     // to the block container.
-    for (const NGBlockBreakToken* float_break_token :
+    for (scoped_refptr<const NGBlockBreakToken> float_break_token :
          line_breaker.PropagatedBreakTokens())
-      context_->PropagateBreakToken(float_break_token);
+      context_->PropagateBreakToken(std::move(float_break_token));
 
     if (is_empty_inline) {
       DCHECK_EQ(container_builder_.BlockSize(), 0);
@@ -1135,7 +1134,8 @@
 
   DCHECK(items_builder);
   container_builder_.PropagateChildrenData(*line_box);
-  const NGLayoutResult* layout_result = container_builder_.ToLineBoxFragment();
+  scoped_refptr<const NGLayoutResult> layout_result =
+      container_builder_.ToLineBoxFragment();
   items_builder->AssociateLogicalLineItems(line_box,
                                            layout_result->PhysicalFragment());
   return layout_result;
@@ -1148,7 +1148,7 @@
     NGPositionedFloatVector* positioned_floats) {
   bool is_empty_inline = Node().IsEmptyInline();
 
-  const HeapVector<NGInlineItem>& items =
+  const Vector<NGInlineItem>& items =
       Node().ItemsData(/* is_first_line */ false).items;
 
   unsigned index = BreakToken() ? BreakToken()->ItemIndex() : 0;
@@ -1176,31 +1176,31 @@
         is_empty_inline ? ConstraintSpace().ExpectedBfcBlockOffset()
                         : ConstraintSpace().BfcOffset().block_offset;
 
-    NGPositionedFloat* positioned_float = PositionFloat(
+    NGPositionedFloat positioned_float = PositionFloat(
         origin_bfc_block_offset, item.GetLayoutObject(), exclusion_space);
 
     if (ConstraintSpace().HasBlockFragmentation()) {
       // Propagate any breaks before or inside floats to the block container.
-      if (positioned_float->need_break_before) {
+      if (positioned_float.need_break_before) {
         NGBlockNode float_node(To<LayoutBox>(item.GetLayoutObject()));
-        auto* break_before = NGBlockBreakToken::CreateBreakBefore(
+        auto break_before = NGBlockBreakToken::CreateBreakBefore(
             float_node, /* is_forced_break */ false);
-        context_->PropagateBreakToken(break_before);
-        positioned_float->layout_result = nullptr;
-      } else if (const NGBreakToken* token =
-                     positioned_float->layout_result->PhysicalFragment()
+        context_->PropagateBreakToken(std::move(break_before));
+        positioned_float.layout_result = nullptr;
+      } else if (scoped_refptr<const NGBreakToken> token =
+                     positioned_float.layout_result->PhysicalFragment()
                          .BreakToken()) {
-        context_->PropagateBreakToken(To<NGBlockBreakToken>(token));
+        context_->PropagateBreakToken(To<NGBlockBreakToken>(token.get()));
       }
     }
 
-    positioned_floats->push_back(positioned_float);
+    positioned_floats->push_back(std::move(positioned_float));
   }
 
   return index;
 }
 
-NGPositionedFloat* NGInlineLayoutAlgorithm::PositionFloat(
+NGPositionedFloat NGInlineLayoutAlgorithm::PositionFloat(
     LayoutUnit origin_bfc_block_offset,
     LayoutObject* floating_object,
     NGExclusionSpace* exclusion_space) const {
@@ -1278,8 +1278,12 @@
   // Reorder to the visual order.
   NGLogicalLineItems visual_items;
   visual_items.ReserveInitialCapacity(line_box->size());
-  for (unsigned logical_index : indices_in_visual_order)
+  for (unsigned logical_index : indices_in_visual_order) {
     visual_items.AddChild(std::move((*line_box)[logical_index]));
+    DCHECK(!(*line_box)[logical_index].HasInFlowFragment() ||
+           // |inline_item| will not be null by moving.
+           (*line_box)[logical_index].inline_item);
+  }
   DCHECK_EQ(line_box->size(), visual_items.size());
   *line_box = std::move(visual_items);
 }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h
index f86d109..42f28b34 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h
@@ -51,7 +51,7 @@
                   NGLogicalLineItems* line_box,
                   NGExclusionSpace*);
 
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override {
@@ -61,9 +61,9 @@
 
  private:
   unsigned PositionLeadingFloats(NGExclusionSpace*, NGPositionedFloatVector*);
-  NGPositionedFloat* PositionFloat(LayoutUnit origin_block_bfc_offset,
-                                   LayoutObject* floating_object,
-                                   NGExclusionSpace*) const;
+  NGPositionedFloat PositionFloat(LayoutUnit origin_block_bfc_offset,
+                                  LayoutObject* floating_object,
+                                  NGExclusionSpace*) const;
 
   void PrepareBoxStates(const NGLineInfo&, const NGInlineBreakToken*);
   void RebuildBoxStates(const NGLineInfo&,
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
index 5a32738..4e87c6c 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
@@ -58,19 +58,19 @@
                                        container_builder.GetWritingDirection());
   container_builder.SetItemsBuilder(&items_builder);
   context.SetItemsBuilder(&items_builder);
-  const NGLayoutResult* layout_result =
+  scoped_refptr<const NGLayoutResult> layout_result =
       inline_node.Layout(constraint_space, nullptr, &context);
   const auto& line1 = layout_result->PhysicalFragment();
   EXPECT_TRUE(line1.BreakToken());
 
   // Perform 2nd layout with the break token from the 1st line.
-  const NGLayoutResult* layout_result2 =
+  scoped_refptr<const NGLayoutResult> layout_result2 =
       inline_node.Layout(constraint_space, line1.BreakToken(), &context);
   const auto& line2 = layout_result2->PhysicalFragment();
   EXPECT_TRUE(line2.BreakToken());
 
   // Perform 3rd layout with the break token from the 2nd line.
-  const NGLayoutResult* layout_result3 =
+  scoped_refptr<const NGLayoutResult> layout_result3 =
       inline_node.Layout(constraint_space, line2.BreakToken(), &context);
   const auto& line3 = layout_result3->PhysicalFragment();
   EXPECT_FALSE(line3.BreakToken());
@@ -190,7 +190,7 @@
   NGBlockNode block_node(block_flow);
   NGConstraintSpace space =
       NGConstraintSpace::CreateFromLayoutObject(*block_flow);
-  const NGLayoutResult* layout_result = block_node.Layout(space);
+  scoped_refptr<const NGLayoutResult> layout_result = block_node.Layout(space);
 
   EXPECT_TRUE(layout_result->BfcBlockOffset().has_value());
   EXPECT_EQ(0, *layout_result->BfcBlockOffset());
@@ -262,7 +262,7 @@
   )HTML");
   // ** Run LayoutNG algorithm **
   NGConstraintSpace space;
-  const NGPhysicalBoxFragment* html_fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> html_fragment;
   std::tie(html_fragment, space) = RunBlockLayoutAlgorithmForElement(
       GetDocument().getElementsByTagName("html")->item(0));
   auto* body_fragment =
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
index 616151d..1c7dd9a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -155,7 +155,7 @@
 
  public:
   ReusingTextShaper(NGInlineItemsData* data,
-                    const HeapVector<NGInlineItem>* reusable_items)
+                    const Vector<NGInlineItem>* reusable_items)
       : data_(*data),
         reusable_items_(reusable_items),
         shaper_(data->text_content) {}
@@ -261,7 +261,7 @@
   }
 
   NGInlineItemsData& data_;
-  const HeapVector<NGInlineItem>* const reusable_items_;
+  const Vector<NGInlineItem>* const reusable_items_;
   HarfBuzzShaper shaper_;
 };
 
@@ -474,30 +474,31 @@
 
 bool NGInlineNode::IsPrepareLayoutFinished() const {
   const NGInlineNodeData* data =
-      To<LayoutBlockFlow>(box_.Get())->GetNGInlineNodeData();
+      To<LayoutBlockFlow>(box_)->GetNGInlineNodeData();
   return data && !data->text_content.IsNull();
 }
 
 void NGInlineNode::PrepareLayoutIfNeeded() const {
-  NGInlineNodeData* previous_data = nullptr;
+  std::unique_ptr<NGInlineNodeData> previous_data;
   LayoutBlockFlow* block_flow = GetLayoutBlockFlow();
   if (IsPrepareLayoutFinished()) {
     if (!block_flow->NeedsCollectInlines())
       return;
 
-    previous_data = block_flow->TakeNGInlineNodeData();
+    previous_data.reset(block_flow->TakeNGInlineNodeData());
     block_flow->ResetNGInlineNodeData();
   }
 
-  PrepareLayout(previous_data);
+  PrepareLayout(std::move(previous_data));
 }
 
-void NGInlineNode::PrepareLayout(NGInlineNodeData* previous_data) const {
+void NGInlineNode::PrepareLayout(
+    std::unique_ptr<NGInlineNodeData> previous_data) const {
   // Scan list of siblings collecting all in-flow non-atomic inlines. A single
   // NGInlineNode represent a collection of adjacent non-atomic inlines.
   NGInlineNodeData* data = MutableData();
   DCHECK(data);
-  CollectInlines(data, previous_data);
+  CollectInlines(data, previous_data.get());
   SegmentText(data);
   ShapeText(data, previous_data ? &previous_data->text_content : nullptr);
   ShapeTextForFirstLineIfNeeded(data);
@@ -513,7 +514,7 @@
   DCHECK(!data->offset_mapping);
   ComputeOffsetMappingIfNeeded();
   DCHECK(data->offset_mapping);
-  data->offset_mapping.Clear();
+  data->offset_mapping.reset();
 #endif
 }
 
@@ -560,8 +561,8 @@
     const NGOffsetMapping* const offset_mapping =
         NGInlineNode::GetOffsetMapping(block_flow_);
     DCHECK(offset_mapping);
-    data_ = block_flow_->TakeNGInlineNodeData();
-    return data_;
+    data_.reset(block_flow_->TakeNGInlineNodeData());
+    return data_.get();
   }
 
   void Run() {
@@ -580,9 +581,8 @@
     DCHECK_LE(start_offset, new_length - matched_length);
     const unsigned end_offset = old_length - matched_length;
     DCHECK_LE(start_offset, end_offset);
-    HeapVector<NGInlineItem> items;
-    ClearCollectionScope<HeapVector<NGInlineItem>> clear_scope(&items);
 
+    Vector<NGInlineItem> items;
     // +3 for before and after replaced text.
     items.ReserveInitialCapacity(data_->items.size() + 3);
 
@@ -822,7 +822,7 @@
         item->shape_result_->CopyAdjustedOffset(item->start_offset_);
   }
 
-  void VerifyItems(const HeapVector<NGInlineItem>& items) const {
+  void VerifyItems(const Vector<NGInlineItem>& items) const {
 #if DCHECK_IS_ON()
     if (items.IsEmpty())
       return;
@@ -842,7 +842,7 @@
 #endif
   }
 
-  NGInlineNodeData* data_;
+  std::unique_ptr<NGInlineNodeData> data_;
   LayoutBlockFlow* const block_flow_;
   const LayoutText& layout_text_;
 };
@@ -910,7 +910,7 @@
     DCHECK(data->offset_mapping);
   }
 
-  return data->offset_mapping;
+  return data->offset_mapping.get();
 }
 
 void NGInlineNode::ComputeOffsetMapping(LayoutBlockFlow* layout_block_flow,
@@ -923,8 +923,7 @@
   // NGInlineItems and text content built by |builder|, because they are
   // already there in NGInlineNodeData. For efficiency, we should make
   // |builder| not construct items and text content.
-  HeapVector<NGInlineItem> items;
-  ClearCollectionScope<HeapVector<NGInlineItem>> clear_scope(&items);
+  Vector<NGInlineItem> items;
   items.ReserveCapacity(EstimateInlineItemsCount(*layout_block_flow));
   NGInlineItemsBuilderForOffsetMapping builder(layout_block_flow, &items);
   builder.GetOffsetMappingBuilder().ReserveCapacity(
@@ -972,10 +971,10 @@
   // |LayoutBlockFlowRareData|.
   if (const NGOffsetMapping* mapping = layout_block_flow->GetOffsetMapping())
     return mapping;
-  NGInlineNodeData* data = MakeGarbageCollected<NGInlineNodeData>();
-  ComputeOffsetMapping(layout_block_flow, data);
-  NGOffsetMapping* const mapping = data->offset_mapping.Release();
-  layout_block_flow->SetOffsetMapping(mapping);
+  NGInlineNodeData data;
+  ComputeOffsetMapping(layout_block_flow, &data);
+  NGOffsetMapping* const mapping = data.offset_mapping.get();
+  layout_block_flow->SetOffsetMapping(std::move(data.offset_mapping));
   return mapping;
 }
 
@@ -997,8 +996,7 @@
     // Build NGInlineItems and NGOffsetMapping first.  They are used only by
     // NGSVGTextLayoutAttributesBuilder, and are discarded because they might
     // be different from final ones.
-    HeapVector<NGInlineItem> items;
-    ClearCollectionScope<HeapVector<NGInlineItem>> clear_scope(&items);
+    Vector<NGInlineItem> items;
     items.ReserveCapacity(EstimateInlineItemsCount(*block));
     NGInlineItemsBuilderForOffsetMapping items_builder(block, &items);
     items_builder.GetOffsetMappingBuilder().ReserveCapacity(
@@ -1008,10 +1006,10 @@
     NGSVGTextLayoutAttributesBuilder svg_attr_builder(*this);
     svg_attr_builder.Build(items_builder.ToString(), items);
 
-    auto* svg_data = MakeGarbageCollected<SVGInlineNodeData>();
+    auto svg_data = std::make_unique<SVGInlineNodeData>();
     svg_data->character_data_list = svg_attr_builder.CharacterDataList();
     svg_data->text_path_range_list = svg_attr_builder.TextPathRangeList();
-    data->svg_node_data_ = svg_data;
+    data->svg_node_data_ = std::move(svg_data);
 
     // TODO(tkent): Pass "text chunk" information to NGInlineItemsBuilder.
   }
@@ -1042,7 +1040,7 @@
     return;
   }
 
-  HeapVector<NGInlineItem>& items = data->items;
+  Vector<NGInlineItem>& items = data->items;
   if (items.IsEmpty()) {
     return;
   }
@@ -1123,7 +1121,7 @@
   if (GetLayoutBlockFlow()->IsHorizontalWritingMode())
     return;
 
-  HeapVector<NGInlineItem>& items = data->items;
+  Vector<NGInlineItem>& items = data->items;
   if (items.IsEmpty())
     return;
   String& text_content = data->text_content;
@@ -1182,7 +1180,7 @@
     return;
   }
 
-  HeapVector<NGInlineItem>& items = data->items;
+  Vector<NGInlineItem>& items = data->items;
   unsigned item_index = 0;
   for (unsigned start = 0; start < data->text_content.length();) {
     UBiDiLevel level;
@@ -1202,13 +1200,12 @@
 #endif
 }
 
-void NGInlineNode::ShapeText(
-    NGInlineItemsData* data,
-    const String* previous_text,
-    const HeapVector<NGInlineItem>* previous_items) const {
+void NGInlineNode::ShapeText(NGInlineItemsData* data,
+                             const String* previous_text,
+                             const Vector<NGInlineItem>* previous_items) const {
   TRACE_EVENT0("fonts", "NGInlineNode::ShapeText");
   const String& text_content = data->text_content;
-  HeapVector<NGInlineItem>* items = &data->items;
+  Vector<NGInlineItem>* items = &data->items;
 
   // Provide full context of the entire node to the shaper.
   ReusingTextShaper shaper(data, previous_items);
@@ -1387,7 +1384,7 @@
 #endif
 }
 
-// Create HeapVector<NGInlineItem> with :first-line rules applied if needed.
+// Create Vector<NGInlineItem> with :first-line rules applied if needed.
 void NGInlineNode::ShapeTextForFirstLineIfNeeded(NGInlineNodeData* data) const {
   // First check if the document has any :first-line rules.
   DCHECK(!data->first_line_items_);
@@ -1401,7 +1398,7 @@
   if (block_style == first_line_style)
     return;
 
-  auto* first_line_items = MakeGarbageCollected<NGInlineItemsData>();
+  auto first_line_items = std::make_unique<NGInlineItemsData>();
   first_line_items->text_content = data->text_content;
   bool needs_reshape = false;
   if (first_line_style->TextTransform() != block_style->TextTransform()) {
@@ -1428,19 +1425,18 @@
 
   // Re-shape if the font is different.
   if (needs_reshape || FirstLineNeedsReshape(*first_line_style, *block_style))
-    ShapeText(first_line_items);
+    ShapeText(first_line_items.get());
 
-  data->first_line_items_ = first_line_items;
+  data->first_line_items_ = std::move(first_line_items);
 }
 
 void NGInlineNode::AssociateItemsWithInlines(NGInlineNodeData* data) const {
 #if DCHECK_IS_ON()
-  HeapHashSet<Member<LayoutObject>> associated_objects;
+  HashSet<LayoutObject*> associated_objects;
 #endif
-  HeapVector<NGInlineItem>& items = data->items;
-  size_t size = items.size();
-  for (size_t i = 0; i != size;) {
-    LayoutObject* object = items[i].GetLayoutObject();
+  Vector<NGInlineItem>& items = data->items;
+  for (NGInlineItem* item = items.begin(); item != items.end();) {
+    LayoutObject* object = item->GetLayoutObject();
     if (auto* layout_text = DynamicTo<LayoutNGText>(object)) {
 #if DCHECK_IS_ON()
       // Items split from a LayoutObject should be consecutive.
@@ -1448,24 +1444,23 @@
 #endif
       layout_text->ClearHasBidiControlInlineItems();
       bool has_bidi_control = false;
-      size_t begin = i;
-      for (++i; i != size; ++i) {
-        auto& item = items[i];
-        if (item.GetLayoutObject() != object)
+      NGInlineItem* begin = item;
+      for (++item; item != items.end(); ++item) {
+        if (item->GetLayoutObject() != object)
           break;
-        if (item.Type() == NGInlineItem::kBidiControl)
+        if (item->Type() == NGInlineItem::kBidiControl)
           has_bidi_control = true;
       }
-      layout_text->SetInlineItems(data, begin, i - begin);
+      layout_text->SetInlineItems(begin, item);
       if (has_bidi_control)
         layout_text->SetHasBidiControlInlineItems();
       continue;
     }
-    ++i;
+    ++item;
   }
 }
 
-const NGLayoutResult* NGInlineNode::Layout(
+scoped_refptr<const NGLayoutResult> NGInlineNode::Layout(
     const NGConstraintSpace& constraint_space,
     const NGBreakToken* break_token,
     NGInlineChildLayoutContext* context) const {
@@ -1572,7 +1567,7 @@
       EFloat previous_float_type = EFloat::kNone;
       for (const auto& floating_object : floating_objects_) {
         const EClear float_clear =
-            floating_object.float_style->Clear(*floating_object.style);
+            floating_object.float_style.Clear(floating_object.style);
 
         // If this float clears the previous float we start a new "line".
         // This is subtly different to block layout which will only reset either
@@ -1591,7 +1586,7 @@
         floats_inline_size_ += floating_object.float_inline_max_size_with_margin
                                    .ClampNegativeToZero();
         previous_float_type =
-            floating_object.float_style->Floating(*floating_object.style);
+            floating_object.float_style.Floating(floating_object.style);
       }
       max_inline_size =
           std::max(max_inline_size, line_inline_size + floats_inline_size_);
@@ -1842,7 +1837,7 @@
 
 void NGInlineNode::CheckConsistency() const {
 #if DCHECK_IS_ON()
-  const HeapVector<NGInlineItem>& items = Data().items;
+  const Vector<NGInlineItem>& items = Data().items;
   for (const NGInlineItem& item : items) {
     DCHECK(!item.GetLayoutObject() || !item.Style() ||
            item.Style() == item.GetLayoutObject()->Style());
@@ -1864,7 +1859,7 @@
   return Data().svg_node_data_->character_data_list;
 }
 
-const HeapVector<SVGTextPathRange>& NGInlineNode::SVGTextPathRangeList() const {
+const Vector<SVGTextPathRange>& NGInlineNode::SVGTextPathRangeList() const {
   DCHECK(IsSVGText());
   return Data().svg_node_data_->text_path_range_list;
 }
@@ -1877,9 +1872,4 @@
   return "NGInlineNode";
 }
 
-void NGInlineNode::FloatingObject::Trace(Visitor* visitor) const {
-  visitor->Trace(float_style);
-  visitor->Trace(style);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
index ea06056a..5f2e3f5 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
@@ -30,13 +30,14 @@
   explicit NGInlineNode(std::nullptr_t) : NGLayoutInputNode(nullptr) {}
 
   LayoutBlockFlow* GetLayoutBlockFlow() const {
-    return To<LayoutBlockFlow>(box_.Get());
+    return To<LayoutBlockFlow>(box_);
   }
   NGLayoutInputNode NextSibling() const { return nullptr; }
 
-  const NGLayoutResult* Layout(const NGConstraintSpace&,
-                               const NGBreakToken*,
-                               NGInlineChildLayoutContext* context) const;
+  scoped_refptr<const NGLayoutResult> Layout(
+      const NGConstraintSpace&,
+      const NGBreakToken*,
+      NGInlineChildLayoutContext* context) const;
 
   // Computes the value of min-content and max-content for this anonymous block
   // box. min-content is the inline size when lines wrap at every break
@@ -118,17 +119,17 @@
   const Vector<std::pair<unsigned, NGSVGCharacterData>>& SVGCharacterDataList()
       const;
   // This function is available after PrepareLayout(), only for SVG <text>.
-  const HeapVector<SVGTextPathRange>& SVGTextPathRangeList() const;
+  const Vector<SVGTextPathRange>& SVGTextPathRangeList() const;
 
   String ToString() const;
 
   struct FloatingObject {
     DISALLOW_NEW();
 
-    void Trace(Visitor* visitor) const;
+    void Trace(Visitor* visitor) const {}
 
-    Member<const ComputedStyle> const float_style;
-    Member<const ComputedStyle> const style;
+    const ComputedStyle& float_style;
+    const ComputedStyle& style;
     LayoutUnit float_inline_max_size_with_margin;
   };
 
@@ -142,7 +143,7 @@
   // Prepare inline and text content for layout. Must be called before
   // calling the Layout method.
   void PrepareLayoutIfNeeded() const;
-  void PrepareLayout(NGInlineNodeData* previous_data) const;
+  void PrepareLayout(std::unique_ptr<NGInlineNodeData> previous_data) const;
 
   void CollectInlines(NGInlineNodeData*,
                       NGInlineNodeData* previous_data = nullptr) const;
@@ -150,25 +151,24 @@
   void SegmentScriptRuns(NGInlineNodeData*) const;
   void SegmentFontOrientation(NGInlineNodeData*) const;
   void SegmentBidiRuns(NGInlineNodeData*) const;
-  void ShapeText(
-      NGInlineItemsData*,
-      const String* previous_text = nullptr,
-      const HeapVector<NGInlineItem>* previous_items = nullptr) const;
+  void ShapeText(NGInlineItemsData*,
+                 const String* previous_text = nullptr,
+                 const Vector<NGInlineItem>* previous_items = nullptr) const;
   void ShapeTextForFirstLineIfNeeded(NGInlineNodeData*) const;
   void AssociateItemsWithInlines(NGInlineNodeData*) const;
 
   NGInlineNodeData* MutableData() const {
-    return To<LayoutBlockFlow>(box_.Get())->GetNGInlineNodeData();
+    return To<LayoutBlockFlow>(box_)->GetNGInlineNodeData();
   }
   const NGInlineNodeData& Data() const {
     DCHECK(IsPrepareLayoutFinished() &&
            !GetLayoutBlockFlow()->NeedsCollectInlines());
-    return *To<LayoutBlockFlow>(box_.Get())->GetNGInlineNodeData();
+    return *To<LayoutBlockFlow>(box_)->GetNGInlineNodeData();
   }
   // Same as |Data()| but can access even when |NeedsCollectInlines()| is set.
   const NGInlineNodeData& MaybeDirtyData() const {
     DCHECK(IsPrepareLayoutFinished());
-    return *To<LayoutBlockFlow>(box_.Get())->GetNGInlineNodeData();
+    return *To<LayoutBlockFlow>(box_)->GetNGInlineNodeData();
   }
   const NGInlineNodeData& EnsureData() const;
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.cc
deleted file mode 100644
index 3d7ecd30..0000000
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.cc
+++ /dev/null
@@ -1,17 +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/core/layout/ng/inline/ng_inline_node_data.h"
-
-#include "third_party/blink/renderer/core/layout/ng/svg/svg_inline_node_data.h"
-
-namespace blink {
-
-void NGInlineNodeData::Trace(Visitor* visitor) const {
-  visitor->Trace(first_line_items_);
-  visitor->Trace(svg_node_data_);
-  NGInlineItemsData::Trace(visitor);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h
index 248779bb..06129bc 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h
@@ -7,15 +7,15 @@
 
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h"
+#include "third_party/blink/renderer/core/layout/ng/svg/svg_inline_node_data.h"
 
 namespace blink {
 
 template <typename OffsetMappingBuilder>
 class NGInlineItemsBuilderTemplate;
-struct SVGInlineNodeData;
 
 // Data which is required for inline nodes.
-struct CORE_EXPORT NGInlineNodeData final : NGInlineItemsData {
+struct CORE_EXPORT NGInlineNodeData : NGInlineItemsData {
  public:
   bool IsBidiEnabled() const { return is_bidi_enabled_; }
   TextDirection BaseDirection() const {
@@ -34,8 +34,6 @@
                : *first_line_items_;
   }
 
-  void Trace(Visitor* visitor) const override;
-
  private:
   void SetBaseDirection(TextDirection direction) {
     base_direction_ = static_cast<unsigned>(direction);
@@ -54,9 +52,9 @@
   // Items have different ComputedStyle, and may also have different
   // text_content and ShapeResult if 'text-transform' is applied or fonts are
   // different.
-  Member<NGInlineItemsData> first_line_items_;
+  std::unique_ptr<NGInlineItemsData> first_line_items_;
 
-  Member<SVGInlineNodeData> svg_node_data_;
+  std::unique_ptr<SVGInlineNodeData> svg_node_data_;
 
   unsigned is_bidi_enabled_ : 1;
   unsigned base_direction_ : 1;  // TextDirection
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
index 05e8e28..873e080 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
@@ -12,7 +12,6 @@
 #include "third_party/blink/renderer/core/html_names.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_span.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
@@ -38,8 +37,8 @@
   using NGInlineNode::NGInlineNode;
 
   std::string Text() const { return Data().text_content.Utf8(); }
-  HeapVector<NGInlineItem>& Items() { return MutableData()->items; }
-  static HeapVector<NGInlineItem>& Items(NGInlineNodeData& data) {
+  Vector<NGInlineItem>& Items() { return MutableData()->items; }
+  static Vector<NGInlineItem>& Items(NGInlineNodeData& data) {
     return data.items;
   }
 
@@ -121,7 +120,7 @@
     return data->text_content;
   }
 
-  HeapVector<NGInlineItem>& Items() {
+  Vector<NGInlineItem>& Items() {
     NGInlineNodeData* data = layout_block_flow_->GetNGInlineNodeData();
     CHECK(data);
     return NGInlineNodeForTest::Items(*data);
@@ -156,8 +155,8 @@
     EXPECT_FALSE(expected);
   }
 
-  Persistent<LayoutNGBlockFlow> layout_block_flow_;
-  Persistent<LayoutObject> layout_object_;
+  LayoutNGBlockFlow* layout_block_flow_ = nullptr;
+  LayoutObject* layout_object_ = nullptr;
   FontCachePurgePreventer purge_preventer_;
 };
 
@@ -182,7 +181,7 @@
   NGInlineNodeForTest node = CreateInlineNode();
   node.CollectInlines();
   EXPECT_FALSE(node.IsBidiEnabled());
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   TEST_ITEM_TYPE_OFFSET(items[0], kText, 0u, 6u);
   TEST_ITEM_TYPE_OFFSET(items[1], kOpenTag, 6u, 6u);
   TEST_ITEM_TYPE_OFFSET(items[2], kText, 6u, 12u);
@@ -197,7 +196,7 @@
   node.CollectInlines();
   EXPECT_EQ("Hello\nWorld", node.Text());
   EXPECT_FALSE(node.IsBidiEnabled());
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   TEST_ITEM_TYPE_OFFSET(items[0], kText, 0u, 5u);
   TEST_ITEM_TYPE_OFFSET(items[1], kControl, 5u, 6u);
   TEST_ITEM_TYPE_OFFSET(items[2], kText, 6u, 11u);
@@ -217,7 +216,7 @@
   node.CollectInlines();
   EXPECT_EQ(u8"abc\uFFFCghi\uFFFCmno", node.Text())
       << "floats are appeared as an object replacement character";
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   ASSERT_EQ(5u, items.size());
   TEST_ITEM_TYPE_OFFSET(items[0], kText, 0u, 3u);
   TEST_ITEM_TYPE_OFFSET(items[1], kFloating, 3u, 4u);
@@ -235,7 +234,7 @@
   node.CollectInlines();
   EXPECT_EQ(u8"abc\uFFFCjkl", node.Text())
       << "inline-block is appeared as an object replacement character";
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   ASSERT_EQ(3u, items.size());
   TEST_ITEM_TYPE_OFFSET(items[0], kText, 0u, 3u);
   TEST_ITEM_TYPE_OFFSET(items[1], kAtomicInline, 3u, 4u);
@@ -270,7 +269,7 @@
   EXPECT_TRUE(node.IsBidiEnabled());
   node.SegmentText();
   EXPECT_TRUE(node.IsBidiEnabled());
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   TEST_ITEM_TYPE_OFFSET_LEVEL(items[0], kText, 0u, 2u, 1u);
   TEST_ITEM_TYPE_OFFSET_LEVEL(items[1], kOpenTag, 2u, 2u, 1u);
   TEST_ITEM_TYPE_OFFSET_LEVEL(items[2], kText, 2u, 3u, 1u);
@@ -286,7 +285,7 @@
   EXPECT_TRUE(node.IsBidiEnabled());
   node.SegmentText();
   EXPECT_TRUE(node.IsBidiEnabled());
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   TEST_ITEM_TYPE_OFFSET_LEVEL(items[0], kText, 0u, 7u, 0u);
   TEST_ITEM_TYPE_OFFSET_LEVEL(items[1], kText, 7u, 9u, 1u);
   TEST_ITEM_TYPE_OFFSET_LEVEL(items[2], kOpenTag, 9u, 9u, 1u);
@@ -302,7 +301,7 @@
   EXPECT_TRUE(node.IsBidiEnabled());
   node.SegmentText();
   EXPECT_TRUE(node.IsBidiEnabled());
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   TEST_ITEM_TYPE_OFFSET_LEVEL(items[0], kText, 0u, 7u, 0u);
   TEST_ITEM_TYPE_OFFSET_LEVEL(items[1], kText, 7u, 9u, 1u);
   TEST_ITEM_TYPE_OFFSET_LEVEL(items[2], kOpenTag, 9u, 9u, 1u);
@@ -316,7 +315,7 @@
   NGInlineNodeForTest node = CreateInlineNode();
   node.Append("Hello", layout_object_);
   node.SegmentText();
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   ASSERT_EQ(1u, items.size());
   TEST_ITEM_OFFSET_DIR(items[0], 0u, 5u, TextDirection::kLtr);
 }
@@ -326,7 +325,7 @@
   node.Append(u"\u05E2\u05D1\u05E8\u05D9\u05EA", layout_object_);
   node.SegmentText();
   ASSERT_EQ(1u, node.Items().size());
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   ASSERT_EQ(1u, items.size());
   TEST_ITEM_OFFSET_DIR(items[0], 0u, 5u, TextDirection::kRtl);
 }
@@ -335,7 +334,7 @@
   NGInlineNodeForTest node = CreateInlineNode();
   node.Append(u"Hello \u05E2\u05D1\u05E8\u05D9\u05EA", layout_object_);
   node.SegmentText();
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   ASSERT_EQ(2u, items.size());
   TEST_ITEM_OFFSET_DIR(items[0], 0u, 6u, TextDirection::kLtr);
   TEST_ITEM_OFFSET_DIR(items[1], 6u, 11u, TextDirection::kRtl);
@@ -347,7 +346,7 @@
   node.Append(u"lo \u05E2", layout_object_);
   node.Append(u"\u05D1\u05E8\u05D9\u05EA", layout_object_);
   node.SegmentText();
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   ASSERT_EQ(4u, items.size());
   TEST_ITEM_OFFSET_DIR(items[0], 0u, 3u, TextDirection::kLtr);
   TEST_ITEM_OFFSET_DIR(items[1], 3u, 6u, TextDirection::kLtr);
@@ -362,7 +361,7 @@
   node.Append("ABC", layout_object_);
   node.Append(kPopDirectionalFormattingCharacter);
   node.SegmentText();
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   ASSERT_EQ(4u, items.size());
   TEST_ITEM_OFFSET_DIR(items[0], 0u, 6u, TextDirection::kLtr);
   TEST_ITEM_OFFSET_DIR(items[1], 6u, 7u, TextDirection::kRtl);
@@ -388,7 +387,7 @@
 TEST_F(NGInlineNodeTest, SegmentBidiIsolate) {
   NGInlineNodeForTest node = CreateInlineNode();
   node = CreateBidiIsolateNode(node, layout_object_);
-  HeapVector<NGInlineItem>& items = node.Items();
+  Vector<NGInlineItem>& items = node.Items();
   EXPECT_EQ(9u, items.size());
   TEST_ITEM_OFFSET_DIR(items[0], 0u, 6u, TextDirection::kLtr);
   TEST_ITEM_OFFSET_DIR(items[1], 6u, 7u, TextDirection::kLtr);
@@ -1381,7 +1380,7 @@
   auto* block_flow = To<LayoutNGBlockFlow>(GetLayoutObjectByElementId("p"));
   const NGInlineNodeData* data = block_flow->GetNGInlineNodeData();
   ASSERT_TRUE(data);
-  const auto& items = data->items;
+  const Vector<NGInlineItem>& items = data->items;
 
   // We shape "AV" together, which usually has kerning between "A" and "V", then
   // split the |ShapeResult| to two |NGInlineItem|s. The |NGInlineItem| for "V"
@@ -1410,7 +1409,7 @@
   auto* block_flow = To<LayoutNGBlockFlow>(GetLayoutObjectByElementId("p"));
   const NGInlineNodeData* data = block_flow->GetNGInlineNodeData();
   ASSERT_TRUE(data);
-  const auto& items = data->items;
+  const Vector<NGInlineItem>& items = data->items;
   const NGInlineItem& item_v = items[4];
   EXPECT_EQ(item_v.Type(), NGInlineItem::kText);
   EXPECT_EQ(
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
index 7c4d0c1e..984f06e7 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
@@ -58,7 +58,7 @@
     }
     if (child.out_of_flow_positioned_box) {
       AddOutOfFlowInlineChildCandidate(
-          NGBlockNode(To<LayoutBox>(child.out_of_flow_positioned_box.Get())),
+          NGBlockNode(To<LayoutBox>(child.out_of_flow_positioned_box)),
           child.Offset(), child.container_direction);
       child.out_of_flow_positioned_box = nullptr;
     }
@@ -68,15 +68,16 @@
   MoveOutOfFlowDescendantCandidatesToDescendants();
 }
 
-const NGLayoutResult* NGLineBoxFragmentBuilder::ToLineBoxFragment() {
+scoped_refptr<const NGLayoutResult>
+NGLineBoxFragmentBuilder::ToLineBoxFragment() {
   writing_direction_.SetWritingMode(ToLineWritingMode(GetWritingMode()));
 
-  const NGPhysicalLineBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalLineBoxFragment> fragment =
       NGPhysicalLineBoxFragment::Create(this);
 
-  return MakeGarbageCollected<NGLayoutResult>(
-      NGLayoutResult::NGLineBoxFragmentBuilderPassKey(), std::move(fragment),
-      this);
+  return base::AdoptRef(
+      new NGLayoutResult(NGLayoutResult::NGLineBoxFragmentBuilderPassKey(),
+                         std::move(fragment), this));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
index 2848421..6eded710 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
@@ -28,7 +28,7 @@
 
  public:
   NGLineBoxFragmentBuilder(NGInlineNode node,
-                           const ComputedStyle* style,
+                           scoped_refptr<const ComputedStyle> style,
                            const NGConstraintSpace* space,
                            WritingDirectionMode writing_direction)
       : NGContainerFragmentBuilder(
@@ -68,8 +68,8 @@
 
   // Set the break token for the fragment to build.
   // Is nullptr if we didn't break.
-  void SetBreakToken(const NGInlineBreakToken* break_token) {
-    break_token_ = break_token;
+  void SetBreakToken(scoped_refptr<NGInlineBreakToken> break_token) {
+    break_token_ = std::move(break_token);
   }
 
   // Propagate data in |ChildList| without adding them to this builder. When
@@ -78,7 +78,7 @@
   void PropagateChildrenData(NGLogicalLineItems&);
 
   // Creates the fragment. Can only be called once.
-  const NGLayoutResult* ToLineBoxFragment();
+  scoped_refptr<const NGLayoutResult> ToLineBoxFragment();
 
  private:
   FontHeight metrics_ = FontHeight::Empty();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
index d1cccb72..24fc517 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -116,10 +116,9 @@
 // padding, border, or margin.
 // The inline-end size from all of these ancestors contribute to the "used
 // size" of the float, and may cause the float to be pushed down.
-LayoutUnit ComputeFloatAncestorInlineEndSize(
-    const NGConstraintSpace& space,
-    const HeapVector<NGInlineItem>& items,
-    wtf_size_t item_index) {
+LayoutUnit ComputeFloatAncestorInlineEndSize(const NGConstraintSpace& space,
+                                             const Vector<NGInlineItem>& items,
+                                             wtf_size_t item_index) {
   LayoutUnit inline_end_size;
   for (const NGInlineItem *cur = items.begin() + item_index, *end = items.end();
        cur != end; ++cur) {
@@ -534,7 +533,7 @@
 void NGLineBreaker::BreakLine(
     NGLineInfo* line_info) {
   DCHECK(!line_info->IsLastLine());
-  const HeapVector<NGInlineItem>& items = Items();
+  const Vector<NGInlineItem>& items = Items();
   state_ = LineBreakState::kContinue;
   trailing_whitespace_ = WhitespaceState::kLeading;
   while (state_ != LineBreakState::kDone) {
@@ -651,7 +650,7 @@
     return false;
   // This kObjectReplacementCharacter can be any objects, such as a floating or
   // an OOF object. Check if it's really an atomic inline.
-  const HeapVector<NGInlineItem>& items = Items();
+  const Vector<NGInlineItem>& items = Items();
   for (const NGInlineItem* item = std::next(item_result.item);
        item != items.end(); ++item) {
     DCHECK_EQ(item->StartOffset(), item_result.EndOffset());
@@ -1499,7 +1498,7 @@
     // This is not a defined behavior, but legacy/WebKit do this for preserved
     // newlines and <br>s. Gecko does this only for preserved newlines (but
     // not for <br>s).
-    const HeapVector<NGInlineItem>& items = Items();
+    const Vector<NGInlineItem>& items = Items();
     while (item_index_ < items.size()) {
       const NGInlineItem& next_item = items[item_index_];
       if (next_item.Type() == NGInlineItem::kCloseTag) {
@@ -1825,15 +1824,15 @@
     return;
   }
 
-  NGPositionedFloat* positioned_float =
+  NGPositionedFloat positioned_float =
       PositionFloat(&unpositioned_float, exclusion_space_);
 
   if (constraint_space_.HasBlockFragmentation()) {
-    if (positioned_float->need_break_before) {
+    if (positioned_float.need_break_before) {
       // We broke before the float, and there's no fragment. Create a break
       // token and propagate it all the way to the block container layout
       // algorithm. The float will start in the next fragmentainer.
-      auto* break_before = NGBlockBreakToken::CreateBreakBefore(
+      auto break_before = NGBlockBreakToken::CreateBreakBefore(
           unpositioned_float.node, /* is_forced_break */ false);
       RemoveLastItem(line_info);
       PropagateBreakToken(break_before);
@@ -1842,9 +1841,9 @@
     // If we broke inside the float, we also need to propagate a break token to
     // the block container. Layout of the float will resume in the next
     // fragmentainer.
-    if (const NGBreakToken* token =
-            positioned_float->layout_result->PhysicalFragment().BreakToken())
-      PropagateBreakToken(To<NGBlockBreakToken>(token));
+    if (scoped_refptr<const NGBreakToken> token =
+            positioned_float.layout_result->PhysicalFragment().BreakToken())
+      PropagateBreakToken(std::move(To<NGBlockBreakToken>(token.get())));
   }
 
   item_result->positioned_float = positioned_float;
@@ -2066,7 +2065,7 @@
           }
           continue;
         }
-        const ComputedStyle* was_current_style = current_style_;
+        scoped_refptr<const ComputedStyle> was_current_style = current_style_;
         SetCurrentStyle(*item.Style());
         const NGInlineItemResult item_result_before = *item_result;
         BreakText(item_result, item, *item.TextShapeResult(),
@@ -2155,7 +2154,7 @@
 // Rewind to |new_end| on overflow. If trailable items follow at |new_end|, they
 // are included (not rewound).
 void NGLineBreaker::RewindOverflow(unsigned new_end, NGLineInfo* line_info) {
-  const HeapVector<NGInlineItem>& items = Items();
+  const Vector<NGInlineItem>& items = Items();
   const NGInlineItemResults& item_results = line_info->Results();
   DCHECK_LT(new_end, item_results.size());
 
@@ -2321,7 +2320,7 @@
     //   [7] kCloseTag 13-13 <i>
     // Note: We can have multiple empty |LayoutText| by ::first-letter, nested
     // <q>, Text.splitText(), etc.
-    const HeapVector<NGInlineItem>& items = Items();
+    const Vector<NGInlineItem>& items = Items();
     while (item_index_ < items.size() &&
            items[item_index_].Type() == NGInlineItem::kText &&
            !items[item_index_].Length())
@@ -2384,7 +2383,7 @@
 }
 
 void NGLineBreaker::SetCurrentStyle(const ComputedStyle& style) {
-  if (&style == current_style_) {
+  if (&style == current_style_.get()) {
 #if DCHECK_IS_ON()
     // Check that cache fields are already setup correctly.
     DCHECK_EQ(auto_wrap_, !is_svg_text_ && style.AutoWrap());
@@ -2454,7 +2453,7 @@
   offset_ = item.EndOffset();
   item_index_++;
 #if DCHECK_IS_ON()
-  const HeapVector<NGInlineItem>& items = Items();
+  const Vector<NGInlineItem>& items = Items();
   if (item_index_ < items.size()) {
     items[item_index_].AssertOffset(offset_);
   } else {
@@ -2471,25 +2470,27 @@
     item_index_++;
 }
 
-const NGInlineBreakToken* NGLineBreaker::CreateBreakToken(
+scoped_refptr<NGInlineBreakToken> NGLineBreaker::CreateBreakToken(
     const NGLineInfo& line_info) const {
   DCHECK(current_style_);
-  const HeapVector<NGInlineItem>& items = Items();
+  const Vector<NGInlineItem>& items = Items();
   DCHECK_LE(item_index_, items.size());
   if (item_index_ >= items.size())
     return nullptr;
   return NGInlineBreakToken::Create(
-      node_, current_style_, item_index_, offset_,
-      ((is_after_forced_break_ ? NGInlineBreakToken::kIsForcedBreak : 0) |
-       (line_info.UseFirstLineStyle() ? NGInlineBreakToken::kUseFirstLineStyle
-                                      : 0) |
-       (cloned_box_decorations_count_
-            ? NGInlineBreakToken::kHasClonedBoxDecorations
-            : 0)));
+      node_, current_style_.get(), item_index_, offset_,
+      (is_after_forced_break_ ? NGInlineBreakToken::kIsForcedBreak : 0) |
+          (line_info.UseFirstLineStyle()
+               ? NGInlineBreakToken::kUseFirstLineStyle
+               : 0) |
+          (cloned_box_decorations_count_
+               ? NGInlineBreakToken::kHasClonedBoxDecorations
+               : 0));
 }
 
-void NGLineBreaker::PropagateBreakToken(const NGBlockBreakToken* token) {
-  propagated_break_tokens_.push_back(token);
+void NGLineBreaker::PropagateBreakToken(
+    scoped_refptr<const NGBlockBreakToken> token) {
+  propagated_break_tokens_.push_back(std::move(token));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
index 5d98a49..20b58127 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
@@ -57,10 +57,10 @@
   bool IsFinished() const { return item_index_ >= Items().size(); }
 
   // Create an NGInlineBreakToken for the last line returned by NextLine().
-  const NGInlineBreakToken* CreateBreakToken(const NGLineInfo&) const;
+  scoped_refptr<NGInlineBreakToken> CreateBreakToken(const NGLineInfo&) const;
 
-  void PropagateBreakToken(const NGBlockBreakToken*);
-  HeapVector<Member<const NGBlockBreakToken>>& PropagatedBreakTokens() {
+  void PropagateBreakToken(scoped_refptr<const NGBlockBreakToken>);
+  Vector<scoped_refptr<const NGBlockBreakToken>>& PropagatedBreakTokens() {
     return propagated_break_tokens_;
   }
 
@@ -93,7 +93,7 @@
 
  private:
   const String& Text() const { return text_content_; }
-  const HeapVector<NGInlineItem>& Items() const { return items_data_.items; }
+  const Vector<NGInlineItem>& Items() const { return items_data_.items; }
 
   String TextContentForLineBreak() const;
 
@@ -283,8 +283,8 @@
 
   const NGConstraintSpace& constraint_space_;
   NGExclusionSpace* exclusion_space_;
-  const NGInlineBreakToken* break_token_;
-  const ComputedStyle* current_style_ = nullptr;
+  scoped_refptr<const NGInlineBreakToken> break_token_;
+  scoped_refptr<const ComputedStyle> current_style_;
 
   LazyLineBreakIterator break_iterator_;
   HarfBuzzShaper shaper_;
@@ -322,7 +322,7 @@
   // if 'unicode-bidi: plaintext'.
   TextDirection base_direction_;
 
-  HeapVector<Member<const NGBlockBreakToken>> propagated_break_tokens_;
+  Vector<scoped_refptr<const NGBlockBreakToken>> propagated_break_tokens_;
 
   // Fields for `box-decoration-break: clone`.
   unsigned cloned_box_decorations_count_ = 0;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
index 9fcc1c48..67d120d 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc
@@ -58,7 +58,7 @@
     builder.SetAvailableSize({available_width, kIndefiniteSize});
     NGConstraintSpace space = builder.ToConstraintSpace();
 
-    const NGInlineBreakToken* break_token = nullptr;
+    scoped_refptr<NGInlineBreakToken> break_token;
 
     Vector<std::pair<String, unsigned>> lines;
     trailing_whitespaces_.resize(0);
@@ -69,7 +69,7 @@
       NGLineInfo line_info;
       NGLineBreaker line_breaker(node, NGLineBreakerMode::kContent, space,
                                  line_opportunity, leading_floats, 0u,
-                                 break_token, &exclusion_space);
+                                 break_token.get(), &exclusion_space);
       line_breaker.NextLine(&line_info);
       if (callback)
         callback(line_breaker, line_info);
@@ -290,7 +290,7 @@
     </style>
     <div id=container><span>123 456</span> 789</div>
   )HTML");
-  const HeapVector<NGInlineItem>& items = node.ItemsData(false).items;
+  const Vector<NGInlineItem>& items = node.ItemsData(false).items;
 
   // While "123 456" can fit in a line, "456" has a right margin that cannot
   // fit. Since "456" and its right margin is not breakable, "456" should be on
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
index d0c1973..05b43d2 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc
@@ -403,7 +403,7 @@
 void NGLineTruncator::HideChild(NGLogicalLineItem* child) {
   DCHECK(child->HasInFlowFragment());
 
-  if (const NGLayoutResult* layout_result = child->layout_result) {
+  if (const NGLayoutResult* layout_result = child->layout_result.get()) {
     // Need to propagate OOF descendants in this inline-block child.
     const auto& fragment =
         To<NGPhysicalBoxFragment>(layout_result->PhysicalFragment());
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h
index dfccb80..024e2d3c 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h
@@ -85,7 +85,7 @@
                                  TextDirection direction);
   void HideChild(NGLogicalLineItem* child);
 
-  const ComputedStyle* line_style_;
+  scoped_refptr<const ComputedStyle> line_style_;
   LayoutUnit available_width_;
   TextDirection line_direction_;
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc
index efd5f8da..dcd82490e 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.cc
@@ -54,13 +54,6 @@
   return stream;
 }
 
-void NGLogicalLineItem::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_result);
-  visitor->Trace(layout_object);
-  visitor->Trace(out_of_flow_positioned_box);
-  visitor->Trace(unpositioned_float);
-}
-
 NGLogicalLineItem* NGLogicalLineItems::FirstInFlowChild() {
   for (auto& child : *this) {
     if (child.HasInFlowFragment())
@@ -113,8 +106,4 @@
     children_[index].rect.offset.block_offset += delta;
 }
 
-void NGLogicalLineItems::Trace(Visitor* visitor) const {
-  visitor->Trace(children_);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h
index c629525..e7b4f0f 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h
@@ -32,7 +32,7 @@
   // bidi level and affects bidi reordering.
   explicit NGLogicalLineItem(UBiDiLevel bidi_level) : bidi_level(bidi_level) {}
   // Create an in-flow |NGLayoutResult|.
-  NGLogicalLineItem(const NGLayoutResult* layout_result,
+  NGLogicalLineItem(scoped_refptr<const NGLayoutResult> layout_result,
                     const LogicalRect& rect,
                     unsigned children_count,
                     UBiDiLevel bidi_level)
@@ -40,7 +40,7 @@
         rect(rect),
         children_count(children_count),
         bidi_level(bidi_level) {}
-  NGLogicalLineItem(const NGLayoutResult* layout_result,
+  NGLogicalLineItem(scoped_refptr<const NGLayoutResult> layout_result,
                     LogicalOffset offset,
                     LayoutUnit inline_size,
                     unsigned children_count,
@@ -132,7 +132,7 @@
   NGLogicalLineItem(LayoutObject* unpositioned_float, UBiDiLevel bidi_level)
       : unpositioned_float(unpositioned_float), bidi_level(bidi_level) {}
   // Create a positioned float.
-  NGLogicalLineItem(const NGLayoutResult* layout_result,
+  NGLogicalLineItem(scoped_refptr<const NGLayoutResult> layout_result,
                     NGBfcOffset bfc_offset,
                     UBiDiLevel bidi_level)
       : layout_result(std::move(layout_result)),
@@ -199,9 +199,7 @@
                           : TextDirection::kLtr;
   }
 
-  void Trace(Visitor*) const;
-
-  Member<const NGLayoutResult> layout_result;
+  scoped_refptr<const NGLayoutResult> layout_result;
 
   // Data to create a text fragment from.
   // |inline_item| is null only for ellipsis items.
@@ -214,13 +212,12 @@
 
   // Ellipsis does not have |NGInlineItem|, but built from |LayoutObject| and
   // |NGStyleVariant|.
-  Member<const LayoutObject> layout_object = nullptr;
+  const LayoutObject* layout_object = nullptr;
   // Used only when |layout_object_| is not null.
   NGStyleVariant style_variant = NGStyleVariant::kStandard;
 
-  Member<LayoutObject> out_of_flow_positioned_box;
-  Member<LayoutObject> unpositioned_float;
-
+  LayoutObject* out_of_flow_positioned_box = nullptr;
+  LayoutObject* unpositioned_float = nullptr;
   // The offset of the border box, initially in this child coordinate system.
   // |ComputeInlinePositions()| converts it to the offset within the line box.
   LogicalRect rect;
@@ -253,8 +250,7 @@
 // A vector of Child.
 // Unlike the fragment builder, chlidren are mutable.
 // Callers can add to the fragment builder in a batch once finalized.
-class CORE_EXPORT NGLogicalLineItems final
-    : public GarbageCollected<NGLogicalLineItems> {
+class NGLogicalLineItems {
  public:
   NGLogicalLineItems() = default;
   void operator=(NGLogicalLineItems&& other) {
@@ -300,7 +296,7 @@
     children_.insert(index, item);
   }
   void InsertChild(unsigned index,
-                   const NGLayoutResult* layout_result,
+                   scoped_refptr<const NGLayoutResult> layout_result,
                    const LogicalRect& rect,
                    unsigned children_count) {
     WillInsertChild(index);
@@ -314,12 +310,10 @@
   void MoveInBlockDirection(LayoutUnit);
   void MoveInBlockDirection(LayoutUnit, unsigned start, unsigned end);
 
-  void Trace(Visitor*) const;
-
  private:
   void WillInsertChild(unsigned index);
 
-  HeapVector<NGLogicalLineItem, 16> children_;
+  Vector<NGLogicalLineItem, 16> children_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
index 14ba80a..1d7022f 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
@@ -124,8 +124,7 @@
 }
 
 const Node* NGOffsetMappingUnit::AssociatedNode() const {
-  if (const auto* text_fragment =
-          DynamicTo<LayoutTextFragment>(layout_object_.Get()))
+  if (const auto* text_fragment = DynamicTo<LayoutTextFragment>(layout_object_))
     return text_fragment->AssociatedTextNode();
   return layout_object_->GetNode();
 }
@@ -147,7 +146,7 @@
     return false;
   // Don't merge first letter and remaining text
   if (const auto* text_fragment =
-          DynamicTo<LayoutTextFragment>(layout_object_.Get())) {
+          DynamicTo<LayoutTextFragment>(layout_object_)) {
     // TODO(layout-dev): Fix offset calculation for text-transform
     if (text_fragment->IsRemainingTextLayoutObject() &&
         other.dom_start_ == text_fragment->TextStartOffset())
@@ -589,8 +588,4 @@
   return true;
 }
 
-void NGOffsetMappingUnit::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_object_);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
index bf26b5f..67351ca 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h
@@ -73,12 +73,10 @@
 
   void AssertValid() const;
 
-  void Trace(Visitor*) const;
-
  private:
   NGOffsetMappingUnitType type_ = NGOffsetMappingUnitType::kIdentity;
 
-  Member<const LayoutObject> layout_object_;
+  const LayoutObject* layout_object_;
   // TODO(yosin): We should rename |dom_start_| and |dom_end_| to appropriate
   // names since |layout_object_| is for generated text, these offsets are
   // offset in |LayoutText::text_| instead of DOM node.
@@ -98,12 +96,13 @@
 // object that stores the mapping information between DOM positions and offsets
 // in the text content string of the context.
 // See design doc https://goo.gl/CJbxky for details.
-class CORE_EXPORT NGOffsetMapping final
-    : public GarbageCollected<NGOffsetMapping> {
+class CORE_EXPORT NGOffsetMapping {
+  USING_FAST_MALLOC(NGOffsetMapping);
+
  public:
-  using UnitVector = HeapVector<NGOffsetMappingUnit>;
+  using UnitVector = Vector<NGOffsetMappingUnit>;
   using RangeMap =
-      HeapHashMap<Member<const Node>, std::pair<unsigned, unsigned>>;
+      HashMap<Persistent<const Node>, std::pair<unsigned, unsigned>>;
 
   NGOffsetMapping(UnitVector&&, RangeMap&&, String);
   NGOffsetMapping(const NGOffsetMapping&) = delete;
@@ -231,11 +230,6 @@
   // control characters. Returns true otherwise.
   bool HasBidiControlCharactersOnly(unsigned start, unsigned end) const;
 
-  void Trace(Visitor* visitor) const {
-    visitor->Trace(units_);
-    visitor->Trace(ranges_);
-  }
-
  private:
   // The NGOffsetMappingUnits of the inline formatting context in osrted order.
   UnitVector units_;
@@ -252,6 +246,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::NGOffsetMappingUnit)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_OFFSET_MAPPING_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc
index ec2dcc89..5482cc88 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.cc
@@ -139,7 +139,7 @@
   unsigned text_content_offset = container_unit->TextContentStart();
   unsigned offset_to_collapse = space_offset - text_content_offset;
 
-  HeapVector<NGOffsetMappingUnit, 3> new_units;
+  Vector<NGOffsetMappingUnit, 3> new_units;
   if (offset_to_collapse) {
     new_units.emplace_back(NGOffsetMappingUnitType::kIdentity, layout_object,
                            dom_offset, dom_offset + offset_to_collapse,
@@ -216,7 +216,7 @@
   destination_string_ = string;
 }
 
-NGOffsetMapping* NGOffsetMappingBuilder::Build() {
+std::unique_ptr<NGOffsetMapping> NGOffsetMappingBuilder::Build() {
   // All mapping units are already built. Scan them to build mapping ranges.
   for (unsigned range_start = 0; range_start < mapping_units_.size();) {
     const LayoutObject& layout_object =
@@ -239,7 +239,7 @@
     range_start = range_end;
   }
 
-  return MakeGarbageCollected<NGOffsetMapping>(
+  return std::make_unique<NGOffsetMapping>(
       std::move(mapping_units_), std::move(unit_ranges_), destination_string_);
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h
index 97a36e65..dd7d5814 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_builder.h
@@ -119,7 +119,7 @@
 
   // Finalize and return the offset mapping.
   // This method can only be called once, as it can invalidate the stored data.
-  NGOffsetMapping* Build();
+  std::unique_ptr<NGOffsetMapping> Build();
 
  private:
   const LayoutObject* current_layout_object_ = nullptr;
@@ -133,7 +133,7 @@
   unsigned destination_length_ = 0;
 
   // Mapping units of the current mapping function.
-  HeapVector<NGOffsetMappingUnit> mapping_units_;
+  Vector<NGOffsetMappingUnit> mapping_units_;
 
   // Unit ranges of the current mapping function.
   NGOffsetMapping::RangeMap unit_ranges_;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
index af931bb..1785a2a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
@@ -23,9 +23,9 @@
 #define SEGMENT_BREAK_TRANSFORMATION_FOR_EAST_ASIAN_WIDTH 0
 
 // Helper functions to use |EXPECT_EQ()| for |NGOffsetMappingUnit| and its span.
-HeapVector<NGOffsetMappingUnit> ToVector(
+Vector<NGOffsetMappingUnit> ToVector(
     const base::span<const NGOffsetMappingUnit>& range) {
-  HeapVector<NGOffsetMappingUnit> units;
+  Vector<NGOffsetMappingUnit> units;
   for (const auto& unit : range)
     units.push_back(unit);
   return units;
@@ -54,8 +54,8 @@
            << unit.TextContentEnd() << "}";
 }
 
-bool operator==(const HeapVector<NGOffsetMappingUnit>& units1,
-                const HeapVector<NGOffsetMappingUnit>& units2) {
+bool operator==(const Vector<NGOffsetMappingUnit>& units1,
+                const Vector<NGOffsetMappingUnit>& units2) {
   if (units1.size() != units2.size())
     return false;
   auto* it2 = units2.begin();
@@ -67,13 +67,12 @@
   return true;
 }
 
-bool operator==(const HeapVector<NGOffsetMappingUnit>& units,
+bool operator==(const Vector<NGOffsetMappingUnit>& units,
                 const base::span<const NGOffsetMappingUnit>& range) {
   return units == ToVector(range);
 }
 
-void PrintTo(const HeapVector<NGOffsetMappingUnit>& units,
-             std::ostream* ostream) {
+void PrintTo(const Vector<NGOffsetMappingUnit>& units, std::ostream* ostream) {
   *ostream << "[";
   const char* comma = "";
   for (const auto& unit : units) {
@@ -140,14 +139,13 @@
     return result.ToString();
   }
 
-  HeapVector<NGOffsetMappingUnit> GetFirstLast(const std::string& caret_text) {
+  Vector<NGOffsetMappingUnit> GetFirstLast(const std::string& caret_text) {
     const auto offset = caret_text.find('|');
     return {*GetOffsetMapping().GetFirstMappingUnit(offset),
             *GetOffsetMapping().GetLastMappingUnit(offset)};
   }
 
-  HeapVector<NGOffsetMappingUnit> GetUnits(wtf_size_t index1,
-                                           wtf_size_t index2) {
+  Vector<NGOffsetMappingUnit> GetUnits(wtf_size_t index1, wtf_size_t index2) {
     const auto& units = GetOffsetMapping().GetUnits();
     return {units[index1], units[index2]};
   }
@@ -189,7 +187,7 @@
   }
 
   bool IsOffsetMappingStored() const {
-    return layout_block_flow_->GetNGInlineNodeData()->offset_mapping;
+    return layout_block_flow_->GetNGInlineNodeData()->offset_mapping.get();
   }
 
   const LayoutText* GetLayoutTextUnder(const char* parent_id) {
@@ -231,8 +229,8 @@
     return GetOffsetMapping().GetLastPosition(offset);
   }
 
-  Persistent<LayoutBlockFlow> layout_block_flow_;
-  Persistent<LayoutObject> layout_object_;
+  LayoutBlockFlow* layout_block_flow_ = nullptr;
+  LayoutObject* layout_object_ = nullptr;
   FontCachePurgePreventer purge_preventer_;
 };
 
@@ -517,7 +515,7 @@
 
 TEST_F(NGOffsetMappingTest, TwoTextNodes) {
   SetupHtml("t", "<div id=t>foo<span id=s>bar</span></div>");
-  const auto* foo = To<LayoutText>(layout_object_.Get());
+  const auto* foo = To<LayoutText>(layout_object_);
   const auto* bar = GetLayoutTextUnder("s");
   const Node* foo_node = foo->GetNode();
   const Node* bar_node = bar->GetNode();
@@ -583,7 +581,7 @@
 
 TEST_F(NGOffsetMappingTest, BRBetweenTextNodes) {
   SetupHtml("t", u"<div id=t>foo<br>bar</div>");
-  const auto* foo = To<LayoutText>(layout_object_.Get());
+  const auto* foo = To<LayoutText>(layout_object_);
   const auto* br = To<LayoutText>(foo->NextSibling());
   const auto* bar = To<LayoutText>(br->NextSibling());
   const Node* foo_node = foo->GetNode();
@@ -773,7 +771,7 @@
 
 TEST_F(NGOffsetMappingTest, ReplacedElement) {
   SetupHtml("t", "<div id=t>foo <img> bar</div>");
-  const auto* foo = To<LayoutText>(layout_object_.Get());
+  const auto* foo = To<LayoutText>(layout_object_);
   const LayoutObject* img = foo->NextSibling();
   const auto* bar = To<LayoutText>(img->NextSibling());
   const Node* foo_node = foo->GetNode();
@@ -1012,7 +1010,7 @@
                                    ->SlowFirstChild();
   const NGOffsetMapping& result = GetOffsetMapping();
 
-  EXPECT_EQ((HeapVector<NGOffsetMappingUnit>{
+  EXPECT_EQ((Vector<NGOffsetMappingUnit>{
                 NGOffsetMappingUnit(kIdentity, before, 0u, 3u, 0u, 3u),
                 NGOffsetMappingUnit(kIdentity, *text->GetLayoutObject(), 0u, 3u,
                                     3u, 6u),
@@ -1020,10 +1018,10 @@
             result.GetUnits());
 
   // Verify |GetMappingUnitsForLayoutObject()| for ::before and ::after
-  EXPECT_EQ((HeapVector<NGOffsetMappingUnit>{
+  EXPECT_EQ((Vector<NGOffsetMappingUnit>{
                 NGOffsetMappingUnit(kIdentity, before, 0u, 3u, 0u, 3u)}),
             result.GetMappingUnitsForLayoutObject(before));
-  EXPECT_EQ((HeapVector<NGOffsetMappingUnit>{
+  EXPECT_EQ((Vector<NGOffsetMappingUnit>{
                 NGOffsetMappingUnit(kIdentity, after, 0u, 3u, 6u, 9u)}),
             result.GetMappingUnitsForLayoutObject(after));
 }
@@ -1046,7 +1044,7 @@
       To<LayoutText>(*target.firstChild()->GetLayoutObject());
 
   EXPECT_EQ(
-      (HeapVector<NGOffsetMappingUnit>{
+      (Vector<NGOffsetMappingUnit>{
           NGOffsetMappingUnit(kCollapsed, first_letter_part, 0u, 2u, 0u, 0u),
           NGOffsetMappingUnit(kIdentity, first_letter_part, 2u, 3u, 0u, 1u),
           NGOffsetMappingUnit(kIdentity, remaining_part, 0u, 1u, 1u, 2u),
@@ -1057,12 +1055,12 @@
 
   // Verify |GetMappingUnitsForLayoutObject()| for ::first-letter
   EXPECT_EQ(
-      (HeapVector<NGOffsetMappingUnit>{
+      (Vector<NGOffsetMappingUnit>{
           NGOffsetMappingUnit(kCollapsed, first_letter_part, 0u, 2u, 0u, 0u),
           NGOffsetMappingUnit(kIdentity, first_letter_part, 2u, 3u, 0u, 1u)}),
       result.GetMappingUnitsForLayoutObject(first_letter_part));
   EXPECT_EQ(
-      (HeapVector<NGOffsetMappingUnit>{
+      (Vector<NGOffsetMappingUnit>{
           NGOffsetMappingUnit(kIdentity, remaining_part, 0u, 1u, 1u, 2u),
           NGOffsetMappingUnit(kCollapsed, remaining_part, 1u, 3u, 2u, 2u),
           NGOffsetMappingUnit(kIdentity, remaining_part, 3u, 5u, 2u, 4u)}),
@@ -1159,7 +1157,7 @@
 
   EXPECT_EQ("ab\ncd", result.GetText());
 
-  EXPECT_EQ((HeapVector<NGOffsetMappingUnit>{
+  EXPECT_EQ((Vector<NGOffsetMappingUnit>{
                 NGOffsetMappingUnit(kIdentity, text_ab_n_cd, 0u, 2u, 0u, 2u),
                 NGOffsetMappingUnit(kCollapsed, text_ab_n_cd, 2u, 3u, 2u, 2u),
                 NGOffsetMappingUnit(kIdentity, text_ab_n_cd, 3u, 4u, 2u, 3u),
@@ -1281,7 +1279,7 @@
   const NGOffsetMapping& mapping = GetOffsetMapping();
   EXPECT_EQ(String(u" \u200Bxyz"), mapping.GetText())
       << "We have ZWS after leading preserved space.";
-  EXPECT_EQ((HeapVector<NGOffsetMappingUnit>{
+  EXPECT_EQ((Vector<NGOffsetMappingUnit>{
                 NGOffsetMappingUnit(kIdentity, *text.GetLayoutObject(), 0u, 1u,
                                     0u, 1u),
                 NGOffsetMappingUnit(kIdentity, *text.GetLayoutObject(), 1u, 4u,
@@ -1308,7 +1306,7 @@
   const LayoutObject& newline = *layout_object_b.NextSibling();
   const LayoutObject& layout_object_i = *newline.NextSibling();
   EXPECT_EQ(
-      (HeapVector<NGOffsetMappingUnit>{
+      (Vector<NGOffsetMappingUnit>{
           NGOffsetMappingUnit(kIdentity, *layout_object_a.SlowFirstChild(), 0u,
                               1u, 0u, 1u),
           NGOffsetMappingUnit(kCollapsed, *layout_object_b.SlowFirstChild(), 0u,
@@ -1338,7 +1336,7 @@
   const LayoutObject& newline = *layout_object_b.NextSibling();
   const LayoutObject& layout_object_i = *newline.NextSibling();
   EXPECT_EQ(
-      (HeapVector<NGOffsetMappingUnit>{
+      (Vector<NGOffsetMappingUnit>{
           NGOffsetMappingUnit(kIdentity, *layout_object_a.SlowFirstChild(), 0u,
                               1u, 0u, 1u),
           NGOffsetMappingUnit(kIdentity, *layout_object_b.SlowFirstChild(), 0u,
@@ -1361,7 +1359,7 @@
   const LayoutObject& newline = *layout_object_b.NextSibling();
   const LayoutObject& layout_object_i = *newline.NextSibling();
   EXPECT_EQ(
-      (HeapVector<NGOffsetMappingUnit>{
+      (Vector<NGOffsetMappingUnit>{
           NGOffsetMappingUnit(kIdentity, *layout_object_a.SlowFirstChild(), 0u,
                               1u, 0u, 1u),
           // We take the first space character.
@@ -1394,7 +1392,7 @@
   const LayoutObject& newline = *layout_object_b.NextSibling();
   const LayoutObject& layout_object_i = *newline.NextSibling();
   EXPECT_EQ(
-      (HeapVector<NGOffsetMappingUnit>{
+      (Vector<NGOffsetMappingUnit>{
           NGOffsetMappingUnit(kIdentity, *layout_object_a.SlowFirstChild(), 0u,
                               1u, 0u, 1u),
           NGOffsetMappingUnit(kCollapsed, *layout_object_b.SlowFirstChild(), 0u,
@@ -1424,7 +1422,7 @@
   const LayoutObject& newline = *layout_object_b.NextSibling();
   const LayoutObject& layout_object_i = *newline.NextSibling();
   EXPECT_EQ(
-      (HeapVector<NGOffsetMappingUnit>{
+      (Vector<NGOffsetMappingUnit>{
           NGOffsetMappingUnit(kIdentity, *layout_object_a.SlowFirstChild(), 0u,
                               1u, 0u, 1u),
           NGOffsetMappingUnit(kIdentity, *layout_object_b.SlowFirstChild(), 0u,
@@ -1498,13 +1496,13 @@
   const LayoutObject& text_b = *wbr.NextSibling();
   const NGOffsetMapping& result = GetOffsetMapping();
 
-  EXPECT_EQ((HeapVector<NGOffsetMappingUnit>{
+  EXPECT_EQ((Vector<NGOffsetMappingUnit>{
                 NGOffsetMappingUnit(kIdentity, text_a, 0u, 1u, 0u, 1u),
                 NGOffsetMappingUnit(kIdentity, wbr, 0u, 1u, 1u, 2u),
                 NGOffsetMappingUnit(kIdentity, text_b, 0u, 1u, 2u, 3u)}),
             result.GetUnits());
 
-  EXPECT_EQ((HeapVector<NGOffsetMappingUnit>{
+  EXPECT_EQ((Vector<NGOffsetMappingUnit>{
                 NGOffsetMappingUnit(kIdentity, wbr, 0u, 1u, 1u, 2u)}),
             result.GetMappingUnitsForLayoutObject(wbr));
 }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc
index c5f99bd..117ea03 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc
@@ -26,10 +26,10 @@
 
 }  // namespace
 
-const NGPhysicalLineBoxFragment* NGPhysicalLineBoxFragment::Create(
-    NGLineBoxFragmentBuilder* builder) {
+scoped_refptr<const NGPhysicalLineBoxFragment>
+NGPhysicalLineBoxFragment::Create(NGLineBoxFragmentBuilder* builder) {
   DCHECK_EQ(builder->children_.size(), 0u);
-  return MakeGarbageCollected<NGPhysicalLineBoxFragment>(PassKey(), builder);
+  return base::MakeRefCounted<NGPhysicalLineBoxFragment>(PassKey(), builder);
 }
 
 NGPhysicalLineBoxFragment::NGPhysicalLineBoxFragment(
@@ -118,9 +118,4 @@
   const auto* break_token = To<NGInlineBreakToken>(BreakToken());
   return break_token && !break_token->IsForcedBreak();
 }
-
-void NGPhysicalLineBoxFragment::TraceAfterDispatch(Visitor* visitor) const {
-  NGPhysicalFragment::TraceAfterDispatch(visitor);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h
index 052ce22..d213b8e 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h
@@ -27,14 +27,16 @@
     kEmptyLineBox
   };
 
-  static const NGPhysicalLineBoxFragment* Create(
+  static scoped_refptr<const NGPhysicalLineBoxFragment> Create(
       NGLineBoxFragmentBuilder* builder);
 
   using PassKey = base::PassKey<NGPhysicalLineBoxFragment>;
   NGPhysicalLineBoxFragment(PassKey, NGLineBoxFragmentBuilder* builder);
-  ~NGPhysicalLineBoxFragment() = default;
 
-  void TraceAfterDispatch(Visitor*) const;
+  ~NGPhysicalLineBoxFragment() {
+    for (const NGLink& child : Children())
+      child.fragment->Release();
+  }
 
   NGLineBoxType LineBoxType() const {
     return static_cast<NGLineBoxType>(sub_type_);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc
index dd8a9a5..667f5788 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc
@@ -15,21 +15,21 @@
   NGPhysicalLineBoxFragmentTest() : NGLayoutTest() {}
 
  protected:
-  HeapVector<Member<const NGPhysicalLineBoxFragment>> GetLineBoxes() const {
+  Vector<const NGPhysicalLineBoxFragment*> GetLineBoxes() const {
     const Element* container = GetElementById("root");
     DCHECK(container);
     const LayoutObject* layout_object = container->GetLayoutObject();
     DCHECK(layout_object) << container;
     DCHECK(layout_object->IsLayoutBlockFlow()) << container;
     NGInlineCursor cursor(*To<LayoutBlockFlow>(layout_object));
-    HeapVector<Member<const NGPhysicalLineBoxFragment>> lines;
+    Vector<const NGPhysicalLineBoxFragment*> lines;
     for (cursor.MoveToFirstLine(); cursor; cursor.MoveToNextLine())
       lines.push_back(cursor.Current()->LineBoxFragment());
     return lines;
   }
 
   const NGPhysicalLineBoxFragment* GetLineBox() const {
-    HeapVector<Member<const NGPhysicalLineBoxFragment>> lines = GetLineBoxes();
+    Vector<const NGPhysicalLineBoxFragment*> lines = GetLineBoxes();
     if (!lines.IsEmpty())
       return lines.front();
     return nullptr;
@@ -56,7 +56,7 @@
     </style>
     <div id=root>12345678 12345<div class=float>float</div></div>
   )HTML");
-  HeapVector<Member<const NGPhysicalLineBoxFragment>> lines = GetLineBoxes();
+  Vector<const NGPhysicalLineBoxFragment*> lines = GetLineBoxes();
   EXPECT_EQ(lines.size(), 2u);
   EXPECT_FALSE(lines[0]->HasPropagatedDescendants());
   EXPECT_TRUE(lines[1]->HasPropagatedDescendants());
@@ -74,7 +74,7 @@
     </style>
     <div id=root>12345678 12345<div class=abspos>abspos</div></div>
   )HTML");
-  HeapVector<Member<const NGPhysicalLineBoxFragment>> lines = GetLineBoxes();
+  Vector<const NGPhysicalLineBoxFragment*> lines = GetLineBoxes();
   EXPECT_EQ(lines.size(), 2u);
   EXPECT_FALSE(lines[0]->HasPropagatedDescendants());
   EXPECT_TRUE(lines[1]->HasPropagatedDescendants());
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc
index eb8ba3f..41e0187 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_ruby_utils.cc
@@ -274,7 +274,7 @@
         }
 
         // Check if we really have an annotation.
-        if (const auto& layout_result = item.layout_result) {
+        if (const auto* layout_result = item.layout_result.get()) {
           LayoutUnit overflow = layout_result->AnnotationOverflow();
           if (IsFlippedLinesWritingMode(line_style.GetWritingMode()))
             overflow = -overflow;
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc
index e93ece6..ac97610e 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc
@@ -53,23 +53,23 @@
 
 template <typename Base>
 NGInlineNodeData* LayoutNGBlockFlowMixin<Base>::TakeNGInlineNodeData() {
-  return ng_inline_node_data_.Release();
+  return ng_inline_node_data_.release();
 }
 
 template <typename Base>
 NGInlineNodeData* LayoutNGBlockFlowMixin<Base>::GetNGInlineNodeData() const {
   DCHECK(ng_inline_node_data_);
-  return ng_inline_node_data_;
+  return ng_inline_node_data_.get();
 }
 
 template <typename Base>
 void LayoutNGBlockFlowMixin<Base>::ResetNGInlineNodeData() {
-  ng_inline_node_data_ = MakeGarbageCollected<NGInlineNodeData>();
+  ng_inline_node_data_ = std::make_unique<NGInlineNodeData>();
 }
 
 template <typename Base>
 void LayoutNGBlockFlowMixin<Base>::ClearNGInlineNodeData() {
-  ng_inline_node_data_ = nullptr;
+  ng_inline_node_data_.reset();
 }
 
 template <typename Base>
@@ -260,12 +260,6 @@
   LayoutNGMixin<Base>::UpdateMargins();
 }
 
-template <typename Base>
-void LayoutNGBlockFlowMixin<Base>::Trace(Visitor* visitor) const {
-  visitor->Trace(ng_inline_node_data_);
-  LayoutNGMixin<Base>::Trace(visitor);
-}
-
 template class CORE_TEMPLATE_EXPORT LayoutNGBlockFlowMixin<LayoutBlockFlow>;
 template class CORE_TEMPLATE_EXPORT LayoutNGBlockFlowMixin<LayoutProgress>;
 template class CORE_TEMPLATE_EXPORT LayoutNGBlockFlowMixin<LayoutRubyAsBlock>;
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h
index 7e14324..b06834a9 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h
@@ -35,7 +35,7 @@
   NGInlineNodeData* GetNGInlineNodeData() const final;
   void ResetNGInlineNodeData() final;
   void ClearNGInlineNodeData() final;
-  bool HasNGInlineNodeData() const final { return ng_inline_node_data_; }
+  bool HasNGInlineNodeData() const final { return ng_inline_node_data_.get(); }
 
   LayoutUnit FirstLineBoxBaseline() const final;
   LayoutUnit InlineBlockBaseline(LineDirectionMode) const final;
@@ -47,8 +47,6 @@
 
   PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
 
-  void Trace(Visitor*) const override;
-
   using LayoutNGMixin<Base>::CurrentFragment;
 
  protected:
@@ -67,7 +65,7 @@
   // behavior as LayoutNGBlockFlow.
   void UpdateNGBlockLayout();
 
-  Member<NGInlineNodeData> ng_inline_node_data_;
+  std::unique_ptr<NGInlineNodeData> ng_inline_node_data_;
 
   friend class NGBaseLayoutAlgorithmTest;
 
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_button.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_button.cc
index 36ccf49f..2ebb84c 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_button.cc
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_button.cc
@@ -13,11 +13,6 @@
 
 LayoutNGButton::~LayoutNGButton() = default;
 
-void LayoutNGButton::Trace(Visitor* visitor) const {
-  visitor->Trace(inner_);
-  LayoutNGFlexibleBox::Trace(visitor);
-}
-
 void LayoutNGButton::AddChild(LayoutObject* new_child,
                               LayoutObject* before_child) {
   if (!inner_) {
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_button.h b/third_party/blink/renderer/core/layout/ng/layout_ng_button.h
index a853861..bc322125 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_button.h
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_button.h
@@ -13,7 +13,6 @@
  public:
   explicit LayoutNGButton(Element*);
   ~LayoutNGButton() override;
-  void Trace(Visitor*) const override;
 
   const char* GetName() const override { return "LayoutNGButton"; }
   void AddChild(LayoutObject* new_child,
@@ -30,7 +29,7 @@
     return type == kLayoutObjectNGButton || LayoutNGFlexibleBox::IsOfType(type);
   }
 
-  Member<LayoutBlock> inner_;
+  LayoutBlock* inner_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
index f175d53..958be5f 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
@@ -281,7 +281,7 @@
   // copying back position information.
   NGBlockNode container_node(container);
   NGBoxFragmentBuilder container_builder(
-      container_node, container_style,
+      container_node, scoped_refptr<const ComputedStyle>(container_style),
       /* space */ nullptr, container_style->GetWritingDirection());
   container_builder.SetIsNewFormattingContext(
       container_node.CreatesNewFormattingContext());
@@ -351,7 +351,8 @@
                         *container_style, constraint_space, &container_builder,
                         initial_containing_block_fixed_size)
       .Run(/* only_layout */ this);
-  const NGLayoutResult* result = container_builder.ToBoxFragment();
+  scoped_refptr<const NGLayoutResult> result =
+      container_builder.ToBoxFragment();
   // These are the unpositioned OOF descendants of the current OOF block.
   for (const auto& descendant :
        result->PhysicalFragment().OutOfFlowPositionedDescendants())
@@ -382,8 +383,10 @@
 }
 
 template <typename Base>
-const NGLayoutResult* LayoutNGMixin<Base>::UpdateInFlowBlockLayout() {
-  const NGLayoutResult* previous_result = Base::GetCachedLayoutResult();
+scoped_refptr<const NGLayoutResult>
+LayoutNGMixin<Base>::UpdateInFlowBlockLayout() {
+  scoped_refptr<const NGLayoutResult> previous_result =
+      Base::GetCachedLayoutResult();
   bool is_layout_root = !Base::View()->GetLayoutState()->Next();
 
   // If we are a layout root, use the previous space if available. This will
@@ -393,7 +396,8 @@
           ? previous_result->GetConstraintSpaceForCaching()
           : NGConstraintSpace::CreateFromLayoutObject(*this);
 
-  const NGLayoutResult* result = NGBlockNode(this).Layout(constraint_space);
+  scoped_refptr<const NGLayoutResult> result =
+      NGBlockNode(this).Layout(constraint_space);
 
   const auto& physical_fragment =
       To<NGPhysicalBoxFragment>(result->PhysicalFragment());
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h
index 5af4f42..3d25be3 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h
@@ -49,7 +49,7 @@
   NGConstraintSpace ConstraintSpaceForMinMaxSizes() const;
 
   void UpdateOutOfFlowBlockLayout();
-  const NGLayoutResult* UpdateInFlowBlockLayout();
+  scoped_refptr<const NGLayoutResult> UpdateInFlowBlockLayout();
   void UpdateMargins();
 };
 
diff --git a/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc b/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc
index 0531b3a..d516194 100644
--- a/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc
+++ b/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc
@@ -37,7 +37,7 @@
   return margins.first;
 }
 
-const NGLayoutResult* NGUnpositionedListMarker::Layout(
+scoped_refptr<const NGLayoutResult> NGUnpositionedListMarker::Layout(
     const NGConstraintSpace& parent_space,
     const ComputedStyle& parent_style,
     FontBaseline baseline_type) const {
@@ -46,9 +46,10 @@
 
   // We need the first-line baseline from the list-marker, instead of the
   // typical atomic-inline baseline.
-  const NGLayoutResult* marker_layout_result = marker_node.LayoutAtomicInline(
-      parent_space, parent_style, parent_space.UseFirstLineStyle(),
-      NGBaselineAlgorithmType::kFirstLine);
+  scoped_refptr<const NGLayoutResult> marker_layout_result =
+      marker_node.LayoutAtomicInline(parent_space, parent_style,
+                                     parent_space.UseFirstLineStyle(),
+                                     NGBaselineAlgorithmType::kFirstLine);
   DCHECK(marker_layout_result);
   return marker_layout_result;
 }
diff --git a/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h b/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h
index 1673c6d..5bbc083 100644
--- a/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h
+++ b/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h
@@ -10,7 +10,6 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h"
 #include "third_party/blink/renderer/platform/fonts/font_baseline.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 namespace blink {
@@ -89,23 +88,22 @@
     return marker_layout_object_ == other.marker_layout_object_;
   }
 
-  const NGLayoutResult* Layout(const NGConstraintSpace& parent_space,
-                               const ComputedStyle& parent_style,
-                               FontBaseline) const;
+  scoped_refptr<const NGLayoutResult> Layout(
+      const NGConstraintSpace& parent_space,
+      const ComputedStyle& parent_style,
+      FontBaseline) const;
 
 #if DCHECK_IS_ON()
   void CheckMargin() const;
 #endif
 
-  void Trace(Visitor* visitor) const { visitor->Trace(marker_layout_object_); }
-
  private:
   LayoutUnit ComputeIntrudedFloatOffset(const NGConstraintSpace&,
                                         const NGBoxFragmentBuilder*,
                                         const NGBoxStrut&,
                                         LayoutUnit) const;
 
-  Member<LayoutNGOutsideListMarker> marker_layout_object_;
+  LayoutNGOutsideListMarker* marker_layout_object_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block_with_anonymous_mrow.cc b/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block_with_anonymous_mrow.cc
index 073c0f31..abd787e5 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block_with_anonymous_mrow.cc
+++ b/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block_with_anonymous_mrow.cc
@@ -17,12 +17,12 @@
     LayoutObject* before_child) {
   LayoutBlock* anonymous_mrow = To<LayoutBlock>(FirstChild());
   if (!anonymous_mrow) {
-    ComputedStyle* new_style =
+    scoped_refptr<ComputedStyle> new_style =
         GetDocument().GetStyleResolver().CreateAnonymousStyleWithDisplay(
             StyleRef(), EDisplay::kBlockMath);
 
     UpdateAnonymousChildStyle(nullptr, *new_style);
-    anonymous_mrow = MakeGarbageCollected<LayoutNGMathMLBlock>(nullptr);
+    anonymous_mrow = new LayoutNGMathMLBlock(nullptr);
     anonymous_mrow->SetDocumentForAnonymous(&GetDocument());
     anonymous_mrow->SetStyle(std::move(new_style));
     LayoutBox::AddChild(anonymous_mrow);
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc
index 5225fec..a9cc781 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc
@@ -151,7 +151,7 @@
   DCHECK(*denominator);
 }
 
-const NGLayoutResult* NGMathFractionLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGMathFractionLayoutAlgorithm::Layout() {
   DCHECK(!BreakToken());
 
   NGBlockNode numerator = nullptr;
@@ -160,13 +160,13 @@
 
   auto numerator_space = CreateConstraintSpaceForMathChild(
       Node(), ChildAvailableSize(), ConstraintSpace(), numerator);
-  const NGLayoutResult* numerator_layout_result =
+  scoped_refptr<const NGLayoutResult> numerator_layout_result =
       numerator.Layout(numerator_space);
   auto numerator_margins =
       ComputeMarginsFor(numerator_space, numerator.Style(), ConstraintSpace());
   auto denominator_space = CreateConstraintSpaceForMathChild(
       Node(), ChildAvailableSize(), ConstraintSpace(), denominator);
-  const NGLayoutResult* denominator_layout_result =
+  scoped_refptr<const NGLayoutResult> denominator_layout_result =
       denominator.Layout(denominator_space);
   auto denominator_margins = ComputeMarginsFor(
       denominator_space, denominator.Style(), ConstraintSpace());
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h
index 655714a..ff9f8cd 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h
@@ -17,7 +17,7 @@
   explicit NGMathFractionLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
  private:
-  const NGLayoutResult* Layout() final;
+  scoped_refptr<const NGLayoutResult> Layout() final;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const final;
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.cc
index fe7183f..d159182 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.cc
@@ -32,7 +32,7 @@
       Node().IsInlineFormattingContextRoot());
 }
 
-const NGLayoutResult* NGMathOperatorLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGMathOperatorLayoutAlgorithm::Layout() {
   // This algorithm can only be used for operators with a single text node,
   // which itself must contain only one glyph. We ensure that the subtree is
   // properly laid out but the glyph will actually be used to determine a
@@ -49,7 +49,7 @@
       To<NGInlineNode>(child), container_builder_.GetWritingDirection());
   container_builder_.SetItemsBuilder(&items_builder);
   context.SetItemsBuilder(&items_builder);
-  const NGLayoutResult* child_layout_result =
+  scoped_refptr<const NGLayoutResult> child_layout_result =
       To<NGInlineNode>(child).Layout(ConstraintSpace(), nullptr, &context);
   container_builder_.AddResult(*child_layout_result, {});
 
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.h
index 59fc6b0c..372696e6 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_operator_layout_algorithm.h
@@ -20,7 +20,7 @@
   explicit NGMathOperatorLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
  private:
-  const NGLayoutResult* Layout() final;
+  scoped_refptr<const NGLayoutResult> Layout() final;
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const final;
   UChar32 GetBaseCodePoint() const;
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_padded_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_padded_layout_algorithm.cc
index aa23ebe..3d3383c 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_padded_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_padded_layout_algorithm.cc
@@ -65,18 +65,18 @@
   }
 }
 
-const NGLayoutResult* NGMathPaddedLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGMathPaddedLayoutAlgorithm::Layout() {
   DCHECK(!BreakToken());
 
   NGBlockNode content = nullptr;
   GatherChildren(&content, &container_builder_);
   LayoutUnit content_ascent, content_descent;
   NGBoxStrut content_margins;
-  const NGPhysicalBoxFragment* content_fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> content_fragment;
   if (content) {
     NGConstraintSpace constraint_space = CreateConstraintSpaceForMathChild(
         Node(), ChildAvailableSize(), ConstraintSpace(), content);
-    const NGLayoutResult* content_layout_result =
+    scoped_refptr<const NGLayoutResult> content_layout_result =
         content.Layout(constraint_space);
     content_fragment =
         &To<NGPhysicalBoxFragment>(content_layout_result->PhysicalFragment());
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_padded_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_padded_layout_algorithm.h
index 4891a01..e3e43c4 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_padded_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_padded_layout_algorithm.h
@@ -16,7 +16,7 @@
  public:
   explicit NGMathPaddedLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
-  const NGLayoutResult* Layout() final;
+  scoped_refptr<const NGLayoutResult> Layout() final;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const final;
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.cc
index 95557609..3a5cfd1 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.cc
@@ -61,13 +61,12 @@
   }
 }
 
-const NGLayoutResult* NGMathRadicalLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGMathRadicalLayoutAlgorithm::Layout() {
   DCHECK(!BreakToken());
   DCHECK(IsValidMathMLRadical(Node()));
 
   auto vertical = GetRadicalVerticalParameters(Style(), Node().HasIndex());
-  const NGPhysicalBoxFragment* index_fragment = nullptr;
-  const NGPhysicalBoxFragment* base_fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> index_fragment, base_fragment;
   LayoutUnit index_inline_size, index_ascent, index_descent, base_ascent,
       base_descent;
   RadicalHorizontalParameters horizontal;
@@ -81,7 +80,8 @@
     // the row layout algorithm.
     NGConstraintSpace constraint_space = CreateConstraintSpaceForMathChild(
         Node(), ChildAvailableSize(), ConstraintSpace(), base);
-    const NGLayoutResult* base_layout_result = base.Layout(constraint_space);
+    scoped_refptr<const NGLayoutResult> base_layout_result =
+        base.Layout(constraint_space);
     base_fragment =
         &To<NGPhysicalBoxFragment>(base_layout_result->PhysicalFragment());
     base_margins =
@@ -96,7 +96,8 @@
     // (https://mathml-refresh.github.io/mathml-core/#root-with-index).
     NGConstraintSpace constraint_space = CreateConstraintSpaceForMathChild(
         Node(), ChildAvailableSize(), ConstraintSpace(), index);
-    const NGLayoutResult* index_layout_result = index.Layout(constraint_space);
+    scoped_refptr<const NGLayoutResult> index_layout_result =
+        index.Layout(constraint_space);
     index_fragment =
         &To<NGPhysicalBoxFragment>(index_layout_result->PhysicalFragment());
     index_margins =
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.h
index d982c57..71ec10f 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.h
@@ -17,7 +17,7 @@
  public:
   explicit NGMathRadicalLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
-  const NGLayoutResult* Layout() final;
+  scoped_refptr<const NGLayoutResult> Layout() final;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const final;
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.cc
index 6656c67..4287147 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.cc
@@ -75,7 +75,7 @@
     const ComputedStyle& child_style = child.Style();
     NGConstraintSpace child_space = CreateConstraintSpaceForMathChild(
         Node(), ChildAvailableSize(), ConstraintSpace(), child);
-    const NGLayoutResult* result =
+    scoped_refptr<const NGLayoutResult> result =
         To<NGBlockNode>(child).Layout(child_space, nullptr /* break token */);
     const NGPhysicalFragment& physical_fragment = result->PhysicalFragment();
     NGBoxFragment fragment(ConstraintSpace().GetWritingDirection(),
@@ -109,7 +109,7 @@
   row_total_size->block_size = max_row_ascent + max_row_descent;
 }
 
-const NGLayoutResult* NGMathRowLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGMathRowLayoutAlgorithm::Layout() {
   DCHECK(!BreakToken());
 
   bool is_display_block_math =
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h
index 13c356d..99b023a 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h
@@ -26,26 +26,21 @@
     ChildWithOffsetAndMargins(const NGBlockNode& child,
                               const NGBoxStrut& margins,
                               LogicalOffset offset,
-                              const NGPhysicalFragment* fragment)
+                              scoped_refptr<const NGPhysicalFragment> fragment)
         : child(child),
           margins(margins),
           offset(offset),
           fragment(std::move(fragment)) {}
 
-    void Trace(Visitor* visitor) const {
-      visitor->Trace(child);
-      visitor->Trace(fragment);
-    }
-
     NGBlockNode child;
     NGBoxStrut margins;
     LogicalOffset offset;
-    Member<const NGPhysicalFragment> fragment;
+    scoped_refptr<const NGPhysicalFragment> fragment;
   };
-  typedef HeapVector<ChildWithOffsetAndMargins, 4> ChildrenVector;
+  typedef Vector<ChildWithOffsetAndMargins, 4> ChildrenVector;
 
  private:
-  const NGLayoutResult* Layout() final;
+  scoped_refptr<const NGLayoutResult> Layout() final;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const final;
@@ -57,7 +52,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGMathRowLayoutAlgorithm::ChildWithOffsetAndMargins)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_ROW_LAYOUT_ALGORITHM_H_
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc
index 01c73cf..771d5a55 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.cc
@@ -94,7 +94,7 @@
 
 void NGMathScriptsLayoutAlgorithm::GatherChildren(
     NGBlockNode* base,
-    HeapVector<SubSupPair>* sub_sup_pairs,
+    Vector<SubSupPair>* sub_sup_pairs,
     NGBlockNode* prescripts,
     unsigned* first_prescript_index,
     NGBoxFragmentBuilder* container_builder) const {
@@ -286,12 +286,12 @@
   return child_and_metrics;
 }
 
-const NGLayoutResult* NGMathScriptsLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGMathScriptsLayoutAlgorithm::Layout() {
   DCHECK(!BreakToken());
 
   NGBlockNode base = nullptr;
   NGBlockNode prescripts = nullptr;
-  HeapVector<SubSupPair> sub_sup_pairs;
+  Vector<SubSupPair> sub_sup_pairs;
   wtf_size_t first_prescript_index = 0;
   GatherChildren(&base, &sub_sup_pairs, &prescripts, &first_prescript_index,
                  &container_builder_);
@@ -415,7 +415,7 @@
 
   NGBlockNode base = nullptr;
   NGBlockNode prescripts = nullptr;
-  HeapVector<SubSupPair> sub_sup_pairs;
+  Vector<SubSupPair> sub_sup_pairs;
   unsigned first_prescript_index = 0;
   GatherChildren(&base, &sub_sup_pairs, &prescripts, &first_prescript_index);
   DCHECK_GE(sub_sup_pairs.size(), 1ul);
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.h
index 28defc2a..8a998c1 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.h
@@ -21,40 +21,15 @@
  public:
   explicit NGMathScriptsLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
-  struct ChildAndMetrics {
-    DISALLOW_NEW();
-
-   public:
-    Member<const NGLayoutResult> result;
-    LayoutUnit ascent;
-    LayoutUnit descent;
-    LayoutUnit inline_size;
-    LayoutUnit base_italic_correction;
-    NGBoxStrut margins;
-    NGBlockNode node = nullptr;
-
-    void Trace(Visitor* visitor) const {
-      visitor->Trace(result);
-      visitor->Trace(node);
-    }
-  };
-
+ private:
   struct SubSupPair {
     DISALLOW_NEW();
-
-   public:
-    void Trace(Visitor* visitor) const {
-      visitor->Trace(sub);
-      visitor->Trace(sup);
-    }
-
     NGBlockNode sub = nullptr;
     NGBlockNode sup = nullptr;
   };
 
- private:
   void GatherChildren(NGBlockNode* base,
-                      HeapVector<SubSupPair>*,
+                      Vector<SubSupPair>*,
                       NGBlockNode* prescripts,
                       unsigned* first_prescript_index,
                       NGBoxFragmentBuilder* = nullptr) const;
@@ -62,7 +37,19 @@
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const final;
 
-  typedef HeapVector<ChildAndMetrics, 4> ChildrenAndMetrics;
+  struct ChildAndMetrics {
+    DISALLOW_NEW();
+
+   public:
+    scoped_refptr<const NGLayoutResult> result;
+    LayoutUnit ascent;
+    LayoutUnit descent;
+    LayoutUnit inline_size;
+    LayoutUnit base_italic_correction;
+    NGBoxStrut margins;
+    NGBlockNode node = nullptr;
+  };
+  typedef Vector<ChildAndMetrics, 4> ChildrenAndMetrics;
 
   ChildAndMetrics LayoutAndGetMetrics(NGBlockNode child) const;
 
@@ -81,14 +68,9 @@
       const ChildrenAndMetrics& sub_metrics,
       const ChildrenAndMetrics& sup_metrics) const;
 
-  const NGLayoutResult* Layout() final;
+  scoped_refptr<const NGLayoutResult> Layout() final;
 };
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGMathScriptsLayoutAlgorithm::ChildAndMetrics)
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGMathScriptsLayoutAlgorithm::SubSupPair)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_SCRIPTS_LAYOUT_ALGORITHM_H_
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.cc
index 0f12572..6d635ae 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.cc
@@ -16,7 +16,7 @@
   DCHECK(params.space.IsNewFormattingContext());
 }
 
-const NGLayoutResult* NGMathSpaceLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGMathSpaceLayoutAlgorithm::Layout() {
   DCHECK(!BreakToken());
 
   LayoutUnit intrinsic_block_size = BorderScrollbarPadding().BlockSum();
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.h
index f838ca18..3803d81 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.h
@@ -18,7 +18,7 @@
   explicit NGMathSpaceLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
  private:
-  const NGLayoutResult* Layout() final;
+  scoped_refptr<const NGLayoutResult> Layout() final;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const final;
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc
index cd2c11c..6d08cad 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.cc
@@ -182,7 +182,7 @@
   }
 }
 
-const NGLayoutResult* NGMathUnderOverLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGMathUnderOverLayoutAlgorithm::Layout() {
   DCHECK(!BreakToken());
   DCHECK(IsValidMathMLScript(Node()));
 
@@ -216,7 +216,7 @@
 
   auto base_space = CreateConstraintSpaceForMathChild(
       Node(), ChildAvailableSize(), ConstraintSpace(), base);
-  auto* base_layout_result = base.Layout(base_space);
+  auto base_layout_result = base.Layout(base_space);
   auto base_margins =
       ComputeMarginsFor(base_space, base.Style(), ConstraintSpace());
 
@@ -230,7 +230,8 @@
   if (over) {
     auto over_space = CreateConstraintSpaceForMathChild(
         Node(), ChildAvailableSize(), ConstraintSpace(), over);
-    const NGLayoutResult* over_layout_result = over.Layout(over_space);
+    scoped_refptr<const NGLayoutResult> over_layout_result =
+        over.Layout(over_space);
     NGBoxStrut over_margins =
         ComputeMarginsFor(over_space, over.Style(), ConstraintSpace());
     NGBoxFragment over_fragment(
@@ -278,7 +279,8 @@
   if (under) {
     auto under_space = CreateConstraintSpaceForMathChild(
         Node(), ChildAvailableSize(), ConstraintSpace(), under);
-    const NGLayoutResult* under_layout_result = under.Layout(under_space);
+    scoped_refptr<const NGLayoutResult> under_layout_result =
+        under.Layout(under_space);
     NGBoxStrut under_margins =
         ComputeMarginsFor(under_space, under.Style(), ConstraintSpace());
     NGBoxFragment under_fragment(
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.h
index 80038d4d..b850e09a 100644
--- a/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/mathml/ng_math_under_over_layout_algorithm.h
@@ -18,7 +18,7 @@
   explicit NGMathUnderOverLayoutAlgorithm(
       const NGLayoutAlgorithmParams& params);
 
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
index 93e94f2..b70fa7f 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
@@ -460,7 +460,7 @@
   return depends_on_min_max_sizes;
 }
 
-const NGLayoutResult* ComputeOutOfFlowBlockDimensions(
+scoped_refptr<const NGLayoutResult> ComputeOutOfFlowBlockDimensions(
     const NGBlockNode& node,
     const NGConstraintSpace& space,
     const NGBoxStrut& border_padding,
@@ -470,7 +470,7 @@
     NGLogicalOutOfFlowDimensions* dimensions) {
   DCHECK(dimensions);
 
-  Member<const NGLayoutResult> result;
+  scoped_refptr<const NGLayoutResult> result;
 
   // NOTE: |is_shrink_to_fit| isn't symmetrical with the inline calculations.
   const auto& style = node.Style();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
index dc599b7..752e029 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
@@ -51,7 +51,7 @@
 
 // If layout was performed to determine the position, this will be returned
 // otherwise it will return nullptr.
-CORE_EXPORT const NGLayoutResult* ComputeOutOfFlowBlockDimensions(
+CORE_EXPORT scoped_refptr<const NGLayoutResult> ComputeOutOfFlowBlockDimensions(
     const NGBlockNode&,
     const NGConstraintSpace&,
     const NGBoxStrut& border_padding,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc
index ae419f5..d9818fb 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/renderer/core/layout/ng/geometry/ng_static_position.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
@@ -46,14 +47,13 @@
     RunDocumentLifecycle();
 
     element_ = GetDocument().getElementById("target");
-    spaces_ = MakeGarbageCollected<Spaces>();
-    spaces_->ltr_space_ = CreateConstraintSpace(
+    ltr_space_ = CreateConstraintSpace(
         {WritingMode::kHorizontalTb, TextDirection::kLtr});
-    spaces_->rtl_space_ = CreateConstraintSpace(
+    rtl_space_ = CreateConstraintSpace(
         {WritingMode::kHorizontalTb, TextDirection::kRtl});
-    spaces_->vlr_space_ =
+    vlr_space_ =
         CreateConstraintSpace({WritingMode::kVerticalLr, TextDirection::kLtr});
-    spaces_->vrl_space_ =
+    vrl_space_ =
         CreateConstraintSpace({WritingMode::kVerticalRl, TextDirection::kLtr});
   }
 
@@ -92,23 +92,11 @@
     RunDocumentLifecycle();
   }
 
-  struct Spaces final : public GarbageCollected<Spaces> {
-   public:
-    NGConstraintSpace ltr_space_;
-    NGConstraintSpace rtl_space_;
-    NGConstraintSpace vlr_space_;
-    NGConstraintSpace vrl_space_;
-
-    void Trace(Visitor* visitor) const {
-      visitor->Trace(ltr_space_);
-      visitor->Trace(rtl_space_);
-      visitor->Trace(vlr_space_);
-      visitor->Trace(vrl_space_);
-    }
-  };
-
   Persistent<Element> element_;
-  Persistent<Spaces> spaces_;
+  NGConstraintSpace ltr_space_;
+  NGConstraintSpace rtl_space_;
+  NGConstraintSpace vlr_space_;
+  NGConstraintSpace vrl_space_;
 };
 
 TEST_F(NGAbsoluteUtilsTest, Horizontal) {
@@ -120,18 +108,14 @@
   element_->SetInlineStyleProperty(CSSPropertyID::kContainIntrinsicSize,
                                    "60px 4px");
 
-  NGBoxStrut ltr_border_padding =
-      ComputeBorders(spaces_->ltr_space_, node) +
-      ComputePadding(spaces_->ltr_space_, node.Style());
-  NGBoxStrut rtl_border_padding =
-      ComputeBorders(spaces_->rtl_space_, node) +
-      ComputePadding(spaces_->rtl_space_, node.Style());
-  NGBoxStrut vlr_border_padding =
-      ComputeBorders(spaces_->vlr_space_, node) +
-      ComputePadding(spaces_->vlr_space_, node.Style());
-  NGBoxStrut vrl_border_padding =
-      ComputeBorders(spaces_->vrl_space_, node) +
-      ComputePadding(spaces_->vrl_space_, node.Style());
+  NGBoxStrut ltr_border_padding = ComputeBorders(ltr_space_, node) +
+                                  ComputePadding(ltr_space_, node.Style());
+  NGBoxStrut rtl_border_padding = ComputeBorders(rtl_space_, node) +
+                                  ComputePadding(rtl_space_, node.Style());
+  NGBoxStrut vlr_border_padding = ComputeBorders(vlr_space_, node) +
+                                  ComputePadding(vlr_space_, node.Style());
+  NGBoxStrut vrl_border_padding = ComputeBorders(vrl_space_, node) +
+                                  ComputePadding(vrl_space_, node.Style());
 
   NGLogicalStaticPosition static_position = {
       {LayoutUnit(), LayoutUnit()},
@@ -148,16 +132,15 @@
   // All auto => width is content, left is 0.
   SetHorizontalStyle("auto", "auto", "auto", "auto", "auto");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(116, dimensions.size.inline_size);
   EXPECT_EQ(0, dimensions.inset.inline_start);
 
   // All auto => width is content, static_position is right
   SetHorizontalStyle("auto", "auto", "auto", "auto", "auto");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position_inline_end,
+      node, ltr_space_, ltr_border_padding, static_position_inline_end,
       base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
       &dimensions);
   EXPECT_EQ(116, dimensions.size.inline_size);
@@ -166,9 +149,8 @@
   // All auto + RTL.
   SetHorizontalStyle("auto", "auto", "auto", "auto", "auto");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->rtl_space_, rtl_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, rtl_space_, rtl_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(116, dimensions.size.inline_size);
   // 200 = 0 + 0 + 116 + 84 + 0
   EXPECT_EQ(84, dimensions.inset.inline_end);
@@ -176,9 +158,8 @@
   // left, right, and left are known, compute margins.
   SetHorizontalStyle("5px", "auto", "160px", "auto", "13px");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 200 = 5 + 11 + 160 + 11 + 13
   EXPECT_EQ(16, dimensions.inset.inline_start);
   EXPECT_EQ(24, dimensions.inset.inline_end);
@@ -186,53 +167,47 @@
   // left, right, and left are known, compute margins, writing mode vertical_lr.
   SetHorizontalStyle("5px", "auto", "160px", "auto", "13px", "vertical-lr");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->vlr_space_, vlr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, vlr_space_, vlr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(16, dimensions.inset.block_start);
   EXPECT_EQ(24, dimensions.inset.block_end);
 
   // left, right, and left are known, compute margins, writing mode vertical_rl.
   SetHorizontalStyle("5px", "auto", "160px", "auto", "13px", "vertical-rl");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->vrl_space_, vrl_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, vrl_space_, vrl_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(16, dimensions.inset.block_end);
   EXPECT_EQ(24, dimensions.inset.block_start);
 
   // left, right, and width are known, not enough space for margins LTR.
   SetHorizontalStyle("5px", "auto", "200px", "auto", "13px");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(5, dimensions.inset.inline_start);
   EXPECT_EQ(-5, dimensions.inset.inline_end);
 
   // left, right, and left are known, not enough space for margins RTL.
   SetHorizontalStyle("5px", "auto", "200px", "auto", "13px");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->rtl_space_, rtl_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kRtl},
-      &dimensions);
+      node, rtl_space_, rtl_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kRtl}, &dimensions);
   EXPECT_EQ(-13, dimensions.inset.inline_start);
   EXPECT_EQ(13, dimensions.inset.inline_end);
 
   // Rule 1 left and width are auto.
   SetHorizontalStyle("auto", "7px", "auto", "15px", "13px");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(116, dimensions.size.inline_size);
 
   // Rule 2 left and right are auto LTR.
   SetHorizontalStyle("auto", "7px", "160px", "15px", "auto");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 200 = 0 + 7 + 160 + 15 + 18
   EXPECT_EQ(0 + 7, dimensions.inset.inline_start);
   EXPECT_EQ(15 + 18, dimensions.inset.inline_end);
@@ -240,9 +215,8 @@
   // Rule 2 left and right are auto RTL.
   SetHorizontalStyle("auto", "7px", "160px", "15px", "auto");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->rtl_space_, rtl_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kRtl},
-      &dimensions);
+      node, rtl_space_, rtl_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kRtl}, &dimensions);
   // 200 = 0 + 7 + 160 + 15 + 18
   EXPECT_EQ(0 + 7, dimensions.inset.inline_start);
   EXPECT_EQ(15 + 18, dimensions.inset.inline_end);
@@ -250,9 +224,8 @@
   // Rule 3 width and right are auto.
   SetHorizontalStyle("5px", "7px", "auto", "15px", "auto");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 200 = 5 + 7 + 116 + 15 + 57
   EXPECT_EQ(116, dimensions.size.inline_size);
   EXPECT_EQ(15 + 57, dimensions.inset.inline_end);
@@ -260,9 +233,8 @@
   // Rule 4: left is auto.
   SetHorizontalStyle("auto", "7px", "160px", "15px", "13px");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 200 = 5 + 7 + 160 + 15 + 13
   EXPECT_EQ(5 + 7, dimensions.inset.inline_start);
 
@@ -270,27 +242,24 @@
   SetHorizontalStyle("auto", "7px", "104px", "15px", "13px", "horizontal-tb",
                      "content-box");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 200 = 5 + 7 + 160 + 15 + 13
   EXPECT_EQ(5 + 7, dimensions.inset.inline_start);
 
   // Rule 5: right is auto.
   SetHorizontalStyle("5px", "7px", "160px", "15px", "auto");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 200 = 5 + 7 + 160 + 15 + 13
   EXPECT_EQ(15 + 13, dimensions.inset.inline_end);
 
   // Rule 6: width is auto.
   SetHorizontalStyle("5px", "7px", "auto", "15px", "13px");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 200 = 5 + 7 + 160 + 15 + 13
   EXPECT_EQ(160, dimensions.size.inline_size);
 }
@@ -305,15 +274,12 @@
 
   NGBlockNode node(element_->GetLayoutBox());
 
-  NGBoxStrut ltr_border_padding =
-      ComputeBorders(spaces_->ltr_space_, node) +
-      ComputePadding(spaces_->ltr_space_, node.Style());
-  NGBoxStrut vlr_border_padding =
-      ComputeBorders(spaces_->vlr_space_, node) +
-      ComputePadding(spaces_->vlr_space_, node.Style());
-  NGBoxStrut vrl_border_padding =
-      ComputeBorders(spaces_->vrl_space_, node) +
-      ComputePadding(spaces_->vrl_space_, node.Style());
+  NGBoxStrut ltr_border_padding = ComputeBorders(ltr_space_, node) +
+                                  ComputePadding(ltr_space_, node.Style());
+  NGBoxStrut vlr_border_padding = ComputeBorders(vlr_space_, node) +
+                                  ComputePadding(vlr_space_, node.Style());
+  NGBoxStrut vrl_border_padding = ComputeBorders(vrl_space_, node) +
+                                  ComputePadding(vrl_space_, node.Style());
 
   NGLogicalStaticPosition static_position = {
       {LayoutUnit(), LayoutUnit()},
@@ -328,22 +294,20 @@
 
   // Set inline-dimensions in-case any block dimensions require it.
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
 
   // All auto, compute margins.
   SetVerticalStyle("auto", "auto", "auto", "auto", "auto");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(60, dimensions.size.block_size);
   EXPECT_EQ(0, dimensions.inset.block_start);
 
   // All auto, static position bottom.
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position_block_end,
+      node, ltr_space_, ltr_border_padding, static_position_block_end,
       base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
       &dimensions);
   EXPECT_EQ(300, dimensions.inset.block_end);
@@ -351,9 +315,8 @@
   // If top, bottom, and height are known, compute margins.
   SetVerticalStyle("5px", "auto", "260px", "auto", "13px");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 300 = 5 + 11 + 260 + 11 + 13
   EXPECT_EQ(5 + 11, dimensions.inset.block_start);
   EXPECT_EQ(11 + 13, dimensions.inset.block_end);
@@ -361,9 +324,8 @@
   // If top, bottom, and height are known, "writing-mode: vertical-lr".
   SetVerticalStyle("5px", "auto", "260px", "auto", "13px", "vertical-lr");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->vlr_space_, vlr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, vlr_space_, vlr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 300 = 5 + 11 + 260 + 11 + 13
   EXPECT_EQ(5 + 11, dimensions.inset.inline_start);
   EXPECT_EQ(11 + 13, dimensions.inset.inline_end);
@@ -371,9 +333,8 @@
   // If top, bottom, and height are known, "writing-mode: vertical-rl".
   SetVerticalStyle("5px", "auto", "260px", "auto", "13px", "vertical-rl");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->vrl_space_, vrl_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, vrl_space_, vrl_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 300 = 5 + 11 + 260 + 11 + 13
   EXPECT_EQ(5 + 11, dimensions.inset.inline_start);
   EXPECT_EQ(11 + 13, dimensions.inset.inline_end);
@@ -381,9 +342,8 @@
   // If top, bottom, and height are known, negative auto margins.
   SetVerticalStyle("5px", "auto", "300px", "auto", "13px");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 300 = 5 + (-9) + 300 + (-9) + 13
   EXPECT_EQ(5 - 9, dimensions.inset.block_start);
   EXPECT_EQ(-9 + 13, dimensions.inset.block_end);
@@ -391,17 +351,15 @@
   // Rule 1: top and height are unknown.
   SetVerticalStyle("auto", "7px", "auto", "15px", "13px");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(60, dimensions.size.block_size);
 
   // Rule 2: top and bottom are unknown.
   SetVerticalStyle("auto", "7px", "260px", "15px", "auto");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 300 = 0 + 7 + 260 + 15 + 18
   EXPECT_EQ(0 + 7, dimensions.inset.block_start);
   EXPECT_EQ(15 + 18, dimensions.inset.block_end);
@@ -409,26 +367,23 @@
   // Rule 3: height and bottom are unknown.
   SetVerticalStyle("5px", "7px", "auto", "15px", "auto");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(60, dimensions.size.block_size);
 
   // Rule 4: top is unknown.
   SetVerticalStyle("auto", "7px", "260px", "15px", "13px");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   // 300 = 5 + 7 + 260 + 15 + 13
   EXPECT_EQ(5 + 7, dimensions.inset.block_start);
 
   // Rule 5: bottom is unknown.
   SetVerticalStyle("5px", "7px", "260px", "15px", "auto");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(260, dimensions.size.block_size);
 }
 
@@ -449,21 +404,21 @@
   NGLogicalOutOfFlowDimensions dimensions;
 
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, border_padding, static_position, base::nullopt,
+      node, ltr_space_, border_padding, static_position, base::nullopt,
       {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(100, dimensions.size.inline_size);
   EXPECT_EQ(100, dimensions.inset.inline_start);
   EXPECT_EQ(0, dimensions.inset.inline_end);
 
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, border_padding, static_position, base::nullopt,
+      node, ltr_space_, border_padding, static_position, base::nullopt,
       {WritingMode::kHorizontalTb, TextDirection::kRtl}, &dimensions);
   EXPECT_EQ(100, dimensions.size.inline_size);
   EXPECT_EQ(100, dimensions.inset.inline_start);
   EXPECT_EQ(0, dimensions.inset.inline_end);
 
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, border_padding, static_position, base::nullopt,
+      node, ltr_space_, border_padding, static_position, base::nullopt,
       {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(150, dimensions.size.block_size);
   EXPECT_EQ(125, dimensions.inset.block_start);
@@ -482,9 +437,8 @@
 
   NGBlockNode node(element_->GetLayoutBox());
 
-  NGBoxStrut ltr_border_padding =
-      ComputeBorders(spaces_->ltr_space_, node) +
-      ComputePadding(spaces_->ltr_space_, node.Style());
+  NGBoxStrut ltr_border_padding = ComputeBorders(ltr_space_, node) +
+                                  ComputePadding(ltr_space_, node.Style());
 
   NGLogicalStaticPosition static_position = {
       {LayoutUnit(), LayoutUnit()},
@@ -498,25 +452,22 @@
   // width < min gets set to min.
   SetHorizontalStyle("auto", "auto", "5px", "auto", "auto");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(70, dimensions.size.inline_size);
 
   // width > max gets set to max.
   SetHorizontalStyle("auto", "auto", "200px", "auto", "auto");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(150, dimensions.size.inline_size);
 
   // Unspecified width becomes min_max, gets clamped to min.
   SetHorizontalStyle("auto", "auto", "auto", "auto", "auto");
   ComputeOutOfFlowInlineDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(70, dimensions.size.inline_size);
 
   // HEIGHT TESTS
@@ -524,25 +475,22 @@
   // height < min gets set to min.
   SetVerticalStyle("auto", "auto", "5px", "auto", "auto");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(70, dimensions.size.block_size);
 
   // height > max gets set to max.
   SetVerticalStyle("auto", "auto", "200px", "auto", "auto");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(150, dimensions.size.block_size);
 
   // // Unspecified height becomes estimated, gets clamped to min.
   SetVerticalStyle("auto", "auto", "auto", "auto", "auto");
   ComputeOutOfFlowBlockDimensions(
-      node, spaces_->ltr_space_, ltr_border_padding, static_position,
-      base::nullopt, {WritingMode::kHorizontalTb, TextDirection::kLtr},
-      &dimensions);
+      node, ltr_space_, ltr_border_padding, static_position, base::nullopt,
+      {WritingMode::kHorizontalTb, TextDirection::kLtr}, &dimensions);
   EXPECT_EQ(70, dimensions.size.block_size);
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc
index cea30aeb..b6a1bd17 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc
@@ -30,14 +30,15 @@
   GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInPerformLayout);
 }
 
-const NGPhysicalBoxFragment* NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(
+scoped_refptr<const NGPhysicalBoxFragment>
+NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(
     NGBlockNode node,
     const NGConstraintSpace& space,
     const NGBreakToken* break_token) {
   NGFragmentGeometry fragment_geometry =
       CalculateInitialFragmentGeometry(space, node);
 
-  const NGLayoutResult* result =
+  scoped_refptr<const NGLayoutResult> result =
       NGBlockLayoutAlgorithm(
           {node, fragment_geometry, space, To<NGBlockBreakToken>(break_token)})
           .Layout();
@@ -45,7 +46,7 @@
   return To<NGPhysicalBoxFragment>(&result->PhysicalFragment());
 }
 
-std::pair<const NGPhysicalBoxFragment*, NGConstraintSpace>
+std::pair<scoped_refptr<const NGPhysicalBoxFragment>, NGConstraintSpace>
 NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithmForElement(Element* element) {
   auto* block_flow = To<LayoutBlockFlow>(element->GetLayoutObject());
   NGBlockNode node(block_flow);
@@ -54,13 +55,13 @@
   NGFragmentGeometry fragment_geometry =
       CalculateInitialFragmentGeometry(space, node);
 
-  const NGLayoutResult* result =
+  scoped_refptr<const NGLayoutResult> result =
       NGBlockLayoutAlgorithm({node, fragment_geometry, space}).Layout();
   return std::make_pair(To<NGPhysicalBoxFragment>(&result->PhysicalFragment()),
                         std::move(space));
 }
 
-const NGPhysicalBoxFragment*
+scoped_refptr<const NGPhysicalBoxFragment>
 NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
     NGBlockNode node,
     const NGConstraintSpace& space,
@@ -68,7 +69,7 @@
   NGFragmentGeometry fragment_geometry =
       CalculateInitialFragmentGeometry(space, node);
 
-  const NGLayoutResult* result =
+  scoped_refptr<const NGLayoutResult> result =
       NGFieldsetLayoutAlgorithm(
           {node, fragment_geometry, space, To<NGBlockBreakToken>(break_token)})
           .Layout();
@@ -76,11 +77,11 @@
   return To<NGPhysicalBoxFragment>(&result->PhysicalFragment());
 }
 
-const NGPhysicalBoxFragment*
+scoped_refptr<const NGPhysicalBoxFragment>
 NGBaseLayoutAlgorithmTest::GetBoxFragmentByElementId(const char* id) {
   LayoutObject* layout_object = GetLayoutObjectByElementId(id);
   CHECK(layout_object && layout_object->IsLayoutNGMixin());
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       To<LayoutBlockFlow>(layout_object)->GetPhysicalFragment(0);
   CHECK(fragment);
   return fragment;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h b/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h
index 3e757c8..c8ab2326 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h
@@ -33,20 +33,21 @@
   // RunBlockLayoutAlgorithmForElement.
   void AdvanceToLayoutPhase();
 
-  const NGPhysicalBoxFragment* RunBlockLayoutAlgorithm(
+  scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
       NGBlockNode node,
       const NGConstraintSpace& space,
       const NGBreakToken* break_token = nullptr);
 
-  std::pair<const NGPhysicalBoxFragment*, NGConstraintSpace>
+  std::pair<scoped_refptr<const NGPhysicalBoxFragment>, NGConstraintSpace>
   RunBlockLayoutAlgorithmForElement(Element* element);
 
-  const NGPhysicalBoxFragment* RunFieldsetLayoutAlgorithm(
+  scoped_refptr<const NGPhysicalBoxFragment> RunFieldsetLayoutAlgorithm(
       NGBlockNode node,
       const NGConstraintSpace& space,
       const NGBreakToken* break_token = nullptr);
 
-  const NGPhysicalBoxFragment* GetBoxFragmentByElementId(const char*);
+  scoped_refptr<const NGPhysicalBoxFragment> GetBoxFragmentByElementId(
+      const char*);
 
   static const NGPhysicalBoxFragment* CurrentFragmentFor(
       const LayoutNGBlockFlow*);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc
index 528e161c..05939263 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc
@@ -6,8 +6,6 @@
 
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
 #include "third_party/blink/renderer/platform/wtf/size_assertions.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
@@ -23,15 +21,17 @@
 
 }  // namespace
 
-NGBlockBreakToken* NGBlockBreakToken::Create(
+scoped_refptr<NGBlockBreakToken> NGBlockBreakToken::Create(
     const NGBoxFragmentBuilder& builder) {
   // We store the children list inline in the break token as a flexible
   // array. Therefore, we need to make sure to allocate enough space for that
   // array here, which requires a manual allocation + placement new.
-  return MakeGarbageCollected<NGBlockBreakToken>(
-      AdditionalBytes(builder.child_break_tokens_.size() *
-                      sizeof(Member<NGBreakToken>)),
-      PassKey(), builder);
+  void* data = ::WTF::Partitions::FastMalloc(
+      sizeof(NGBlockBreakToken) +
+          builder.child_break_tokens_.size() * sizeof(NGBreakToken*),
+      ::WTF::GetStringWithTypeName<NGBlockBreakToken>());
+  new (data) NGBlockBreakToken(PassKey(), builder);
+  return base::AdoptRef(static_cast<NGBlockBreakToken*>(data));
 }
 
 NGBlockBreakToken::NGBlockBreakToken(PassKey key,
@@ -39,17 +39,19 @@
     : NGBreakToken(kBlockBreakToken, builder.node_),
       consumed_block_size_(builder.consumed_block_size_),
       sequence_number_(builder.sequence_number_),
-      const_num_children_(builder.child_break_tokens_.size()) {
+      num_children_(builder.child_break_tokens_.size()) {
   break_appeal_ = builder.break_appeal_;
   has_seen_all_children_ = builder.has_seen_all_children_;
   is_caused_by_column_spanner_ = builder.FoundColumnSpanner();
   is_at_block_end_ = builder.is_at_block_end_;
-  for (wtf_size_t i = 0; i < builder.child_break_tokens_.size(); ++i)
-    child_break_tokens_[i] = builder.child_break_tokens_[i];
+  for (wtf_size_t i = 0; i < builder.child_break_tokens_.size(); ++i) {
+    child_break_tokens_[i] = builder.child_break_tokens_[i].get();
+    child_break_tokens_[i]->AddRef();
+  }
 }
 
 NGBlockBreakToken::NGBlockBreakToken(PassKey key, NGLayoutInputNode node)
-    : NGBreakToken(kBlockBreakToken, node), const_num_children_(0) {}
+    : NGBreakToken(kBlockBreakToken, node), num_children_(0) {}
 
 const NGInlineBreakToken* NGBlockBreakToken::InlineBreakTokenFor(
     const NGLayoutInputNode& node) const {
@@ -90,12 +92,4 @@
 
 #endif  // DCHECK_IS_ON()
 
-void NGBlockBreakToken::Trace(Visitor* visitor) const {
-  // Looking up |ChildBreakTokens()| in Trace() here is safe because
-  // |const_num_children_| is const.
-  for (auto& child : ChildBreakTokens())
-    visitor->Trace(child);
-  NGBreakToken::Trace(visitor);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h
index 73cfa02f..8261b76 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h
@@ -26,17 +26,23 @@
   //
   // The node is NGBlockNode, or any other NGLayoutInputNode that produces
   // anonymous box.
-  static NGBlockBreakToken* Create(const NGBoxFragmentBuilder&);
+  static scoped_refptr<NGBlockBreakToken> Create(const NGBoxFragmentBuilder&);
 
   // Creates a break token for a node that needs to produce its first fragment
   // in the next fragmentainer. In this case we create a break token for a node
   // that hasn't yet produced any fragments.
-  static NGBlockBreakToken* CreateBreakBefore(NGLayoutInputNode node,
-                                              bool is_forced_break) {
-    auto* token = MakeGarbageCollected<NGBlockBreakToken>(PassKey(), node);
+  static scoped_refptr<NGBlockBreakToken> CreateBreakBefore(
+      NGLayoutInputNode node,
+      bool is_forced_break) {
+    auto* token = new NGBlockBreakToken(PassKey(), node);
     token->is_break_before_ = true;
     token->is_forced_break_ = is_forced_break;
-    return token;
+    return base::AdoptRef(token);
+  }
+
+  ~NGBlockBreakToken() override {
+    for (const NGBreakToken* token : ChildBreakTokens())
+      token->Release();
   }
 
   // Represents the amount of block-size consumed by previous fragments.
@@ -107,8 +113,8 @@
   // this child).
   //
   // A child which we haven't visited yet doesn't have a break token here.
-  const base::span<const Member<const NGBreakToken>> ChildBreakTokens() const {
-    return base::make_span(child_break_tokens_, const_num_children_);
+  const base::span<const NGBreakToken* const> ChildBreakTokens() const {
+    return base::make_span(child_break_tokens_, num_children_);
   }
 
   // Find the child NGInlineBreakToken for the specified node.
@@ -136,8 +142,10 @@
     // Replace the child break token at the provided |index|.
     void ReplaceChildBreakToken(const NGBreakToken* child_break_token,
                                 wtf_size_t index) {
-      DCHECK_LT(index, break_token_->const_num_children_);
+      DCHECK_LT(index, break_token_->num_children_);
+      break_token_->child_break_tokens_[index]->Release();
       break_token_->child_break_tokens_[index] = child_break_token;
+      break_token_->child_break_tokens_[index]->AddRef();
     }
 
    private:
@@ -152,15 +160,13 @@
     return MutableForOutOfFlow(this);
   }
 
-  void Trace(Visitor*) const override;
-
  private:
   LayoutUnit consumed_block_size_;
   unsigned sequence_number_ = 0;
 
-  const wtf_size_t const_num_children_;
+  wtf_size_t num_children_;
   // This must be the last member, because it is a flexible array.
-  Member<const NGBreakToken> child_break_tokens_[];
+  const NGBreakToken* child_break_tokens_[];
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc b/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc
index 58e0370..d5731fff 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_child_iterator_test.cc
@@ -15,7 +15,7 @@
 namespace blink {
 namespace {
 
-const NGBlockBreakToken* CreateBreakToken(
+scoped_refptr<const NGBlockBreakToken> CreateBreakToken(
     NGLayoutInputNode node,
     const NGBreakTokenVector* child_break_tokens = nullptr,
     bool has_seen_all_children = false) {
@@ -25,7 +25,7 @@
   if (has_seen_all_children)
     builder.SetHasSeenAllChildren();
   if (child_break_tokens) {
-    for (const NGBreakToken* token : *child_break_tokens)
+    for (scoped_refptr<const NGBreakToken> token : *child_break_tokens)
       builder.AddBreakToken(token);
   }
   return NGBlockBreakToken::Create(builder);
@@ -74,17 +74,17 @@
   NGLayoutInputNode node4 = node3.NextSibling();
 
   NGBreakTokenVector empty_tokens_list;
-  const NGBreakToken* child_token1 = CreateBreakToken(node1);
-  const NGBreakToken* child_token2 = CreateBreakToken(node2);
-  const NGBreakToken* child_token3 = CreateBreakToken(node3);
+  scoped_refptr<const NGBreakToken> child_token1 = CreateBreakToken(node1);
+  scoped_refptr<const NGBreakToken> child_token2 = CreateBreakToken(node2);
+  scoped_refptr<const NGBreakToken> child_token3 = CreateBreakToken(node3);
 
   NGBreakTokenVector child_break_tokens;
   child_break_tokens.push_back(child_token1);
-  const NGBlockBreakToken* parent_token =
+  scoped_refptr<const NGBlockBreakToken> parent_token =
       CreateBreakToken(container, &child_break_tokens);
 
-  NGBlockChildIterator iterator(node1, parent_token);
-  ASSERT_EQ(NGBlockChildIterator::Entry(node1, child_token1),
+  NGBlockChildIterator iterator(node1, parent_token.get());
+  ASSERT_EQ(NGBlockChildIterator::Entry(node1, child_token1.get()),
             iterator.NextChild());
   ASSERT_EQ(NGBlockChildIterator::Entry(node2, nullptr), iterator.NextChild());
   ASSERT_EQ(NGBlockChildIterator::Entry(node3, nullptr), iterator.NextChild());
@@ -97,10 +97,10 @@
   child_break_tokens.push_back(child_token2);
   parent_token = CreateBreakToken(container, &child_break_tokens);
 
-  iterator = NGBlockChildIterator(node1, parent_token);
-  ASSERT_EQ(NGBlockChildIterator::Entry(node1, child_token1),
+  iterator = NGBlockChildIterator(node1, parent_token.get());
+  ASSERT_EQ(NGBlockChildIterator::Entry(node1, child_token1.get()),
             iterator.NextChild());
-  ASSERT_EQ(NGBlockChildIterator::Entry(node2, child_token2),
+  ASSERT_EQ(NGBlockChildIterator::Entry(node2, child_token2.get()),
             iterator.NextChild());
   ASSERT_EQ(NGBlockChildIterator::Entry(node3, nullptr), iterator.NextChild());
   ASSERT_EQ(NGBlockChildIterator::Entry(node4, nullptr), iterator.NextChild());
@@ -112,10 +112,10 @@
   child_break_tokens.push_back(child_token3);
   parent_token = CreateBreakToken(container, &child_break_tokens);
 
-  iterator = NGBlockChildIterator(node1, parent_token);
-  ASSERT_EQ(NGBlockChildIterator::Entry(node2, child_token2),
+  iterator = NGBlockChildIterator(node1, parent_token.get());
+  ASSERT_EQ(NGBlockChildIterator::Entry(node2, child_token2.get()),
             iterator.NextChild());
-  ASSERT_EQ(NGBlockChildIterator::Entry(node3, child_token3),
+  ASSERT_EQ(NGBlockChildIterator::Entry(node3, child_token3.get()),
             iterator.NextChild());
   ASSERT_EQ(NGBlockChildIterator::Entry(node4, nullptr), iterator.NextChild());
   ASSERT_EQ(NGBlockChildIterator::Entry(nullptr, nullptr),
@@ -126,10 +126,10 @@
   child_break_tokens.push_back(child_token3);
   parent_token = CreateBreakToken(container, &child_break_tokens);
 
-  iterator = NGBlockChildIterator(node1, parent_token);
-  ASSERT_EQ(NGBlockChildIterator::Entry(node1, child_token1),
+  iterator = NGBlockChildIterator(node1, parent_token.get());
+  ASSERT_EQ(NGBlockChildIterator::Entry(node1, child_token1.get()),
             iterator.NextChild());
-  ASSERT_EQ(NGBlockChildIterator::Entry(node3, child_token3),
+  ASSERT_EQ(NGBlockChildIterator::Entry(node3, child_token3.get()),
             iterator.NextChild());
   ASSERT_EQ(NGBlockChildIterator::Entry(node4, nullptr), iterator.NextChild());
   ASSERT_EQ(NGBlockChildIterator::Entry(nullptr, nullptr),
@@ -146,19 +146,19 @@
   NGBlockNode container = NGBlockNode(GetLayoutBoxByElementId("container"));
   NGLayoutInputNode node1 = container.FirstChild();
 
-  const NGBlockBreakToken* child_token1 = CreateBreakToken(node1);
+  scoped_refptr<const NGBlockBreakToken> child_token1 = CreateBreakToken(node1);
 
   NGBreakTokenVector child_break_tokens;
   child_break_tokens.push_back(child_token1);
-  const NGBlockBreakToken* parent_token = CreateBreakToken(
+  scoped_refptr<const NGBlockBreakToken> parent_token = CreateBreakToken(
       container, &child_break_tokens, /* has_seen_all_children*/ true);
 
   // We have a break token for #child1, but have seen all children. This happens
   // e.g. when #child1 has overflow into a new fragmentainer, while #child2 was
   // finished in an earlier fragmentainer.
 
-  NGBlockChildIterator iterator(node1, parent_token);
-  ASSERT_EQ(NGBlockChildIterator::Entry(node1, child_token1),
+  NGBlockChildIterator iterator(node1, parent_token.get());
+  ASSERT_EQ(NGBlockChildIterator::Entry(node1, child_token1.get()),
             iterator.NextChild());
   ASSERT_EQ(NGBlockChildIterator::Entry(nullptr, nullptr),
             iterator.NextChild());
@@ -170,7 +170,7 @@
   // we have a large container with fixed block-size, with empty space at the
   // end, not occupied by any children.
 
-  iterator = NGBlockChildIterator(node1, parent_token);
+  iterator = NGBlockChildIterator(node1, parent_token.get());
   ASSERT_EQ(NGBlockChildIterator::Entry(nullptr, nullptr),
             iterator.NextChild());
 }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
index 0e6e6cf..74dabe7 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -94,10 +94,11 @@
   return offset;
 }
 
-inline const NGLayoutResult* LayoutBlockChild(const NGConstraintSpace& space,
-                                              const NGBreakToken* break_token,
-                                              const NGEarlyBreak* early_break,
-                                              NGBlockNode* node) {
+inline scoped_refptr<const NGLayoutResult> LayoutBlockChild(
+    const NGConstraintSpace& space,
+    const NGBreakToken* break_token,
+    const NGEarlyBreak* early_break,
+    NGBlockNode* node) {
   const NGEarlyBreak* early_break_in_child = nullptr;
   if (UNLIKELY(early_break))
     early_break_in_child = EnterEarlyBreakInChild(*node, *early_break);
@@ -105,11 +106,12 @@
                       early_break_in_child);
 }
 
-inline const NGLayoutResult* LayoutInflow(const NGConstraintSpace& space,
-                                          const NGBreakToken* break_token,
-                                          const NGEarlyBreak* early_break,
-                                          NGLayoutInputNode* node,
-                                          NGInlineChildLayoutContext* context) {
+inline scoped_refptr<const NGLayoutResult> LayoutInflow(
+    const NGConstraintSpace& space,
+    const NGBreakToken* break_token,
+    const NGEarlyBreak* early_break,
+    NGLayoutInputNode* node,
+    NGInlineChildLayoutContext* context) {
   if (auto* inline_node = DynamicTo<NGInlineNode>(node))
     return inline_node->Layout(space, break_token, context);
   return LayoutBlockChild(space, break_token, early_break,
@@ -414,8 +416,8 @@
   return {inline_offset, LayoutUnit()};
 }
 
-const NGLayoutResult* NGBlockLayoutAlgorithm::Layout() {
-  const NGLayoutResult* result = nullptr;
+scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
+  scoped_refptr<const NGLayoutResult> result;
   // Inline children require an inline child layout context to be
   // passed between siblings. We want to stack-allocate that one, but
   // only on demand, as it's quite big.
@@ -442,21 +444,22 @@
   }
 }
 
-NOINLINE const NGLayoutResult*
+NOINLINE scoped_refptr<const NGLayoutResult>
 NGBlockLayoutAlgorithm::LayoutWithInlineChildLayoutContext(
     const NGLayoutInputNode& first_child) {
   NGInlineChildLayoutContext context;
   return LayoutWithItemsBuilder(To<NGInlineNode>(first_child), &context);
 }
 
-NOINLINE const NGLayoutResult* NGBlockLayoutAlgorithm::LayoutWithItemsBuilder(
+NOINLINE scoped_refptr<const NGLayoutResult>
+NGBlockLayoutAlgorithm::LayoutWithItemsBuilder(
     const NGInlineNode& first_child,
     NGInlineChildLayoutContext* context) {
   NGFragmentItemsBuilder items_builder(
       first_child, container_builder_.GetWritingDirection());
   container_builder_.SetItemsBuilder(&items_builder);
   context->SetItemsBuilder(&items_builder);
-  const NGLayoutResult* result = Layout(context);
+  scoped_refptr<const NGLayoutResult> result = Layout(context);
   // Ensure stack-allocated |NGFragmentItemsBuilder| is not used anymore.
   // TODO(kojii): Revisit when the storage of |NGFragmentItemsBuilder| is
   // finalized.
@@ -465,7 +468,7 @@
   return result;
 }
 
-NOINLINE const NGLayoutResult*
+NOINLINE scoped_refptr<const NGLayoutResult>
 NGBlockLayoutAlgorithm::RelayoutIgnoringLineClamp() {
   NGLayoutAlgorithmParams params(Node(),
                                  container_builder_.InitialFragmentGeometry(),
@@ -478,7 +481,7 @@
   return algorithm_ignoring_line_clamp.Layout();
 }
 
-inline const NGLayoutResult* NGBlockLayoutAlgorithm::Layout(
+inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
     NGInlineChildLayoutContext* inline_child_layout_context) {
   if (ConstraintSpace().IsLegacyTableCell())
     container_builder_.AdjustBorderScrollbarPaddingForTableCell();
@@ -589,7 +592,7 @@
   // Try to reuse line box fragments from cached fragments if possible.
   // When possible, this adds fragments to |container_builder_| and update
   // |previous_inflow_position| and |BreakToken()|.
-  const NGInlineBreakToken* previous_inline_break_token = nullptr;
+  scoped_refptr<const NGInlineBreakToken> previous_inline_break_token;
 
   NGBlockChildIterator child_iterator(Node().FirstChild(), BreakToken());
 
@@ -603,7 +606,7 @@
   NGBlockNode placeholder_child(nullptr);
   for (auto entry = child_iterator.NextChild();
        NGLayoutInputNode child = entry.node;
-       entry = child_iterator.NextChild(previous_inline_break_token)) {
+       entry = child_iterator.NextChild(previous_inline_break_token.get())) {
     const NGBreakToken* child_break_token = entry.token;
 
     if (child.IsOutOfFlowPositioned()) {
@@ -713,7 +716,7 @@
         NGLayoutResult::kNeedsRelayoutWithNoForcedTruncateAtLineClamp);
   }
 
-  if (!child_iterator.NextChild(previous_inline_break_token).node) {
+  if (!child_iterator.NextChild(previous_inline_break_token.get()).node) {
     // We've gone through all the children. This doesn't necessarily mean that
     // we're done fragmenting, as there may be parallel flows [1] (visible
     // overflow) still needing more space than what the current fragmentainer
@@ -736,7 +739,7 @@
   return FinishLayout(&previous_inflow_position, inline_child_layout_context);
 }
 
-const NGLayoutResult* NGBlockLayoutAlgorithm::FinishLayout(
+scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::FinishLayout(
     NGPreviousInflowPosition* previous_inflow_position,
     NGInlineChildLayoutContext* inline_child_layout_context) {
   LogicalSize border_box_size = container_builder_.InitialBorderBoxSize();
@@ -969,7 +972,7 @@
 bool NGBlockLayoutAlgorithm::TryReuseFragmentsFromCache(
     NGInlineNode inline_node,
     NGPreviousInflowPosition* previous_inflow_position,
-    const NGInlineBreakToken** inline_break_token_out) {
+    scoped_refptr<const NGInlineBreakToken>* inline_break_token_out) {
   DCHECK(previous_result_);
   DCHECK(!inline_node.IsEmptyInline());
   DCHECK(container_builder_.BfcBlockOffset());
@@ -1136,15 +1139,15 @@
       abort_when_bfc_block_offset_updated_ = true;
   }
 
-  NGPositionedFloat* positioned_float =
+  NGPositionedFloat positioned_float =
       PositionFloat(&unpositioned_float, &exclusion_space_);
 
-  if (positioned_float->need_break_before) {
+  if (positioned_float.need_break_before) {
     DCHECK(ConstraintSpace().HasBlockFragmentation());
     LayoutUnit fragmentainer_block_offset =
         ConstraintSpace().FragmentainerOffsetAtBfc() +
-        positioned_float->bfc_offset.block_offset;
-    BreakBeforeChild(ConstraintSpace(), child, *positioned_float->layout_result,
+        positioned_float.bfc_offset.block_offset;
+    BreakBeforeChild(ConstraintSpace(), child, *positioned_float.layout_result,
                      fragmentainer_block_offset,
                      /* appeal */ base::nullopt,
                      /* is_forced_break */ false, &container_builder_);
@@ -1155,14 +1158,13 @@
     return;
   }
 
-  DCHECK_EQ(positioned_float->layout_result->Status(),
-            NGLayoutResult::kSuccess);
+  DCHECK_EQ(positioned_float.layout_result->Status(), NGLayoutResult::kSuccess);
 
   // TODO(mstensho): There should be a class A breakpoint between a float and
   // another float, and also between a float and an in-flow block.
 
   const NGPhysicalFragment& physical_fragment =
-      positioned_float->layout_result->PhysicalFragment();
+      positioned_float.layout_result->PhysicalFragment();
   LayoutUnit float_inline_size =
       NGFragment(ConstraintSpace().GetWritingDirection(), physical_fragment)
           .InlineSize();
@@ -1172,11 +1174,10 @@
                                 ConstraintSpace().ExpectedBfcBlockOffset())};
 
   LogicalOffset logical_offset = LogicalFromBfcOffsets(
-      positioned_float->bfc_offset, bfc_offset, float_inline_size,
+      positioned_float.bfc_offset, bfc_offset, float_inline_size,
       container_builder_.InlineSize(), ConstraintSpace().Direction());
 
-  container_builder_.AddResult(*positioned_float->layout_result,
-                               logical_offset);
+  container_builder_.AddResult(*positioned_float.layout_result, logical_offset);
 }
 
 NGLayoutResult::EStatus NGBlockLayoutAlgorithm::HandleNewFormattingContext(
@@ -1293,10 +1294,11 @@
                           !child_margin_got_separated &&
                           child_determined_bfc_offset;
   NGBfcOffset child_bfc_offset;
-  const NGLayoutResult* layout_result = LayoutNewFormattingContext(
-      child, child_break_token, child_data,
-      {child_origin_line_offset, child_bfc_offset_estimate}, abort_if_cleared,
-      &child_bfc_offset);
+  scoped_refptr<const NGLayoutResult> layout_result =
+      LayoutNewFormattingContext(
+          child, child_break_token, child_data,
+          {child_origin_line_offset, child_bfc_offset_estimate},
+          abort_if_cleared, &child_bfc_offset);
 
   if (!layout_result) {
     DCHECK(abort_if_cleared);
@@ -1406,7 +1408,8 @@
   return NGLayoutResult::kSuccess;
 }
 
-const NGLayoutResult* NGBlockLayoutAlgorithm::LayoutNewFormattingContext(
+scoped_refptr<const NGLayoutResult>
+NGBlockLayoutAlgorithm::LayoutNewFormattingContext(
     NGLayoutInputNode child,
     const NGBreakToken* child_break_token,
     const NGInflowChildData& child_data,
@@ -1501,7 +1504,7 @@
     // exclusion space.
     DCHECK(child_space.ExclusionSpace().IsEmpty());
 
-    const NGLayoutResult* layout_result = LayoutBlockChild(
+    scoped_refptr<const NGLayoutResult> layout_result = LayoutBlockChild(
         child_space, child_break_token, early_break_, &To<NGBlockNode>(child));
 
     // Since this child establishes a new formatting context, no exclusion space
@@ -1569,7 +1572,7 @@
     const NGBreakToken* child_break_token,
     NGPreviousInflowPosition* previous_inflow_position,
     NGInlineChildLayoutContext* inline_child_layout_context,
-    const NGInlineBreakToken** previous_inline_break_token) {
+    scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token) {
   DCHECK(child);
   DCHECK(!child.IsFloating());
   DCHECK(!child.IsOutOfFlowPositioned());
@@ -1632,7 +1635,7 @@
       child, child_data, ChildAvailableSize(), /* is_new_fc */ false,
       forced_bfc_block_offset, has_clearance_past_adjoining_floats,
       previous_inflow_position->block_end_annotation_space);
-  const NGLayoutResult* layout_result =
+  scoped_refptr<const NGLayoutResult> layout_result =
       LayoutInflow(child_space, child_break_token, early_break_, &child,
                    inline_child_layout_context);
 
@@ -1651,11 +1654,11 @@
     const NGBreakToken* child_break_token,
     const NGConstraintSpace& child_space,
     bool has_clearance_past_adjoining_floats,
-    const NGLayoutResult* layout_result,
+    scoped_refptr<const NGLayoutResult> layout_result,
     NGInflowChildData* child_data,
     NGPreviousInflowPosition* previous_inflow_position,
     NGInlineChildLayoutContext* inline_child_layout_context,
-    const NGInlineBreakToken** previous_inline_break_token) {
+    scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token) {
   base::Optional<LayoutUnit> child_bfc_block_offset =
       layout_result->BfcBlockOffset();
 
@@ -2273,8 +2276,8 @@
                                  std::min(line_count, int(Style().Orphans())));
         }
         // We need to layout again, and stop at the right line number.
-        const NGEarlyBreak* breakpoint =
-            MakeGarbageCollected<NGEarlyBreak>(line_number);
+        scoped_refptr<const NGEarlyBreak> breakpoint =
+            base::AdoptRef(new NGEarlyBreak(line_number));
         container_builder_.SetEarlyBreak(breakpoint, kBreakAppealPerfect);
         return NGBreakStatus::kNeedsEarlierBreak;
       }
@@ -2470,8 +2473,8 @@
     appeal = kBreakAppealViolatingOrphansAndWidows;
   }
   if (container_builder_.BreakAppeal() <= appeal) {
-    const NGEarlyBreak* breakpoint =
-        MakeGarbageCollected<NGEarlyBreak>(line_number);
+    scoped_refptr<const NGEarlyBreak> breakpoint =
+        base::AdoptRef(new NGEarlyBreak(line_number));
     container_builder_.SetEarlyBreak(breakpoint, appeal);
   }
 }
@@ -2842,7 +2845,7 @@
     // now because authors cannot style list-markers currently. If we want to
     // support `::marker` pseudo, we need to create ConstraintSpace for marker
     // separately.
-    const NGLayoutResult* marker_layout_result =
+    scoped_refptr<const NGLayoutResult> marker_layout_result =
         list_marker.Layout(space, container_builder_.Style(), baseline_type);
     DCHECK(marker_layout_result);
     // If the BFC block-offset of li is still not resolved, resolved it now.
@@ -2881,7 +2884,7 @@
   const NGConstraintSpace& space = ConstraintSpace();
   FontBaseline baseline_type = Style().GetFontBaseline();
   // Layout the list marker.
-  const NGLayoutResult* marker_layout_result =
+  scoped_refptr<const NGLayoutResult> marker_layout_result =
       list_marker.Layout(space, container_builder_.Style(), baseline_type);
   DCHECK(marker_layout_result);
   // If the BFC block-offset of li is still not resolved, resolve it now.
@@ -2911,11 +2914,11 @@
 void NGBlockLayoutAlgorithm::HandleRubyText(NGBlockNode ruby_text_child) {
   DCHECK(Node().IsRubyRun());
 
-  const NGBlockBreakToken* break_token = nullptr;
+  scoped_refptr<const NGBlockBreakToken> break_token;
   if (const auto* token = BreakToken()) {
-    for (const auto& child_token : token->ChildBreakTokens()) {
+    for (const auto* child_token : token->ChildBreakTokens()) {
       if (child_token->InputNode() == ruby_text_child) {
-        break_token = To<NGBlockBreakToken>(child_token.Get());
+        break_token = To<NGBlockBreakToken>(child_token);
         break;
       }
     }
@@ -2930,8 +2933,8 @@
                             rt_style.GetWritingMode()))
     builder.SetStretchInlineSizeIfAuto(true);
 
-  const NGLayoutResult* result =
-      ruby_text_child.Layout(builder.ToConstraintSpace(), break_token);
+  scoped_refptr<const NGLayoutResult> result =
+      ruby_text_child.Layout(builder.ToConstraintSpace(), break_token.get());
 
   LayoutUnit ruby_text_box_top;
   const NGPhysicalBoxFragment& ruby_text_fragment =
@@ -3037,7 +3040,7 @@
                        /* child_break_token */ nullptr, is_new_fc),
       available_size, is_new_fc);
 
-  const NGLayoutResult* result = placeholder.Layout(space);
+  scoped_refptr<const NGLayoutResult> result = placeholder.Layout(space);
   LogicalOffset offset = BorderScrollbarPadding().StartOffset();
   if (Node().IsTextArea()) {
     container_builder_.AddResult(*result, offset);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
index 026bf05..8ff7e88 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
@@ -63,22 +63,22 @@
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override;
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 
  private:
-  NOINLINE const NGLayoutResult* LayoutWithInlineChildLayoutContext(
-      const NGLayoutInputNode& first_child);
-  NOINLINE const NGLayoutResult* LayoutWithItemsBuilder(
+  NOINLINE scoped_refptr<const NGLayoutResult>
+  LayoutWithInlineChildLayoutContext(const NGLayoutInputNode& first_child);
+  NOINLINE scoped_refptr<const NGLayoutResult> LayoutWithItemsBuilder(
       const NGInlineNode& first_child,
       NGInlineChildLayoutContext* context);
 
-  NOINLINE const NGLayoutResult* RelayoutIgnoringLineClamp();
+  NOINLINE scoped_refptr<const NGLayoutResult> RelayoutIgnoringLineClamp();
 
-  inline const NGLayoutResult* Layout(
+  inline scoped_refptr<const NGLayoutResult> Layout(
       NGInlineChildLayoutContext* inline_child_layout_context);
 
-  const NGLayoutResult* FinishLayout(NGPreviousInflowPosition*,
-                                     NGInlineChildLayoutContext*);
+  scoped_refptr<const NGLayoutResult> FinishLayout(NGPreviousInflowPosition*,
+                                                   NGInlineChildLayoutContext*);
 
   // Return the BFC block offset of this block.
   LayoutUnit BfcBlockOffset() const {
@@ -148,7 +148,7 @@
   bool TryReuseFragmentsFromCache(
       NGInlineNode child,
       NGPreviousInflowPosition*,
-      const NGInlineBreakToken** inline_break_token_out);
+      scoped_refptr<const NGInlineBreakToken>* inline_break_token_out);
 
   void HandleOutOfFlowPositioned(const NGPreviousInflowPosition&, NGBlockNode);
   void HandleFloat(const NGPreviousInflowPosition&,
@@ -179,7 +179,7 @@
 
   // Performs the actual layout of a new formatting context. This may be called
   // multiple times from HandleNewFormattingContext.
-  const NGLayoutResult* LayoutNewFormattingContext(
+  scoped_refptr<const NGLayoutResult> LayoutNewFormattingContext(
       NGLayoutInputNode child,
       const NGBreakToken* child_break_token,
       const NGInflowChildData&,
@@ -195,18 +195,18 @@
       const NGBreakToken* child_break_token,
       NGPreviousInflowPosition*,
       NGInlineChildLayoutContext*,
-      const NGInlineBreakToken** previous_inline_break_token);
+      scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token);
 
   NGLayoutResult::EStatus FinishInflow(
       NGLayoutInputNode child,
       const NGBreakToken* child_break_token,
       const NGConstraintSpace&,
       bool has_clearance_past_adjoining_floats,
-      const NGLayoutResult*,
+      scoped_refptr<const NGLayoutResult>,
       NGInflowChildData*,
       NGPreviousInflowPosition*,
       NGInlineChildLayoutContext*,
-      const NGInlineBreakToken** previous_inline_break_token);
+      scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token);
 
   // Performs any final adjustments for table-cells.
   void FinalizeForTableCell(LayoutUnit unconstrained_intrinsic_block_size);
@@ -369,7 +369,7 @@
   LogicalSize child_percentage_size_;
   LogicalSize replaced_child_percentage_size_;
 
-  const NGLayoutResult* previous_result_ = nullptr;
+  scoped_refptr<const NGLayoutResult> previous_result_;
 
   // Intrinsic block size based on child layout and containment.
   LayoutUnit intrinsic_block_size_;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
index 81571d2..928eda6 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -47,8 +47,9 @@
     return algorithm.ComputeMinMaxSizes(MinMaxSizesFloatInput()).sizes;
   }
 
-  const NGLayoutResult* RunCachedLayoutResult(const NGConstraintSpace& space,
-                                              const NGBlockNode& node) {
+  scoped_refptr<const NGLayoutResult> RunCachedLayoutResult(
+      const NGConstraintSpace& space,
+      const NGBlockNode& node) {
     NGLayoutCacheStatus cache_status;
     base::Optional<NGFragmentGeometry> initial_fragment_geometry;
     return To<LayoutBlockFlow>(node.GetLayoutBox())
@@ -65,9 +66,9 @@
     return fragment->DumpFragmentTree(flags);
   }
 
-  ComputedStyle* MutableStyleForElement(Element* element) {
+  scoped_refptr<ComputedStyle> MutableStyleForElement(Element* element) {
     DCHECK(element->GetLayoutObject());
-    ComputedStyle* mutable_style =
+    scoped_refptr<ComputedStyle> mutable_style =
         ComputedStyle::Clone(element->GetLayoutObject()->StyleRef());
     element->GetLayoutObject()->SetModifiedStyleOutsideStyleRecalc(
         mutable_style, LayoutObject::ApplyStyleChanges::kNo);
@@ -86,7 +87,8 @@
 
   NGBlockNode box(GetLayoutBoxByElementId("box"));
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(box, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(box, space);
 
   EXPECT_EQ(PhysicalSize(30, 40), fragment->Size());
 }
@@ -106,26 +108,26 @@
   auto* block_flow = To<LayoutBlockFlow>(GetLayoutObjectByElementId("box"));
   NGBlockNode node(block_flow);
 
-  const NGLayoutResult* result = node.Layout(space, nullptr);
+  scoped_refptr<const NGLayoutResult> result(node.Layout(space, nullptr));
   EXPECT_EQ(PhysicalSize(30, 40), result->PhysicalFragment().Size());
 
   // Test pointer-equal constraint space.
   result = RunCachedLayoutResult(space, node);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   // Test identical, but not pointer-equal, constraint space.
   space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(100), LayoutUnit(100)));
   result = RunCachedLayoutResult(space, node);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   // Test different constraint space.
   space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(200), LayoutUnit(100)));
   result = RunCachedLayoutResult(space, node);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   // Test a different constraint space that will actually result in a different
   // sized fragment.
@@ -133,12 +135,12 @@
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(200), LayoutUnit(200)));
   result = RunCachedLayoutResult(space, node);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 
   // Test layout invalidation
   block_flow->SetNeedsLayout("");
   result = RunCachedLayoutResult(space, node);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGBlockLayoutAlgorithmTest, MinInlineSizeCaching) {
@@ -153,26 +155,26 @@
   auto* block_flow = To<LayoutBlockFlow>(GetLayoutObjectByElementId("box"));
   NGBlockNode node(block_flow);
 
-  const NGLayoutResult* result = node.Layout(space, nullptr);
+  scoped_refptr<const NGLayoutResult> result(node.Layout(space, nullptr));
   EXPECT_EQ(PhysicalSize(30, 40), result->PhysicalFragment().Size());
 
   // Test pointer-equal constraint space.
   result = RunCachedLayoutResult(space, node);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   // Test identical, but not pointer-equal, constraint space.
   space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(100), LayoutUnit(100)));
   result = RunCachedLayoutResult(space, node);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   // Test different constraint space.
   space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(100), LayoutUnit(200)));
   result = RunCachedLayoutResult(space, node);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   // Test a different constraint space that will actually result in a different
   // size.
@@ -180,7 +182,7 @@
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(200), LayoutUnit(100)));
   result = RunCachedLayoutResult(space, node);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGBlockLayoutAlgorithmTest, PercentageBlockSizeQuirkDescendantsCaching) {
@@ -234,14 +236,15 @@
   NGConstraintSpace space200 =
       create_space(LogicalSize(LayoutUnit(100), LayoutUnit(200)));
 
-  auto run_test = [&](auto id) -> const NGLayoutResult* {
+  auto run_test = [&](auto id) -> scoped_refptr<const NGLayoutResult> {
     // Grab the box under test.
     auto* box = To<LayoutBlockFlow>(GetLayoutObjectByElementId(id));
     NGBlockNode node(box);
 
     // Check that we have a cache hit with space100.
-    const NGLayoutResult* result = RunCachedLayoutResult(space100, node);
-    EXPECT_NE(result, nullptr);
+    scoped_refptr<const NGLayoutResult> result =
+        RunCachedLayoutResult(space100, node);
+    EXPECT_NE(result.get(), nullptr);
 
     // Return the result of the cache with space200.
     return RunCachedLayoutResult(space200, node);
@@ -299,12 +302,12 @@
       create_space(LogicalSize(LayoutUnit(300), LayoutUnit(100)),
                    NGBfcOffset(LayoutUnit(50), LayoutUnit()));
 
-  const NGLayoutResult* result = nullptr;
+  scoped_refptr<const NGLayoutResult> result;
   auto* box1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("box1"));
 
   // Ensure we get a cached layout result, even if our BFC line-offset changed.
   result = RunCachedLayoutResult(space200, NGBlockNode(box1));
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 // Verifies that two children are laid out with the correct size and position.
@@ -327,7 +330,7 @@
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(100), kIndefiniteSize));
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       RunBlockLayoutAlgorithm(container, space);
 
   EXPECT_EQ(LayoutUnit(kWidth), fragment->Size().width);
@@ -371,7 +374,7 @@
   NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(500), LayoutUnit(500)));
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       RunBlockLayoutAlgorithm(container, space);
 
   const NGLink& child = fragment->Children()[0];
@@ -424,7 +427,7 @@
 
   // ** Run LayoutNG algorithm **
   NGConstraintSpace space;
-  const NGPhysicalBoxFragment* fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement(
       GetDocument().getElementsByTagName("html")->item(0));
   ASSERT_EQ(fragment->Children().size(), 1UL);
@@ -506,7 +509,7 @@
 
   // ** Run LayoutNG algorithm **
   NGConstraintSpace space;
-  const NGPhysicalBoxFragment* fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement(
       GetDocument().getElementsByTagName("html")->item(0));
 
@@ -561,10 +564,10 @@
       </div>
     )HTML");
 
-  const NGPhysicalBoxFragment* body_fragment = nullptr;
-  const NGPhysicalBoxFragment* container_fragment = nullptr;
-  const NGPhysicalBoxFragment* child_fragment = nullptr;
-  const NGPhysicalBoxFragment* fragment = nullptr;
+  const NGPhysicalBoxFragment* body_fragment;
+  const NGPhysicalBoxFragment* container_fragment;
+  const NGPhysicalBoxFragment* child_fragment;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   auto run_test = [&](const Length& container_height) {
     Element* container = GetDocument().getElementById("container");
     MutableStyleForElement(container)->SetHeight(container_height);
@@ -616,7 +619,7 @@
   PhysicalOffset body_offset;
   PhysicalOffset container_offset;
   PhysicalOffset child_offset;
-  const NGPhysicalBoxFragment* fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   auto run_test = [&](const Length& container_padding_top) {
     Element* container = GetDocument().getElementById("container");
     MutableStyleForElement(container)->SetPaddingTop(container_padding_top);
@@ -683,7 +686,7 @@
         <div id='horizontal'></div>
       </div>
     )HTML");
-  const NGPhysicalBoxFragment* fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
       GetDocument().getElementsByTagName("html")->item(0));
 
@@ -737,7 +740,7 @@
       </style>
       <p>Some text</p>
     )HTML");
-  const NGPhysicalBoxFragment* html_fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> html_fragment;
   std::tie(html_fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
       GetDocument().getElementsByTagName("html")->item(0));
 
@@ -781,7 +784,7 @@
   NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(500), LayoutUnit(500)));
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       RunBlockLayoutAlgorithm(container, space);
 
   ASSERT_EQ(fragment->Children().size(), 2UL);
@@ -828,11 +831,11 @@
     <div id="inflow"></div>
   )HTML");
 
-  const NGPhysicalBoxFragment* fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
       GetDocument().getElementsByTagName("html")->item(0));
 
-  FragmentChildIterator iterator(fragment);
+  FragmentChildIterator iterator(fragment.get());
 
   // body
   PhysicalOffset offset;
@@ -898,6 +901,7 @@
   const LayoutNGBlockFlow* zero;
   const LayoutNGBlockFlow* abs;
   const LayoutNGBlockFlow* inflow;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   auto run_test = [&](const Length& zero_top_margin_bottom,
                       const Length& zero_inner_margin_top,
                       const Length& zero_inner_margin_bottom,
@@ -908,7 +912,8 @@
     MutableStyleForElement(zero_top)->SetMarginBottom(zero_top_margin_bottom);
     zero_top->GetLayoutObject()->SetNeedsLayout("");
     Element* zero_inner = GetDocument().getElementById("zero-inner");
-    ComputedStyle* zero_inner_style = MutableStyleForElement(zero_inner);
+    scoped_refptr<ComputedStyle> zero_inner_style =
+        MutableStyleForElement(zero_inner);
     zero_inner_style->SetMarginTop(zero_inner_margin_top);
     zero_inner_style->SetMarginBottom(zero_inner_margin_bottom);
     zero_inner->GetLayoutObject()->SetNeedsLayout("");
@@ -1028,7 +1033,7 @@
       </div>
     )HTML");
 
-  const NGPhysicalBoxFragment* fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   std::tie(fragment, std::ignore) =
       RunBlockLayoutAlgorithmForElement(GetElementById("container"));
 
@@ -1039,7 +1044,7 @@
     offset:125,20 size:50x20
     offset:150,40 size:50x20
 )DUMP";
-  EXPECT_EQ(expectation, DumpFragmentTree(fragment));
+  EXPECT_EQ(expectation, DumpFragmentTree(fragment.get()));
 }
 
 // Verifies that a box's size includes its borders and padding, and that
@@ -1078,7 +1083,7 @@
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(1000), kIndefiniteSize));
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       RunBlockLayoutAlgorithm(container, space);
 
   ASSERT_EQ(fragment->Children().size(), 1UL);
@@ -1114,7 +1119,7 @@
   NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(100), kIndefiniteSize));
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       RunBlockLayoutAlgorithm(container, space);
 
   EXPECT_EQ(LayoutUnit(kWidth + kPaddingLeft), fragment->Size().width);
@@ -1146,7 +1151,7 @@
   NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(100), kIndefiniteSize));
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       RunBlockLayoutAlgorithm(container, space);
 
   EXPECT_EQ(LayoutUnit(kWidth + kPaddingLeft), fragment->Size().width);
@@ -1206,7 +1211,7 @@
 
   // ** Run LayoutNG algorithm **
   NGConstraintSpace space;
-  const NGPhysicalBoxFragment* fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement(
       GetDocument().getElementsByTagName("html")->item(0));
 
@@ -1311,7 +1316,7 @@
 
   // ** Run LayoutNG algorithm **
   NGConstraintSpace space;
-  const NGPhysicalBoxFragment* fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement(
       GetDocument().getElementsByTagName("html")->item(0));
 
@@ -1435,7 +1440,7 @@
   PhysicalOffset container_offset;
   PhysicalOffset block_offset;
   PhysicalOffset adjoining_clearance_offset;
-  const NGPhysicalBoxFragment* fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   auto run_with_clearance = [&](EClear clear_value) {
     Element* el_with_clear = GetDocument().getElementById("clearance");
     MutableStyleForElement(el_with_clear)->SetClear(clear_value);
@@ -1646,7 +1651,7 @@
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(100), kIndefiniteSize),
       /* stretch_inline_size_if_auto */ false);
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       RunBlockLayoutAlgorithm(container, space);
 
   EXPECT_EQ(LayoutUnit(kWidthChild2), fragment->Size().width);
@@ -1681,7 +1686,7 @@
     </div>
   )HTML");
 
-  const NGPhysicalBoxFragment* html_fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> html_fragment;
   std::tie(html_fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
       GetDocument().getElementsByTagName("html")->item(0));
   auto* body_fragment =
@@ -1749,7 +1754,7 @@
   )HTML");
 
   // Run LayoutNG algorithm.
-  const NGPhysicalBoxFragment* html_fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> html_fragment;
   std::tie(html_fragment, std::ignore) = RunBlockLayoutAlgorithmForElement(
       GetDocument().getElementsByTagName("html")->item(0));
   auto* body_fragment =
@@ -1799,7 +1804,8 @@
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
   // We should only have one 150x200 fragment with no fragmentation.
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(node, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(150, 200), fragment->Size());
   ASSERT_FALSE(fragment->BreakToken());
 }
@@ -1826,7 +1832,8 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(node, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(150, 200), fragment->Size());
   EXPECT_TRUE(fragment->BreakToken());
 
@@ -1869,11 +1876,12 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(node, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(150, 200), fragment->Size());
   EXPECT_TRUE(fragment->BreakToken());
 
-  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment));
+  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment.get()));
   PhysicalOffset offset;
   const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
   EXPECT_EQ(PhysicalSize(150, 180), child->Size());
@@ -1885,7 +1893,7 @@
   EXPECT_EQ(PhysicalSize(150, 140), fragment->Size());
   ASSERT_FALSE(fragment->BreakToken());
 
-  iterator.SetParent(To<NGPhysicalBoxFragment>(fragment));
+  iterator.SetParent(To<NGPhysicalBoxFragment>(fragment.get()));
   child = iterator.NextChild(&offset);
   EXPECT_EQ(PhysicalSize(150, 20), child->Size());
   EXPECT_EQ(PhysicalOffset(0, 0), offset);
@@ -1934,11 +1942,12 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(node, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(150, 200), fragment->Size());
   EXPECT_TRUE(fragment->BreakToken());
 
-  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment));
+  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment.get()));
   PhysicalOffset offset;
   const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
   EXPECT_EQ(PhysicalSize(150, 180), child->Size());
@@ -1950,7 +1959,7 @@
   EXPECT_EQ(PhysicalSize(150, 140), fragment->Size());
   ASSERT_FALSE(fragment->BreakToken());
 
-  iterator.SetParent(To<NGPhysicalBoxFragment>(fragment));
+  iterator.SetParent(To<NGPhysicalBoxFragment>(fragment.get()));
   child = iterator.NextChild(&offset);
   EXPECT_EQ(PhysicalSize(150, 20), child->Size());
   EXPECT_EQ(PhysicalOffset(0, 0), offset);
@@ -1997,11 +2006,12 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(node, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(150, 70), fragment->Size());
   EXPECT_TRUE(fragment->BreakToken());
 
-  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment));
+  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment.get()));
   PhysicalOffset offset;
   const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
   EXPECT_EQ(PhysicalSize(150, 180), child->Size());
@@ -2013,7 +2023,7 @@
   EXPECT_EQ(PhysicalSize(150, 0), fragment->Size());
   ASSERT_FALSE(fragment->BreakToken());
 
-  iterator.SetParent(To<NGPhysicalBoxFragment>(fragment));
+  iterator.SetParent(To<NGPhysicalBoxFragment>(fragment.get()));
   child = iterator.NextChild(&offset);
   EXPECT_EQ(PhysicalSize(150, 20), child->Size());
   EXPECT_EQ(PhysicalOffset(0, 0), offset);
@@ -2063,11 +2073,12 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(node, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(150, 50), fragment->Size());
   EXPECT_TRUE(fragment->BreakToken());
 
-  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment));
+  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment.get()));
 
   // First fragment of float1.
   PhysicalOffset offset;
@@ -2090,7 +2101,7 @@
   EXPECT_EQ(PhysicalSize(150, 0), fragment->Size());
   ASSERT_FALSE(fragment->BreakToken());
 
-  iterator.SetParent(To<NGPhysicalBoxFragment>(fragment));
+  iterator.SetParent(To<NGPhysicalBoxFragment>(fragment.get()));
 
   // Second fragment of float1.
   child = iterator.NextChild(&offset);
@@ -2144,11 +2155,12 @@
 
   AdvanceToLayoutPhase();
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(node, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(150, 60), fragment->Size());
   ASSERT_FALSE(fragment->BreakToken());
 
-  const auto* float2 = fragment->Children()[1].fragment.Get();
+  const auto* float2 = fragment->Children()[1].fragment;
 
   // float2 should only have one fragment.
   EXPECT_EQ(PhysicalSize(60, 200), float2->Size());
@@ -2192,11 +2204,12 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(node, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(150, 50), fragment->Size());
   EXPECT_TRUE(fragment->BreakToken());
 
-  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment));
+  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment.get()));
   const auto* child = iterator.NextChild();
 
   // First fragment of float.
@@ -2216,7 +2229,7 @@
   EXPECT_EQ(PhysicalSize(150, 0), fragment->Size());
   ASSERT_FALSE(fragment->BreakToken());
 
-  iterator.SetParent(To<NGPhysicalBoxFragment>(fragment));
+  iterator.SetParent(To<NGPhysicalBoxFragment>(fragment.get()));
   child = iterator.NextChild();
 
   // Second fragment of float.
@@ -2256,7 +2269,7 @@
   PhysicalOffset body_offset;
   PhysicalOffset new_fc_offset;
 
-  const NGPhysicalBoxFragment* fragment = nullptr;
+  scoped_refptr<const NGPhysicalBoxFragment> fragment;
   auto run_test = [&](const Length& block_width) {
     Element* new_fc_block = GetDocument().getElementById("new-fc");
     MutableStyleForElement(new_fc_block)->SetWidth(block_width);
@@ -2315,10 +2328,11 @@
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(1000), kIndefiniteSize));
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(node, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(200, 150), fragment->Size());
 
-  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment));
+  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment.get()));
 
   PhysicalOffset offset;
   const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
@@ -2352,10 +2366,11 @@
       /* stretch_inline_size_if_auto */ true,
       /* is_new_formatting_context */ true);
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(node, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(200, 10), fragment->Size());
 
-  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment));
+  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment.get()));
 
   PhysicalOffset offset;
   const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
@@ -2391,10 +2406,11 @@
       /* stretch_inline_size_if_auto */ true,
       /* is_new_formatting_context */ true);
 
-  const NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm(node, space);
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
+      RunBlockLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(200, 10), fragment->Size());
 
-  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment));
+  FragmentChildIterator iterator(To<NGPhysicalBoxFragment>(fragment.get()));
 
   PhysicalOffset offset;
   const NGPhysicalBoxFragment* child = iterator.NextChild(&offset);
@@ -2464,7 +2480,7 @@
       To<LayoutBlockFlow>(GetLayoutObjectByElementId("target"));
   NGBlockNode target(target_block_flow);
   ASSERT_TRUE(target.UseBlockEndMarginEdgeForInlineBlockBaseline());
-  const NGPhysicalBoxFragment* before =
+  scoped_refptr<const NGPhysicalBoxFragment> before =
       To<NGPhysicalBoxFragment>(target_block_flow->GetPhysicalFragment(0));
   EXPECT_EQ(*before->LastBaseline(), LayoutUnit(200));
 
@@ -2473,7 +2489,7 @@
   outer_element->classList().Add("after");
   UpdateAllLifecyclePhasesForTest();
 
-  const NGPhysicalBoxFragment* after =
+  scoped_refptr<const NGPhysicalBoxFragment> after =
       To<NGPhysicalBoxFragment>(target_block_flow->GetPhysicalFragment(0));
   EXPECT_EQ(*after->LastBaseline(), LayoutUnit(400));
 }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
index ee673cea..cad79de 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -196,9 +196,9 @@
   }
 }
 
-inline const NGLayoutResult* LayoutWithAlgorithm(
+inline scoped_refptr<const NGLayoutResult> LayoutWithAlgorithm(
     const NGLayoutAlgorithmParams& params) {
-  const NGLayoutResult* result = nullptr;
+  scoped_refptr<const NGLayoutResult> result;
   DetermineAlgorithmAndRun(params,
                            [&result](NGLayoutAlgorithmOperations* algorithm) {
                              result = algorithm->Layout();
@@ -377,7 +377,7 @@
 
 }  // namespace
 
-const NGLayoutResult* NGBlockNode::Layout(
+scoped_refptr<const NGLayoutResult> NGBlockNode::Layout(
     const NGConstraintSpace& constraint_space,
     const NGBlockBreakToken* break_token,
     const NGEarlyBreak* early_break) const {
@@ -401,7 +401,7 @@
   // (calculating that isn't necessarily very cheap). So, start off without it.
   base::Optional<NGFragmentGeometry> fragment_geometry;
 
-  const NGLayoutResult* layout_result =
+  scoped_refptr<const NGLayoutResult> layout_result =
       box_->CachedLayoutResult(constraint_space, break_token, early_break,
                                &fragment_geometry, &cache_status);
   if (UNLIKELY(DevtoolsReadonlyLayoutScope::InDevtoolsLayout())) {
@@ -467,14 +467,14 @@
   NGLayoutAlgorithmParams params(*this, *fragment_geometry, constraint_space,
                                  break_token, early_break);
 
-  auto* block_flow = DynamicTo<LayoutBlockFlow>(box_.Get());
+  auto* block_flow = DynamicTo<LayoutBlockFlow>(box_);
 
   // Try to perform "simplified" layout.
   if (cache_status == NGLayoutCacheStatus::kNeedsSimplifiedLayout &&
       !GetFlowThread(block_flow)) {
     DCHECK(layout_result);
 #if DCHECK_IS_ON()
-    const NGLayoutResult* previous_result = layout_result;
+    scoped_refptr<const NGLayoutResult> previous_result = layout_result;
 #endif
 
     // A child may have changed size while performing "simplified" layout (it
@@ -490,7 +490,7 @@
     }
 #endif
   } else if (cache_status == NGLayoutCacheStatus::kCanReuseLines) {
-    params.previous_result = layout_result;
+    params.previous_result = layout_result.get();
     layout_result = nullptr;
   } else {
     layout_result = nullptr;
@@ -536,10 +536,8 @@
 #if DCHECK_IS_ON()
       // Ensure turning on/off scrollbars only once at most, when we call
       // |LayoutWithAlgorithm| recursively.
-      DEFINE_STATIC_LOCAL(
-          Persistent<HeapHashSet<WeakMember<LayoutBox>>>, scrollbar_changed,
-          (MakeGarbageCollected<HeapHashSet<WeakMember<LayoutBox>>>()));
-      DCHECK(scrollbar_changed->insert(box_.Get()).is_new_entry);
+      DEFINE_STATIC_LOCAL(HashSet<LayoutBox*>, scrollbar_changed, ());
+      DCHECK(scrollbar_changed.insert(box_).is_new_entry);
 #endif
 
       // Scrollbar changes are hard to detect. Make sure everyone gets the
@@ -553,7 +551,7 @@
       FinishLayout(block_flow, constraint_space, break_token, layout_result);
 
 #if DCHECK_IS_ON()
-      scrollbar_changed->erase(box_);
+      scrollbar_changed.erase(box_);
 #endif
 
       scrollbars_after = ComputeScrollbars(constraint_space, *this);
@@ -578,9 +576,10 @@
   return layout_result;
 }
 
-const NGLayoutResult* NGBlockNode::SimplifiedLayout(
+scoped_refptr<const NGLayoutResult> NGBlockNode::SimplifiedLayout(
     const NGPhysicalFragment& previous_fragment) const {
-  const NGLayoutResult* previous_result = box_->GetCachedLayoutResult();
+  scoped_refptr<const NGLayoutResult> previous_result =
+      box_->GetCachedLayoutResult();
   DCHECK(previous_result);
 
   // We might be be trying to perform simplfied layout on a fragment in the
@@ -597,7 +596,8 @@
   // Perform layout on ourselves using the previous constraint space.
   const NGConstraintSpace space(
       previous_result->GetConstraintSpaceForCaching());
-  const NGLayoutResult* result = Layout(space, /* break_token */ nullptr);
+  scoped_refptr<const NGLayoutResult> result =
+      Layout(space, /* break_token */ nullptr);
 
   const auto& old_fragment =
       To<NGPhysicalBoxFragment>(previous_result->PhysicalFragment());
@@ -623,7 +623,8 @@
   return result;
 }
 
-const NGLayoutResult* NGBlockNode::CachedLayoutResultForOutOfFlowPositioned(
+scoped_refptr<const NGLayoutResult>
+NGBlockNode::CachedLayoutResultForOutOfFlowPositioned(
     LogicalSize container_content_size) const {
   DCHECK(IsOutOfFlowPositioned());
 
@@ -665,7 +666,7 @@
 }
 
 void NGBlockNode::PrepareForLayout() const {
-  auto* block = DynamicTo<LayoutBlock>(box_.Get());
+  auto* block = DynamicTo<LayoutBlock>(box_);
   if (block && block->IsScrollContainer()) {
     DCHECK(block->GetScrollableArea());
     if (block->GetScrollableArea()->ShouldPerformScrollAnchoring())
@@ -675,13 +676,14 @@
   // TODO(layoutng) Can UpdateMarkerTextIfNeeded call be moved
   // somewhere else? List items need up-to-date markers before layout.
   if (IsListItem())
-    To<LayoutNGListItem>(box_.Get())->UpdateMarkerTextIfNeeded();
+    To<LayoutNGListItem>(box_)->UpdateMarkerTextIfNeeded();
 }
 
-void NGBlockNode::FinishLayout(LayoutBlockFlow* block_flow,
-                               const NGConstraintSpace& constraint_space,
-                               const NGBlockBreakToken* break_token,
-                               const NGLayoutResult* layout_result) const {
+void NGBlockNode::FinishLayout(
+    LayoutBlockFlow* block_flow,
+    const NGConstraintSpace& constraint_space,
+    const NGBlockBreakToken* break_token,
+    scoped_refptr<const NGLayoutResult> layout_result) const {
   // If we abort layout and don't clear the cached layout-result, we can end
   // up in a state where the layout-object tree doesn't match fragment tree
   // referenced by this layout-result.
@@ -774,7 +776,7 @@
   // TODO(layoutng) Can UpdateMarkerTextIfNeeded call be moved
   // somewhere else? List items need up-to-date markers before layout.
   if (IsListItem())
-    To<LayoutNGListItem>(box_.Get())->UpdateMarkerTextIfNeeded();
+    To<LayoutNGListItem>(box_)->UpdateMarkerTextIfNeeded();
 
   bool is_orthogonal_flow_root =
       !IsParallelWritingMode(container_writing_mode, Style().GetWritingMode());
@@ -795,7 +797,8 @@
                                /* depends_on_block_constraints */ false);
     }
 
-    const NGLayoutResult* layout_result = Layout(constraint_space);
+    scoped_refptr<const NGLayoutResult> layout_result =
+        Layout(constraint_space);
     DCHECK_EQ(layout_result->Status(), NGLayoutResult::kSuccess);
     sizes = NGFragment({container_writing_mode, TextDirection::kLtr},
                        layout_result->PhysicalFragment())
@@ -916,9 +919,8 @@
       result.depends_on_block_constraints, &result.sizes);
 
   if (IsNGTableCell()) {
-    To<LayoutNGTableCell>(box_.Get())
-        ->SetIntrinsicLogicalWidthsBorderSizes(
-            constraint_space.TableCellBorders());
+    To<LayoutNGTableCell>(box_)->SetIntrinsicLogicalWidthsBorderSizes(
+        constraint_space.TableCellBorders());
   }
 
   // We report to our parent if we depend on the %-block-size if we used the
@@ -966,7 +968,7 @@
 }
 
 NGLayoutInputNode NGBlockNode::FirstChild() const {
-  auto* block = DynamicTo<LayoutBlock>(box_.Get());
+  auto* block = DynamicTo<LayoutBlock>(box_);
   if (UNLIKELY(!block))
     return NGBlockNode(box_->FirstChildBox());
   auto* child = GetLayoutObjectForFirstChildNode(block);
@@ -977,7 +979,7 @@
 
   NGInlineNode inline_node(To<LayoutBlockFlow>(block));
   if (!inline_node.IsBlockLevel())
-    return std::move(inline_node);
+    return inline_node;
 
   // At this point we have a node which is empty or only has floats and
   // OOF-positioned nodes. We treat all children as block-level, even though
@@ -1005,14 +1007,13 @@
 NGBlockNode NGBlockNode::GetRenderedLegend() const {
   if (!IsFieldsetContainer())
     return nullptr;
-  return NGBlockNode(
-      LayoutFieldset::FindInFlowLegend(*To<LayoutBlock>(box_.Get())));
+  return NGBlockNode(LayoutFieldset::FindInFlowLegend(*To<LayoutBlock>(box_)));
 }
 
 NGBlockNode NGBlockNode::GetFieldsetContent() const {
   if (!IsFieldsetContainer())
     return nullptr;
-  auto* child = GetLayoutObjectForFirstChildNode(To<LayoutBlock>(box_.Get()));
+  auto* child = GetLayoutObjectForFirstChildNode(To<LayoutBlock>(box_));
   if (!child)
     return nullptr;
   return NGBlockNode(To<LayoutBox>(child));
@@ -1107,7 +1108,7 @@
         constraint_space.PercentageResolutionInlineSizeForParentWritingMode());
   }
 
-  auto* block_flow = DynamicTo<LayoutBlockFlow>(box_.Get());
+  auto* block_flow = DynamicTo<LayoutBlockFlow>(box_);
   LayoutMultiColumnFlowThread* flow_thread = GetFlowThread(block_flow);
 
   // Position the children inside the box. We skip this if display-lock prevents
@@ -1140,7 +1141,7 @@
   if (UNLIKELY(!is_last_fragment))
     return;
 
-  LayoutBlock* block = DynamicTo<LayoutBlock>(box_.Get());
+  LayoutBlock* block = DynamicTo<LayoutBlock>(box_);
   bool needs_full_invalidation = false;
   if (LIKELY(block)) {
 #if DCHECK_IS_ON()
@@ -1251,8 +1252,7 @@
     const auto& child_break_tokens =
         previous_container_break_token->ChildBreakTokens();
     if (!child_break_tokens.empty()) {
-      const auto* token =
-          To<NGBlockBreakToken>(child_break_tokens.back().Get());
+      const auto* token = To<NGBlockBreakToken>(child_break_tokens.back());
       // We also create break tokens for spanners, so we need to check.
       if (token->InputNode() == *this) {
         previous_column_break_token = token;
@@ -1467,7 +1467,7 @@
 
 bool NGBlockNode::IsInlineFormattingContextRoot(
     NGLayoutInputNode* first_child_out) const {
-  if (const auto* block = DynamicTo<LayoutBlockFlow>(box_.Get())) {
+  if (const auto* block = DynamicTo<LayoutBlockFlow>(box_)) {
     if (!AreNGBlockFlowChildrenInline(block))
       return false;
     NGLayoutInputNode first_child = FirstChild();
@@ -1516,8 +1516,7 @@
 
   if (!ShouldApplySizeContainment()) {
     IntrinsicSizingInfo legacy_sizing_info;
-    To<LayoutReplaced>(box_.Get())
-        ->ComputeIntrinsicSizingInfo(legacy_sizing_info);
+    To<LayoutReplaced>(box_)->ComputeIntrinsicSizingInfo(legacy_sizing_info);
     if (!legacy_sizing_info.aspect_ratio.IsEmpty()) {
       return LogicalSize::AspectRatioFromFloatSize(
           legacy_sizing_info.aspect_ratio);
@@ -1553,7 +1552,7 @@
 
 bool NGBlockNode::IsCustomLayoutLoaded() const {
   DCHECK(box_->IsLayoutNGCustom());
-  return To<LayoutNGCustom>(box_.Get())->IsLoaded();
+  return To<LayoutNGCustom>(box_)->IsLoaded();
 }
 
 MathScriptType NGBlockNode::ScriptType() const {
@@ -1566,7 +1565,7 @@
   return To<MathMLRadicalElement>(GetDOMNode())->HasIndex();
 }
 
-const NGLayoutResult* NGBlockNode::LayoutAtomicInline(
+scoped_refptr<const NGLayoutResult> NGBlockNode::LayoutAtomicInline(
     const NGConstraintSpace& parent_constraint_space,
     const ComputedStyle& parent_style,
     bool use_first_line_style,
@@ -1587,20 +1586,20 @@
   builder.SetReplacedPercentageResolutionSize(
       parent_constraint_space.ReplacedPercentageResolutionSize());
   NGConstraintSpace constraint_space = builder.ToConstraintSpace();
-  const NGLayoutResult* result = Layout(constraint_space);
+  scoped_refptr<const NGLayoutResult> result = Layout(constraint_space);
   // TODO(kojii): Investigate why ClearNeedsLayout() isn't called automatically
   // when it's being laid out.
   GetLayoutBox()->ClearNeedsLayout();
   return result;
 }
 
-const NGLayoutResult* NGBlockNode::RunLegacyLayout(
+scoped_refptr<const NGLayoutResult> NGBlockNode::RunLegacyLayout(
     const NGConstraintSpace& constraint_space) const {
   // This is an exit-point from LayoutNG to the legacy engine. This means that
   // we need to be at a formatting context boundary, since NG and legacy don't
   // cooperate on e.g. margin collapsing.
   DCHECK(!box_->IsLayoutBlock() ||
-         To<LayoutBlock>(box_.Get())->CreatesNewFormattingContext());
+         To<LayoutBlock>(box_)->CreatesNewFormattingContext());
 
   // We cannot enter legacy layout for something fragmentable if we're inside an
   // NG block fragmentation context. LayoutNG and legacy block fragmentation
@@ -1608,7 +1607,8 @@
   DCHECK(!constraint_space.HasBlockFragmentation() ||
          box_->GetNGPaginationBreakability() == LayoutBox::kForbidBreaks);
 
-  const NGLayoutResult* layout_result = box_->GetCachedLayoutResult();
+  scoped_refptr<const NGLayoutResult> layout_result =
+      box_->GetCachedLayoutResult();
 
   if (UNLIKELY(DevtoolsReadonlyLayoutScope::InDevtoolsLayout())) {
     DCHECK(layout_result);
@@ -1706,10 +1706,10 @@
         constraint_space.PercentageResolutionSize() !=
             old_space.PercentageResolutionSize();
     if (needs_cached_result_update) {
-      layout_result = MakeGarbageCollected<NGLayoutResult>(
+      layout_result = base::AdoptRef(new NGLayoutResult(
           *layout_result, constraint_space, layout_result->EndMarginStrut(),
           layout_result->BfcLineOffset(), layout_result->BfcBlockOffset(),
-          LayoutUnit() /* block_offset_delta */);
+          LayoutUnit() /* block_offset_delta */));
       box_->SetCachedLayoutResult(layout_result);
     }
   }
@@ -1720,7 +1720,7 @@
   return layout_result;
 }
 
-const NGLayoutResult* NGBlockNode::RunSimplifiedLayout(
+scoped_refptr<const NGLayoutResult> NGBlockNode::RunSimplifiedLayout(
     const NGLayoutAlgorithmParams& params,
     const NGLayoutResult& previous_result) const {
   NGSimplifiedLayoutAlgorithm algorithm(params, previous_result);
@@ -1823,22 +1823,21 @@
 }
 
 void NGBlockNode::AddColumnResult(
-    const NGLayoutResult* result,
+    scoped_refptr<const NGLayoutResult> result,
     const NGBlockBreakToken* incoming_break_token) const {
   wtf_size_t index = FragmentIndex(incoming_break_token);
-  GetFlowThread(To<LayoutBlockFlow>(box_.Get()))
-      ->AddLayoutResult(result, index);
+  GetFlowThread(To<LayoutBlockFlow>(box_))->AddLayoutResult(result, index);
 }
 
-void NGBlockNode::AddColumnResult(const NGLayoutResult* result) const {
-  GetFlowThread(To<LayoutBlockFlow>(box_.Get()))
-      ->AddLayoutResult(std::move(result));
+void NGBlockNode::AddColumnResult(
+    scoped_refptr<const NGLayoutResult> result) const {
+  GetFlowThread(To<LayoutBlockFlow>(box_))->AddLayoutResult(std::move(result));
 }
 
 void NGBlockNode::ReplaceColumnResult(
-    const NGLayoutResult* result,
+    scoped_refptr<const NGLayoutResult> result,
     const NGPhysicalBoxFragment& old_fragment) const {
-  GetFlowThread(To<LayoutBlockFlow>(box_.Get()))
+  GetFlowThread(To<LayoutBlockFlow>(box_))
       ->ReplaceLayoutResult(std::move(result), old_fragment);
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.h b/third_party/blink/renderer/core/layout/ng/ng_block_node.h
index 1fc1c9d..08e8599 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.h
@@ -35,16 +35,17 @@
 
   NGBlockNode(std::nullptr_t) : NGLayoutInputNode(nullptr) {}
 
-  const NGLayoutResult* Layout(const NGConstraintSpace& constraint_space,
-                               const NGBlockBreakToken* break_token = nullptr,
-                               const NGEarlyBreak* = nullptr) const;
+  scoped_refptr<const NGLayoutResult> Layout(
+      const NGConstraintSpace& constraint_space,
+      const NGBlockBreakToken* break_token = nullptr,
+      const NGEarlyBreak* = nullptr) const;
 
   // This method is just for use within the |NGSimplifiedLayoutAlgorithm|.
   //
   // If layout is dirty, it will perform layout using the previous constraint
   // space used to generate the |NGLayoutResult|.
   // Otherwise it will simply return the previous layout result generated.
-  const NGLayoutResult* SimplifiedLayout(
+  scoped_refptr<const NGLayoutResult> SimplifiedLayout(
       const NGPhysicalFragment& previous_fragment) const;
 
   // This method is just for use within the |NGOutOfFlowLayoutPart|.
@@ -59,7 +60,7 @@
   //
   // If the containing-block size hasn't changed, and we are layout-clean we
   // can reuse the previous layout result.
-  const NGLayoutResult* CachedLayoutResultForOutOfFlowPositioned(
+  scoped_refptr<const NGLayoutResult> CachedLayoutResultForOutOfFlowPositioned(
       LogicalSize container_content_size) const;
 
   NGLayoutInputNode NextSibling() const;
@@ -165,7 +166,7 @@
   bool HasIndex() const;
 
   // Layout an atomic inline; e.g., inline block.
-  const NGLayoutResult* LayoutAtomicInline(
+  scoped_refptr<const NGLayoutResult> LayoutAtomicInline(
       const NGConstraintSpace& parent_constraint_space,
       const ComputedStyle& parent_style,
       bool use_first_line_style,
@@ -181,12 +182,12 @@
   // Add a column layout result to a list. Columns are essentially
   // LayoutObject-less, but we still need to keep the fragments generated
   // somewhere.
-  void AddColumnResult(const NGLayoutResult*,
+  void AddColumnResult(scoped_refptr<const NGLayoutResult>,
                        const NGBlockBreakToken* incoming_break_token) const;
   // Add a column layout result to this node.
-  void AddColumnResult(const NGLayoutResult*) const;
+  void AddColumnResult(scoped_refptr<const NGLayoutResult>) const;
   // Replace an existing column layout result with a new one.
-  void ReplaceColumnResult(const NGLayoutResult*,
+  void ReplaceColumnResult(scoped_refptr<const NGLayoutResult>,
                            const NGPhysicalBoxFragment& old_fragment) const;
 
   static bool CanUseNewLayout(const LayoutBox&);
@@ -197,7 +198,7 @@
   }
 
   bool HasLineIfEmpty() const {
-    if (const auto* block = DynamicTo<LayoutBlock>(box_.Get()))
+    if (const auto* block = DynamicTo<LayoutBlock>(box_))
       return block->HasLineIfEmpty();
     return false;
   }
@@ -217,17 +218,19 @@
 
   // Runs layout on the underlying LayoutObject and creates a fragment for the
   // resulting geometry.
-  const NGLayoutResult* RunLegacyLayout(const NGConstraintSpace&) const;
+  scoped_refptr<const NGLayoutResult> RunLegacyLayout(
+      const NGConstraintSpace&) const;
 
-  const NGLayoutResult* RunSimplifiedLayout(const NGLayoutAlgorithmParams&,
-                                            const NGLayoutResult&) const;
+  scoped_refptr<const NGLayoutResult> RunSimplifiedLayout(
+      const NGLayoutAlgorithmParams&,
+      const NGLayoutResult&) const;
 
   // If this node is a LayoutNGMixin, the caller must pass the layout object for
   // this node cast to a LayoutBlockFlow as the first argument.
   void FinishLayout(LayoutBlockFlow*,
                     const NGConstraintSpace&,
                     const NGBlockBreakToken*,
-                    const NGLayoutResult*) const;
+                    scoped_refptr<const NGLayoutResult>) const;
 
   // After we run the layout algorithm, this function copies back the geometry
   // data to the layout box.
@@ -280,6 +283,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::NGBlockNode)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_BLOCK_NODE_H_
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
index 6d2e377..ccf928a 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
@@ -33,8 +33,7 @@
     const Items& items,
     const PhysicalOffset& box_offset,
     NGBoxFragmentBuilder::InlineContainingBlockMap* inline_containing_block_map,
-    HeapHashMap<Member<const LayoutObject>, LineBoxPair>*
-        containing_linebox_map) {
+    HashMap<const LayoutObject*, LineBoxPair>* containing_linebox_map) {
   const NGPhysicalLineBoxFragment* linebox = nullptr;
   for (const auto& item : items) {
     // Track the current linebox.
@@ -146,7 +145,7 @@
           // If there is an inline break token, it will always be the last
           // child.
           last_inline_break_token_ =
-              DynamicTo<NGInlineBreakToken>(child_tokens.back().Get());
+              DynamicTo<NGInlineBreakToken>(child_tokens.back());
           if (last_inline_break_token_)
             return;
         }
@@ -159,7 +158,7 @@
     }
     return;
   }
-  auto* token = NGBlockBreakToken::CreateBreakBefore(child, is_forced_break);
+  auto token = NGBlockBreakToken::CreateBreakBefore(child, is_forced_break);
   child_break_tokens_.push_back(token);
 }
 
@@ -327,10 +326,11 @@
   AddChildInternal(&child, child_offset + *relative_offset);
 }
 
-void NGBoxFragmentBuilder::AddBreakToken(const NGBreakToken* token,
-                                         bool is_in_parallel_flow) {
-  DCHECK(token);
-  child_break_tokens_.push_back(token);
+void NGBoxFragmentBuilder::AddBreakToken(
+    scoped_refptr<const NGBreakToken> token,
+    bool is_in_parallel_flow) {
+  DCHECK(token.get());
+  child_break_tokens_.push_back(std::move(token));
   has_inflow_child_break_inside_ |= !is_in_parallel_flow;
 }
 
@@ -438,7 +438,7 @@
     has_violating_break_ |= child_layout_result.HasViolatingBreak();
 }
 
-const NGLayoutResult* NGBoxFragmentBuilder::ToBoxFragment(
+scoped_refptr<const NGLayoutResult> NGBoxFragmentBuilder::ToBoxFragment(
     WritingMode block_or_line_writing_mode) {
 #if DCHECK_IS_ON()
   if (ItemsBuilder()) {
@@ -464,18 +464,19 @@
         items_builder_->HasFloatingDescendantsForPaint();
   }
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGPhysicalBoxFragment::Create(this, block_or_line_writing_mode);
   fragment->CheckType();
 
-  return MakeGarbageCollected<NGLayoutResult>(
-      NGLayoutResult::NGBoxFragmentBuilderPassKey(), std::move(fragment), this);
+  return base::AdoptRef(
+      new NGLayoutResult(NGLayoutResult::NGBoxFragmentBuilderPassKey(),
+                         std::move(fragment), this));
 }
 
-const NGLayoutResult* NGBoxFragmentBuilder::Abort(
+scoped_refptr<const NGLayoutResult> NGBoxFragmentBuilder::Abort(
     NGLayoutResult::EStatus status) {
-  return MakeGarbageCollected<NGLayoutResult>(
-      NGLayoutResult::NGBoxFragmentBuilderPassKey(), status, this);
+  return base::AdoptRef(new NGLayoutResult(
+      NGLayoutResult::NGBoxFragmentBuilderPassKey(), status, this));
 }
 
 LogicalOffset NGBoxFragmentBuilder::GetChildOffset(
@@ -529,7 +530,7 @@
     DCHECK_EQ(entry.key, entry.key->ContinuationRoot());
 #endif
 
-  HeapHashMap<Member<const LayoutObject>, LineBoxPair> containing_linebox_map;
+  HashMap<const LayoutObject*, LineBoxPair> containing_linebox_map;
 
   if (items_builder_) {
     // To access the items correctly we need to convert them to the physical
@@ -648,7 +649,7 @@
   LayoutUnit previous_consumed_block_size =
       PreviousBreakToken()->ConsumedBlockSize();
   for (auto& multicol : multicols_with_pending_oofs_) {
-    NGMulticolWithPendingOOFs<LogicalOffset>& value = *multicol.value;
+    NGMulticolWithPendingOOFs<LogicalOffset>& value = multicol.value;
     if (!value.fixedpos_containing_block.fragment) {
       value.fixedpos_containing_block.offset.block_offset -=
           previous_consumed_block_size;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
index 6bbbdda..179265d0 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
@@ -34,7 +34,7 @@
 
  public:
   NGBoxFragmentBuilder(NGLayoutInputNode node,
-                       const ComputedStyle* style,
+                       scoped_refptr<const ComputedStyle> style,
                        const NGConstraintSpace* space,
                        WritingDirectionMode writing_direction)
       : NGContainerFragmentBuilder(node,
@@ -47,7 +47,7 @@
   // Build a fragment for LayoutObject without NGLayoutInputNode. LayoutInline
   // has NGInlineItem but does not have corresponding NGLayoutInputNode.
   NGBoxFragmentBuilder(LayoutObject* layout_object,
-                       const ComputedStyle* style,
+                       scoped_refptr<const ComputedStyle> style,
                        WritingDirectionMode writing_direction)
       : NGContainerFragmentBuilder(/* node */ nullptr,
                                    std::move(style),
@@ -218,7 +218,8 @@
 
   // Manually add a break token to the builder. Note that we're assuming that
   // this break token is for content in the same flow as this parent.
-  void AddBreakToken(const NGBreakToken*, bool is_in_parallel_flow = false);
+  void AddBreakToken(scoped_refptr<const NGBreakToken>,
+                     bool is_in_parallel_flow = false);
 
   void AddOutOfFlowLegacyCandidate(NGBlockNode,
                                    const NGLogicalStaticPosition&,
@@ -252,11 +253,12 @@
   void SetDidBreakSelf() { did_break_self_ = true; }
 
   // Store the previous break token, if one exists.
-  void SetPreviousBreakToken(const NGBlockBreakToken* break_token) {
-    previous_break_token_ = break_token;
+  void SetPreviousBreakToken(
+      scoped_refptr<const NGBlockBreakToken> break_token) {
+    previous_break_token_ = std::move(break_token);
   }
   const NGBlockBreakToken* PreviousBreakToken() const {
-    return previous_break_token_;
+    return previous_break_token_.get();
   }
 
   // Return true if we need to break before or inside any child, doesn't matter
@@ -269,7 +271,7 @@
       return true;
     // Inline nodes produce a "finished" trailing break token even if we don't
     // need to block-fragment.
-    return last_inline_break_token_;
+    return last_inline_break_token_.get();
   }
 
   // Return true if we need to break before or inside any in-flow child that
@@ -381,14 +383,15 @@
     lines_until_clamp_ = value;
   }
 
-  void SetEarlyBreak(const NGEarlyBreak* breakpoint, NGBreakAppeal appeal) {
+  void SetEarlyBreak(scoped_refptr<const NGEarlyBreak> breakpoint,
+                     NGBreakAppeal appeal) {
     early_break_ = breakpoint;
     break_appeal_ = appeal;
   }
-  bool HasEarlyBreak() const { return early_break_; }
+  bool HasEarlyBreak() const { return early_break_.get(); }
   const NGEarlyBreak& EarlyBreak() const {
-    DCHECK(early_break_);
-    return *early_break_;
+    DCHECK(early_break_.get());
+    return *early_break_.get();
   }
 
   // Set the highest break appeal found so far. This is either:
@@ -402,11 +405,11 @@
   // do not provide a setter here.
 
   // Creates the fragment. Can only be called once.
-  const NGLayoutResult* ToBoxFragment() {
+  scoped_refptr<const NGLayoutResult> ToBoxFragment() {
     DCHECK_NE(BoxType(), NGPhysicalFragment::kInlineBox);
     return ToBoxFragment(GetWritingMode());
   }
-  const NGLayoutResult* ToInlineBoxFragment() {
+  scoped_refptr<const NGLayoutResult> ToInlineBoxFragment() {
     // The logical coordinate for inline box uses line-relative writing-mode,
     // not
     // flow-relative.
@@ -414,7 +417,7 @@
     return ToBoxFragment(ToLineWritingMode(GetWritingMode()));
   }
 
-  const NGLayoutResult* Abort(NGLayoutResult::EStatus);
+  scoped_refptr<const NGLayoutResult> Abort(NGLayoutResult::EStatus);
 
   NGPhysicalFragment::NGBoxType BoxType() const;
   void SetBoxType(NGPhysicalFragment::NGBoxType box_type) {
@@ -505,7 +508,7 @@
   }
 
   void SetTableColumnGeometries(
-      const NGTableFragmentData::ColumnGeometries* table_column_geometries) {
+      const NGTableFragmentData::ColumnGeometries& table_column_geometries) {
     table_column_geometries_ = table_column_geometries;
   }
 
@@ -553,8 +556,8 @@
   };
 
   using InlineContainingBlockMap =
-      HeapHashMap<Member<const LayoutObject>,
-                  base::Optional<InlineContainingBlockGeometry>>;
+      HashMap<const LayoutObject*,
+              base::Optional<InlineContainingBlockGeometry>>;
 
   // Computes the geometry required for any inline containing blocks.
   // |inline_containing_block_map| is a map whose keys specify which inline
@@ -604,7 +607,7 @@
     minimal_space_shortage_ = LayoutUnit::Max();
   }
 
-  const NGLayoutResult* ToBoxFragment(WritingMode);
+  scoped_refptr<const NGLayoutResult> ToBoxFragment(WritingMode);
 
   const NGFragmentGeometry* initial_fragment_geometry_ = nullptr;
   NGBoxStrut border_padding_;
@@ -654,9 +657,9 @@
 
   // Table specific types.
   base::Optional<PhysicalRect> table_grid_rect_;
-  const NGTableFragmentData::ColumnGeometries* table_column_geometries_ =
-      nullptr;
-  const NGTableBorders* table_collapsed_borders_ = nullptr;
+  base::Optional<NGTableFragmentData::ColumnGeometries>
+      table_column_geometries_;
+  scoped_refptr<const NGTableBorders> table_collapsed_borders_;
   std::unique_ptr<NGTableFragmentData::CollapsedBordersGeometry>
       table_collapsed_borders_geometry_;
   base::Optional<wtf_size_t> table_column_count_;
@@ -675,7 +678,7 @@
   std::unique_ptr<NGMathMLPaintInfo> mathml_paint_info_;
   base::Optional<NGLayoutResult::MathData> math_data_;
 
-  const NGBlockBreakToken* previous_break_token_ = nullptr;
+  scoped_refptr<const NGBlockBreakToken> previous_break_token_;
 
 #if DCHECK_IS_ON()
   // Describes what size_.block_size represents; either the size of a single
diff --git a/third_party/blink/renderer/core/layout/ng/ng_break_token.cc b/third_party/blink/renderer/core/layout/ng/ng_break_token.cc
index ffb53e0..7ed2aea 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_break_token.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_break_token.cc
@@ -12,9 +12,9 @@
 
 namespace {
 
-struct SameSizeAsNGBreakToken : GarbageCollected<NGBreakToken> {
+struct SameSizeAsNGBreakToken : RefCounted<NGBreakToken> {
   virtual ~SameSizeAsNGBreakToken() = default;
-  Member<void*> member;
+  void* pointer;
   unsigned flags;
 };
 
@@ -40,7 +40,7 @@
 
   if (auto* block_break_token = DynamicTo<NGBlockBreakToken>(token)) {
     const auto children = block_break_token->ChildBreakTokens();
-    for (const auto& child : children)
+    for (const auto* child : children)
       AppendBreakTokenToString(child, string_builder, indent + 2);
   }
 }
@@ -62,8 +62,4 @@
 }
 #endif  // DCHECK_IS_ON()
 
-void NGBreakToken::Trace(Visitor* visitor) const {
-  visitor->Trace(box_);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_break_token.h b/third_party/blink/renderer/core/layout/ng/ng_break_token.h
index 64a9d73a..12d4eff 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_break_token.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_break_token.h
@@ -9,6 +9,8 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_break_appeal.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
 
 namespace blink {
 
@@ -29,8 +31,12 @@
 // NGPhysicalFragment* fragment2 = node->Layout(space, fragment->BreakToken());
 //
 // The break token should encapsulate enough information to "resume" the layout.
-class CORE_EXPORT NGBreakToken : public GarbageCollected<NGBreakToken> {
+class CORE_EXPORT NGBreakToken : public RefCounted<NGBreakToken> {
+  USING_FAST_MALLOC(NGBreakToken);
+
  public:
+  virtual ~NGBreakToken() = default;
+
   enum NGBreakTokenType {
     kBlockBreakToken = NGLayoutInputNode::kBlock,
     kInlineBreakToken = NGLayoutInputNode::kInline
@@ -56,8 +62,6 @@
   void ShowBreakTokenTree() const;
 #endif
 
-  virtual void Trace(Visitor*) const;
-
  protected:
   NGBreakToken(NGBreakTokenType type,
                NGLayoutInputNode node)
@@ -76,9 +80,10 @@
  private:
   // Because |NGLayoutInputNode| has a pointer and 1 bit flag, and it's fast to
   // re-construct, keep |LayoutBox| to save the memory consumed by alignment.
-  Member<LayoutBox> box_;
+  LayoutBox* box_;
 
   unsigned type_ : 1;
+  unsigned status_ : 1;
 
  protected:
   // The following bitfields are only to be used by NGInlineBreakToken (it's
@@ -111,7 +116,7 @@
   unsigned has_seen_all_children_ : 1;
 };
 
-typedef HeapVector<Member<const NGBreakToken>> NGBreakTokenVector;
+typedef Vector<scoped_refptr<const NGBreakToken>> NGBreakTokenVector;
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
index 137f48c..82106ef1 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -117,7 +117,7 @@
   NGBlockNode spanner_ = nullptr;
   NGBlockNode multicol_container_;
   const NGBlockBreakToken* parent_break_token_;
-  const NGBlockBreakToken* next_column_token_ = nullptr;
+  scoped_refptr<const NGBlockBreakToken> next_column_token_;
 
   // An index into parent_break_token_'s ChildBreakTokens() vector. Used for
   // keeping track of the next child break token to inspect.
@@ -157,7 +157,7 @@
     const auto& child_break_tokens = parent_break_token_->ChildBreakTokens();
     if (child_token_idx_ < child_break_tokens.size()) {
       const auto* child_break_token =
-          To<NGBlockBreakToken>(child_break_tokens[child_token_idx_].Get());
+          To<NGBlockBreakToken>(child_break_tokens[child_token_idx_]);
       if (child_break_token->InputNode() == multicol_container_) {
         current_.spanner = nullptr;
       } else {
@@ -175,7 +175,7 @@
   }
 
   if (next_column_token_) {
-    current_ = Entry(next_column_token_, /* spanner */ nullptr);
+    current_ = Entry(next_column_token_.get(), /* spanner */ nullptr);
     return;
   }
 
@@ -222,7 +222,7 @@
     const NGLayoutAlgorithmParams& params)
     : NGLayoutAlgorithm(params) {}
 
-const NGLayoutResult* NGColumnLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
   const LogicalSize border_box_size = container_builder_.InitialBorderBoxSize();
   // TODO(mstensho): This isn't the content-box size, as
   // |BorderScrollbarPadding()| has been adjusted for fragmentation. Verify
@@ -305,7 +305,7 @@
     // out at the outermost context. If this multicol has OOF positioned
     // elements pending layout, store its node for later use.
     if (container_builder_.HasOutOfFlowFragmentainerDescendants()) {
-      container_builder_.AddMulticolWithPendingOOFs(node_);
+      container_builder_.AddMulticolWithPendingOOFs(Node());
     }
   }
 
@@ -415,7 +415,7 @@
     // break token, we wouldn't be able to resume layout after the any initial
     // spanners.
     if (!entry.spanner) {
-      const NGLayoutResult* result =
+      scoped_refptr<const NGLayoutResult> result =
           LayoutRow(child_break_token, &margin_strut);
 
       if (!result) {
@@ -526,24 +526,7 @@
   return NGBreakStatus::kContinue;
 }
 
-struct ResultWithOffset {
-  DISALLOW_NEW();
-
- public:
-  Member<const NGLayoutResult> result;
-  LogicalOffset offset;
-
-  ResultWithOffset(const NGLayoutResult* result, LogicalOffset offset)
-      : result(result), offset(offset) {}
-
-  const NGPhysicalBoxFragment& Fragment() const {
-    return To<NGPhysicalBoxFragment>(result->PhysicalFragment());
-  }
-
-  void Trace(Visitor* visitor) const { visitor->Trace(result); }
-};
-
-const NGLayoutResult* NGColumnLayoutAlgorithm::LayoutRow(
+scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
     const NGBlockBreakToken* next_column_token,
     NGMarginStrut* margin_strut) {
   LogicalSize column_size(column_inline_size_, column_block_size_);
@@ -624,12 +607,25 @@
   // (colum balancing). Keep them in this list, and add them to the fragment
   // builder when we have the final column fragments. Or clear the list and
   // retry otherwise.
-  HeapVector<ResultWithOffset, 16> new_columns;
+  struct ResultWithOffset {
+    scoped_refptr<const NGLayoutResult> result;
+    LogicalOffset offset;
 
-  const NGLayoutResult* result = nullptr;
+    ResultWithOffset(scoped_refptr<const NGLayoutResult> result,
+                     LogicalOffset offset)
+        : result(result), offset(offset) {}
+
+    const NGPhysicalBoxFragment& Fragment() const {
+      return To<NGPhysicalBoxFragment>(result->PhysicalFragment());
+    }
+  };
+  Vector<ResultWithOffset, 16> new_columns;
+
+  scoped_refptr<const NGLayoutResult> result;
 
   do {
-    const NGBlockBreakToken* column_break_token = next_column_token;
+    scoped_refptr<const NGBlockBreakToken> column_break_token =
+        next_column_token;
 
     bool allow_discard_start_margin =
         column_break_token && !column_break_token->IsCausedByColumnSpanner();
@@ -655,7 +651,7 @@
           CalculateInitialFragmentGeometry(child_space, Node());
 
       NGBlockLayoutAlgorithm child_algorithm(
-          {Node(), fragment_geometry, child_space, column_break_token});
+          {Node(), fragment_geometry, child_space, column_break_token.get()});
       child_algorithm.SetBoxType(NGPhysicalFragment::kColumnBox);
       result = child_algorithm.Layout();
       const auto& column = result->PhysicalFragment();
@@ -841,7 +837,7 @@
   if (UNLIKELY(early_break_))
     early_break_in_child = EnterEarlyBreakInChild(spanner_node, *early_break_);
 
-  auto* result =
+  auto result =
       spanner_node.Layout(spanner_space, break_token, early_break_in_child);
 
   if (ConstraintSpace().HasBlockFragmentation() && !early_break_) {
@@ -852,8 +848,9 @@
         ConstraintSpace().FragmentainerOffsetAtBfc() + block_offset;
 
     NGBreakStatus break_status = BreakBeforeChildIfNeeded(
-        ConstraintSpace(), spanner_node, *result, fragmentainer_block_offset,
-        has_processed_first_child_, &container_builder_);
+        ConstraintSpace(), spanner_node, *result.get(),
+        fragmentainer_block_offset, has_processed_first_child_,
+        &container_builder_);
 
     if (break_status != NGBreakStatus::kContinue) {
       // We need to break, either before the spanner, or even earlier.
@@ -904,7 +901,7 @@
   if (!baseline)
     return;
 
-  const NGLayoutResult* layout_result = marker.Layout(
+  scoped_refptr<const NGLayoutResult> layout_result = marker.Layout(
       ConstraintSpace(), container_builder_.Style(), baseline_type);
   DCHECK(layout_result);
 
@@ -927,7 +924,7 @@
 
   // Lay out the list marker.
   FontBaseline baseline_type = Style().GetFontBaseline();
-  const NGLayoutResult* layout_result =
+  scoped_refptr<const NGLayoutResult> layout_result =
       marker.Layout(ConstraintSpace(), Style(), baseline_type);
   DCHECK(layout_result);
   // Position the list marker without aligning with line boxes.
@@ -1048,13 +1045,13 @@
 
   // First split into content runs at explicit (forced) breaks.
   ContentRuns content_runs;
-  const NGBlockBreakToken* break_token = child_break_token;
+  scoped_refptr<const NGBlockBreakToken> break_token = child_break_token;
   tallest_unbreakable_block_size_ = LayoutUnit();
   do {
     NGBlockLayoutAlgorithm balancing_algorithm(
-        {Node(), fragment_geometry, space, break_token});
+        {Node(), fragment_geometry, space, break_token.get()});
     balancing_algorithm.SetBoxType(NGPhysicalFragment::kColumnBox);
-    const NGLayoutResult* result = balancing_algorithm.Layout();
+    scoped_refptr<const NGLayoutResult> result = balancing_algorithm.Layout();
 
     // This algorithm should never abort.
     DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess);
@@ -1234,5 +1231,3 @@
 }
 
 }  // namespace blink
-
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::ResultWithOffset)
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.h
index 573a0d6..ee6610f 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.h
@@ -24,7 +24,7 @@
  public:
   explicit NGColumnLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override;
@@ -44,8 +44,9 @@
   // column that was laid out. The rows themselves don't create fragments. If
   // we're in a nested fragmentation context and completely out of outer
   // fragmentainer space, nullptr will be returned.
-  const NGLayoutResult* LayoutRow(const NGBlockBreakToken* next_column_token,
-                                  NGMarginStrut*);
+  scoped_refptr<const NGLayoutResult> LayoutRow(
+      const NGBlockBreakToken* next_column_token,
+      NGMarginStrut*);
 
   // Lay out a column spanner. The return value will tell whether to break
   // before the spanner or not. If |NGBreakStatus::kContinue| is returned, and
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
index 33b29c4c..611740f 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
@@ -21,7 +21,8 @@
   NGColumnLayoutAlgorithmTest()
       : ScopedLayoutNGBlockFragmentationForTest(true) {}
 
-  const NGPhysicalBoxFragment* RunBlockLayoutAlgorithm(Element* element) {
+  scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
+      Element* element) {
     NGBlockNode container(element->GetLayoutBox());
     NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
         {WritingMode::kHorizontalTb, TextDirection::kLtr},
@@ -39,8 +40,8 @@
   }
 
   String DumpFragmentTree(Element* element) {
-    auto* fragment = RunBlockLayoutAlgorithm(element);
-    return DumpFragmentTree(fragment);
+    auto fragment = RunBlockLayoutAlgorithm(element);
+    return DumpFragmentTree(fragment.get());
   }
 };
 
@@ -96,9 +97,9 @@
   NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(1000), kIndefiniteSize));
-  const NGPhysicalBoxFragment* parent_fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> parent_fragment =
       NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(container, space);
-  FragmentChildIterator iterator(parent_fragment);
+  FragmentChildIterator iterator(parent_fragment.get());
   const auto* fragment = iterator.NextChild();
   ASSERT_TRUE(fragment);
   EXPECT_EQ(PhysicalSize(210, 100), fragment->Size());
@@ -136,9 +137,9 @@
   NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(1000), kIndefiniteSize));
-  const NGPhysicalBoxFragment* parent_fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> parent_fragment =
       NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(container, space);
-  FragmentChildIterator iterator(parent_fragment);
+  FragmentChildIterator iterator(parent_fragment.get());
   const auto* fragment = iterator.NextChild();
   EXPECT_EQ(PhysicalSize(210, 100), fragment->Size());
   ASSERT_TRUE(fragment);
@@ -185,10 +186,10 @@
   NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
       LogicalSize(LayoutUnit(1000), kIndefiniteSize));
-  const NGPhysicalBoxFragment* parent_fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> parent_fragment =
       NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(container, space);
 
-  FragmentChildIterator iterator(parent_fragment);
+  FragmentChildIterator iterator(parent_fragment.get());
   const auto* fragment = iterator.NextChild();
   ASSERT_TRUE(fragment);
   EXPECT_EQ(PhysicalSize(310, 100), fragment->Size());
@@ -2754,7 +2755,8 @@
   LayoutObject* layout_object = GetLayoutObjectByElementId("multicol");
   ASSERT_TRUE(layout_object);
   NGBlockNode node = NGBlockNode(To<LayoutBox>(layout_object));
-  ComputedStyle* style = ComputedStyle::Clone(layout_object->StyleRef());
+  scoped_refptr<ComputedStyle> style =
+      ComputedStyle::Clone(layout_object->StyleRef());
   layout_object->SetStyle(style);
   NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
       {WritingMode::kHorizontalTb, TextDirection::kLtr},
@@ -3069,10 +3071,10 @@
     </div>
   )HTML");
 
-  const NGPhysicalBoxFragment* parent_fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> parent_fragment =
       RunBlockLayoutAlgorithm(GetElementById("container"));
 
-  FragmentChildIterator iterator(parent_fragment);
+  FragmentChildIterator iterator(parent_fragment.get());
   const auto* multicol = iterator.NextChild();
   ASSERT_TRUE(multicol);
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
index ffa86ac..b186d0d 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
@@ -142,8 +142,6 @@
       delete rare_data_;
   }
 
-  void Trace(Visitor* visitor) const { visitor->Trace(exclusion_space_); }
-
   // Creates NGConstraintSpace representing LayoutObject's containing block.
   // This should live on NGBlockNode or another layout bridge and probably take
   // a root NGConstraintSpace.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc
index c53226a..807f808 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc
@@ -25,11 +25,6 @@
 
 }  // namespace
 
-void NGContainerFragmentBuilder::ChildWithOffset::Trace(
-    Visitor* visitor) const {
-  visitor->Trace(fragment);
-}
-
 void NGContainerFragmentBuilder::ReplaceChild(
     wtf_size_t index,
     const NGPhysicalFragment& new_child,
@@ -121,7 +116,7 @@
 }
 
 void NGContainerFragmentBuilder::AddChildInternal(
-    const NGPhysicalFragment* child,
+    scoped_refptr<const NGPhysicalFragment> child,
     const LogicalOffset& child_offset) {
   // In order to know where list-markers are within the children list (for the
   // |NGSimplifiedLayoutAlgorithm|) we always place them as the first child.
@@ -201,7 +196,7 @@
 }
 
 void NGContainerFragmentBuilder::SwapOutOfFlowPositionedCandidates(
-    HeapVector<NGLogicalOutOfFlowPositionedNode>* candidates) {
+    Vector<NGLogicalOutOfFlowPositionedNode>* candidates) {
   DCHECK(candidates->IsEmpty());
   std::swap(oof_positioned_candidates_, *candidates);
 
@@ -229,7 +224,7 @@
 
 void NGContainerFragmentBuilder::AddMulticolWithPendingOOFs(
     const NGBlockNode& multicol,
-    NGMulticolWithPendingOOFs<LogicalOffset>* multicol_info) {
+    NGMulticolWithPendingOOFs<LogicalOffset> multicol_info) {
   DCHECK(To<LayoutBlockFlow>(multicol.GetLayoutBox())->MultiColumnFlowThread());
   auto it = multicols_with_pending_oofs_.find(multicol.GetLayoutBox());
   if (it != multicols_with_pending_oofs_.end())
@@ -244,7 +239,7 @@
 }
 
 void NGContainerFragmentBuilder::SwapOutOfFlowFragmentainerDescendants(
-    HeapVector<NGLogicalOutOfFlowPositionedNode>* descendants) {
+    Vector<NGLogicalOutOfFlowPositionedNode>* descendants) {
   DCHECK(descendants->IsEmpty());
   DCHECK(!has_oof_candidate_that_needs_block_offset_adjustment_);
   std::swap(oof_positioned_fragmentainer_descendants_, *descendants);
@@ -370,10 +365,10 @@
     for (auto& multicol : multicols_with_pending_oofs) {
       auto& multicol_info = multicol.value;
       LogicalOffset multicol_offset =
-          converter.ToLogical(multicol_info->multicol_offset, PhysicalSize());
+          converter.ToLogical(multicol_info.multicol_offset, PhysicalSize());
 
       const NGPhysicalFragment* fixedpos_containing_block_fragment =
-          multicol_info->fixedpos_containing_block.fragment;
+          multicol_info.fixedpos_containing_block.fragment.get();
       if (!fixedpos_containing_block_fragment &&
           box_fragment->GetLayoutObject() &&
           box_fragment->GetLayoutObject()->CanContainFixedPositionObjects())
@@ -387,10 +382,10 @@
       LogicalOffset fixedpos_containing_block_rel_offset;
       if (fixedpos_containing_block_fragment) {
         fixedpos_containing_block_offset =
-            converter.ToLogical(multicol_info->fixedpos_containing_block.offset,
+            converter.ToLogical(multicol_info.fixedpos_containing_block.offset,
                                 fixedpos_containing_block_fragment->Size());
         fixedpos_containing_block_rel_offset = converter.ToLogical(
-            multicol_info->fixedpos_containing_block.relative_offset,
+            multicol_info.fixedpos_containing_block.relative_offset,
             fixedpos_containing_block_fragment->Size());
         fixedpos_containing_block_rel_offset += relative_offset;
         // We want the fixedpos containing block offset to be the offset from
@@ -408,7 +403,7 @@
       }
       AddMulticolWithPendingOOFs(
           NGBlockNode(multicol.key),
-          MakeGarbageCollected<NGMulticolWithPendingOOFs<LogicalOffset>>(
+          NGMulticolWithPendingOOFs<LogicalOffset>(
               multicol_offset, NGContainingBlock<LogicalOffset>(
                                    fixedpos_containing_block_offset,
                                    fixedpos_containing_block_rel_offset,
@@ -430,7 +425,7 @@
       box_fragment->OutOfFlowPositionedFragmentainerDescendants();
   for (const auto& descendant : out_of_flow_fragmentainer_descendants) {
     const NGPhysicalFragment* containing_block_fragment =
-        descendant.containing_block.fragment;
+        descendant.containing_block.fragment.get();
     if (!containing_block_fragment)
       containing_block_fragment = box_fragment;
 
@@ -445,7 +440,7 @@
     containing_block_offset.block_offset += containing_block_adjustment;
 
     const NGPhysicalFragment* fixedpos_containing_block_fragment =
-        descendant.fixedpos_containing_block.fragment;
+        descendant.fixedpos_containing_block.fragment.get();
     if (!fixedpos_containing_block_fragment &&
         box_fragment->GetLayoutObject() &&
         box_fragment->GetLayoutObject()->CanContainFixedPositionObjects())
@@ -468,7 +463,8 @@
     }
 
     if (!fixedpos_containing_block_fragment && fixedpos_containing_block) {
-      fixedpos_containing_block_fragment = fixedpos_containing_block->fragment;
+      fixedpos_containing_block_fragment =
+          fixedpos_containing_block->fragment.get();
       fixedpos_containing_block_offset = fixedpos_containing_block->offset;
       fixedpos_containing_block_rel_offset =
           fixedpos_containing_block->relative_offset;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
index 196aa7da..b80728b 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
@@ -44,21 +44,19 @@
 
   struct ChildWithOffset {
     DISALLOW_NEW();
-    ChildWithOffset(LogicalOffset offset, const NGPhysicalFragment* fragment)
+    ChildWithOffset(LogicalOffset offset,
+                    scoped_refptr<const NGPhysicalFragment> fragment)
         : offset(offset), fragment(std::move(fragment)) {}
 
-    void Trace(Visitor*) const;
-
     // We store logical offsets (instead of the final physical), as we can't
     // convert into the physical coordinate space until we know our final size.
     LogicalOffset offset;
-    Member<const NGPhysicalFragment> fragment;
+    scoped_refptr<const NGPhysicalFragment> fragment;
   };
 
-  using ChildrenVector = HeapVector<ChildWithOffset, 4>;
+  using ChildrenVector = Vector<ChildWithOffset, 4>;
   using MulticolCollection =
-      HeapHashMap<Member<LayoutBox>,
-                  Member<NGMulticolWithPendingOOFs<LogicalOffset>>>;
+      HashMap<LayoutBox*, NGMulticolWithPendingOOFs<LogicalOffset>>;
 
   LayoutUnit BfcLineOffset() const { return bfc_line_offset_; }
   void SetBfcLineOffset(LayoutUnit bfc_line_offset) {
@@ -155,14 +153,14 @@
   // store such inner multicols for later use.
   void AddMulticolWithPendingOOFs(
       const NGBlockNode& multicol,
-      NGMulticolWithPendingOOFs<LogicalOffset>* multicol_info =
-          MakeGarbageCollected<NGMulticolWithPendingOOFs<LogicalOffset>>());
+      NGMulticolWithPendingOOFs<LogicalOffset> multicol_info =
+          NGMulticolWithPendingOOFs<LogicalOffset>());
 
   void SwapOutOfFlowPositionedCandidates(
-      HeapVector<NGLogicalOutOfFlowPositionedNode>* candidates);
+      Vector<NGLogicalOutOfFlowPositionedNode>* candidates);
 
   void SwapOutOfFlowFragmentainerDescendants(
-      HeapVector<NGLogicalOutOfFlowPositionedNode>* descendants);
+      Vector<NGLogicalOutOfFlowPositionedNode>* descendants);
 
   void SwapMulticolsWithPendingOOFs(
       MulticolCollection* multicols_with_pending_oofs);
@@ -195,7 +193,7 @@
     return !multicols_with_pending_oofs_.IsEmpty();
   }
 
-  HeapVector<NGLogicalOutOfFlowPositionedNode>*
+  Vector<NGLogicalOutOfFlowPositionedNode>*
   MutableOutOfFlowPositionedCandidates() {
     return &oof_positioned_candidates_;
   }
@@ -283,7 +281,7 @@
   friend class NGPhysicalFragment;
 
   NGContainerFragmentBuilder(NGLayoutInputNode node,
-                             const ComputedStyle* style,
+                             scoped_refptr<const ComputedStyle> style,
                              const NGConstraintSpace* space,
                              WritingDirectionMode writing_direction)
       : NGFragmentBuilder(std::move(style), writing_direction),
@@ -299,7 +297,8 @@
       const LayoutInline* inline_container = nullptr,
       base::Optional<LayoutUnit> adjustment_for_oof_propagation = LayoutUnit());
 
-  void AddChildInternal(const NGPhysicalFragment*, const LogicalOffset&);
+  void AddChildInternal(scoped_refptr<const NGPhysicalFragment>,
+                        const LogicalOffset&);
 
   NGLayoutInputNode node_;
   const NGConstraintSpace* space_;
@@ -309,10 +308,10 @@
   NGMarginStrut end_margin_strut_;
   NGExclusionSpace exclusion_space_;
 
-  HeapVector<NGLogicalOutOfFlowPositionedNode> oof_positioned_candidates_;
-  HeapVector<NGLogicalOutOfFlowPositionedNode>
+  Vector<NGLogicalOutOfFlowPositionedNode> oof_positioned_candidates_;
+  Vector<NGLogicalOutOfFlowPositionedNode>
       oof_positioned_fragmentainer_descendants_;
-  HeapVector<NGLogicalOutOfFlowPositionedNode> oof_positioned_descendants_;
+  Vector<NGLogicalOutOfFlowPositionedNode> oof_positioned_descendants_;
 
   MulticolCollection multicols_with_pending_oofs_;
 
@@ -323,9 +322,9 @@
   // Only used by the NGBoxFragmentBuilder subclass, but defined here to avoid
   // a virtual function call.
   NGBreakTokenVector child_break_tokens_;
-  const NGInlineBreakToken* last_inline_break_token_ = nullptr;
+  scoped_refptr<const NGInlineBreakToken> last_inline_break_token_;
 
-  const NGEarlyBreak* early_break_ = nullptr;
+  scoped_refptr<const NGEarlyBreak> early_break_;
   NGBreakAppeal break_appeal_ = kBreakAppealLastResort;
 
   // See NGLayoutResult::AnnotationOverflow().
diff --git a/third_party/blink/renderer/core/layout/ng/ng_early_break.h b/third_party/blink/renderer/core/layout/ng/ng_early_break.h
index b4d61c44..e66bb4e8 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_early_break.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_early_break.h
@@ -13,49 +13,41 @@
 // Possible early unforced breakpoint. This represents a possible (and good)
 // location to break. In cases where we run out of space at an unideal location,
 // we may want to go back and break here instead.
-class NGEarlyBreak : public GarbageCollected<NGEarlyBreak> {
+class NGEarlyBreak : public RefCounted<NGEarlyBreak> {
  public:
   enum BreakType {
     kLine,  // Break before a specified line number.
     kBlock  // Break before or inside a specified child block.
   };
 
-  explicit NGEarlyBreak(NGBlockNode block,
-                        const NGEarlyBreak* break_inside_child = nullptr)
+  explicit NGEarlyBreak(
+      NGBlockNode block,
+      scoped_refptr<const NGEarlyBreak> break_inside_child = nullptr)
       : box_(block.GetLayoutBox()),
         break_inside_child_(break_inside_child),
-        const_type_(kBlock) {}
+        type_(kBlock) {}
   explicit NGEarlyBreak(int line_number)
-      : line_number_(line_number), const_type_(kLine) {}
+      : line_number_(line_number), type_(kLine) {}
 
-  BreakType Type() const { return const_type_; }
+  BreakType Type() const { return type_; }
   bool IsBreakBefore() const { return !break_inside_child_; }
   NGBlockNode BlockNode() const {
-    CHECK_EQ(const_type_, kBlock);
+    CHECK_EQ(type_, kBlock);
     return NGBlockNode(box_);
   }
   int LineNumber() const {
-    DCHECK_EQ(const_type_, kLine);
+    DCHECK_EQ(type_, kLine);
     return line_number_;
   }
-  const NGEarlyBreak* BreakInside() const { return break_inside_child_; }
-
-  void Trace(Visitor* visitor) const {
-    // It is safe to check |const_type_| here because it is a const value.
-    if (const_type_ == kBlock)
-      visitor->Trace(box_);
-    visitor->Trace(break_inside_child_);
-  }
+  const NGEarlyBreak* BreakInside() const { return break_inside_child_.get(); }
 
  private:
   union {
-    GC_PLUGIN_IGNORE("1146383")
-    Member<LayoutBox> box_;  // Set if const_type_ == kBlock
-
-    int line_number_;  // Set if const_type_ == kLine
+    LayoutBox* box_;   // Set if type_ == kBlock
+    int line_number_;  // Set if type_ == kLine
   };
-  Member<const NGEarlyBreak> break_inside_child_;
-  const BreakType const_type_;
+  scoped_refptr<const NGEarlyBreak> break_inside_child_;
+  BreakType type_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc
index cfa93ab..b5ab3e8c 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc
@@ -69,7 +69,7 @@
   border_box_size_ = container_builder_.InitialBorderBoxSize();
 }
 
-const NGLayoutResult* NGFieldsetLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGFieldsetLayoutAlgorithm::Layout() {
   // Layout of a fieldset container consists of two parts: Create a child
   // fragment for the rendered legend (if any), and create a child fragment for
   // the fieldset contents anonymous box (if any).
@@ -145,13 +145,13 @@
 }
 
 NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutChildren() {
-  const NGBlockBreakToken* content_break_token = nullptr;
+  scoped_refptr<const NGBlockBreakToken> content_break_token;
   bool has_seen_all_children = false;
   if (const auto* token = BreakToken()) {
     const auto child_tokens = token->ChildBreakTokens();
     if (wtf_size_t break_token_count = child_tokens.size()) {
-      const NGBlockBreakToken* child_token =
-          To<NGBlockBreakToken>(child_tokens[0].Get());
+      scoped_refptr<const NGBlockBreakToken> child_token =
+          To<NGBlockBreakToken>(child_tokens[0]);
       if (child_token) {
         DCHECK(!child_token->InputNode().IsRenderedLegend());
         content_break_token = child_token;
@@ -175,7 +175,7 @@
     // The legend may eat from the available content box block size. Calculate
     // the minimum block size needed to encompass the legend.
     if (!Node().ShouldApplyBlockSizeContainment() &&
-        !IsResumingLayout(content_break_token)) {
+        !IsResumingLayout(content_break_token.get())) {
       minimum_border_box_block_size_ =
           intrinsic_block_size_ + padding_.BlockSum() + borders_.block_end;
     }
@@ -243,7 +243,8 @@
 
   auto legend_space = CreateConstraintSpaceForLegend(
       legend, ChildAvailableSize(), percentage_size);
-  const NGLayoutResult* result = legend.Layout(legend_space, BreakToken());
+  scoped_refptr<const NGLayoutResult> result =
+      legend.Layout(legend_space, BreakToken());
 
   // Legends are monolithic, so abortions are not expected.
   DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess);
@@ -317,7 +318,7 @@
 
 NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutFieldsetContent(
     NGBlockNode& fieldset_content,
-    const NGBlockBreakToken* content_break_token,
+    scoped_refptr<const NGBlockBreakToken> content_break_token,
     LogicalSize adjusted_padding_box_size,
     bool has_legend) {
   // If the following conditions meet, the content should be laid out with
@@ -337,7 +338,8 @@
           fieldset_content, adjusted_padding_box_size, intrinsic_block_size_,
           NGCacheSlot::kMeasure);
       LayoutUnit intrinsic_content_block_size =
-          fieldset_content.Layout(child_measure_space, content_break_token)
+          fieldset_content
+              .Layout(child_measure_space, content_break_token.get())
               ->IntrinsicBlockSize();
       if (intrinsic_content_block_size > max_content_block_size)
         adjusted_padding_box_size.block_size = max_content_block_size;
@@ -346,14 +348,14 @@
   auto child_space = CreateConstraintSpaceForFieldsetContent(
       fieldset_content, adjusted_padding_box_size, intrinsic_block_size_,
       NGCacheSlot::kLayout);
-  auto* result = fieldset_content.Layout(child_space, content_break_token);
+  auto result = fieldset_content.Layout(child_space, content_break_token.get());
 
   NGBreakStatus break_status = NGBreakStatus::kContinue;
   if (ConstraintSpace().HasBlockFragmentation()) {
     bool has_container_separation = is_legend_past_border_;
     // TODO(almaher): The legend should be treated as out-of-flow.
     break_status = BreakBeforeChildIfNeeded(
-        ConstraintSpace(), fieldset_content, *result,
+        ConstraintSpace(), fieldset_content, *result.get(),
         ConstraintSpace().FragmentainerOffsetAtBfc() + intrinsic_block_size_,
         has_container_separation, &container_builder_);
   }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h
index 3275071a..8691ece 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h
@@ -23,7 +23,7 @@
  public:
   explicit NGFieldsetLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override;
@@ -41,7 +41,7 @@
   void LayoutLegend(NGBlockNode& legend);
   NGBreakStatus LayoutFieldsetContent(
       NGBlockNode& fieldset_content,
-      const NGBlockBreakToken* content_break_token,
+      scoped_refptr<const NGBlockBreakToken> content_break_token,
       LogicalSize adjusted_padding_box_size,
       bool has_legend);
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
index 78a84a3..e60b23e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
@@ -20,7 +20,8 @@
   NGFieldsetLayoutAlgorithmTest()
       : ScopedLayoutNGBlockFragmentationForTest(true) {}
 
-  const NGPhysicalBoxFragment* RunBlockLayoutAlgorithm(Element* element) {
+  scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
+      Element* element) {
     NGBlockNode container(element->GetLayoutBox());
     NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
         {WritingMode::kHorizontalTb, TextDirection::kLtr},
@@ -56,8 +57,8 @@
   }
 
   String DumpFragmentTree(Element* element) {
-    auto* fragment = RunBlockLayoutAlgorithm(element);
-    return DumpFragmentTree(fragment);
+    auto fragment = RunBlockLayoutAlgorithm(element);
+    return DumpFragmentTree(fragment.get());
   }
 };
 
@@ -460,10 +461,10 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext());
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:170x140
     offset:10,0 size:50x120
@@ -561,7 +562,7 @@
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
   // We should only have one 176x126 fragment with no fragmentation.
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(176, 126), fragment->Size());
   ASSERT_FALSE(fragment->BreakToken());
@@ -587,7 +588,7 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   EXPECT_EQ(PhysicalSize(176, 200), fragment->Size());
   ASSERT_TRUE(fragment->BreakToken());
@@ -622,11 +623,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:120x10
 )DUMP";
@@ -636,7 +637,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:120x10
 )DUMP";
@@ -669,11 +670,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x200
     offset:3,3 size:170x197
@@ -685,7 +686,7 @@
       node, space, fragment->BreakToken());
   ASSERT_TRUE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x200
     offset:3,0 size:170x200
@@ -697,7 +698,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x126
     offset:3,0 size:170x123
@@ -732,11 +733,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x126
     offset:3,3 size:170x120
@@ -748,7 +749,7 @@
       node, space, fragment->BreakToken());
   ASSERT_TRUE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x0
     offset:3,0 size:170x0
@@ -760,7 +761,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x0
     offset:3,0 size:170x0
@@ -795,11 +796,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x500
     offset:13,0 size:50x500
@@ -810,7 +811,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x23
     offset:3,0 size:170x20
@@ -845,11 +846,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x500
     offset:13,0 size:50x500
@@ -860,7 +861,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x23
     offset:3,0 size:170x20
@@ -899,11 +900,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x500
     offset:13,0 size:50x500
@@ -913,7 +914,7 @@
   fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
       node, space, fragment->BreakToken());
   ASSERT_TRUE(fragment->BreakToken());
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x200
     offset:3,0 size:170x200
@@ -925,7 +926,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x23
     offset:3,0 size:170x20
@@ -965,11 +966,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x500
     offset:13,0 size:50x500
@@ -980,7 +981,7 @@
       node, space, fragment->BreakToken());
   ASSERT_TRUE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x23
     offset:3,0 size:170x20
@@ -991,7 +992,7 @@
   fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:176x0
     offset:3,0 size:170x0
@@ -1023,11 +1024,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x100
     offset:0,0 size:55x30
@@ -1041,7 +1042,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x80
     offset:0,0 size:1000x80
@@ -1081,11 +1082,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:150x100
     offset:0,0 size:50x100
@@ -1098,7 +1099,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:150x0
     offset:0,0 size:150x0
@@ -1135,11 +1136,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_FALSE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:100x100
     offset:0,0 size:75x60
@@ -1181,11 +1182,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:100x100
     offset:0,0 size:75x10
@@ -1201,7 +1202,7 @@
       node, space, fragment->BreakToken());
   ASSERT_TRUE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:100x0
     offset:0,0 size:100x0
@@ -1214,7 +1215,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:100x0
     offset:0,0 size:100x0
@@ -1249,11 +1250,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:100x100
     offset:0,0 size:10x50
@@ -1264,7 +1265,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:100x0
     offset:0,0 size:100x0
@@ -1302,11 +1303,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:100x100
     offset:0,0 size:10x50
@@ -1317,7 +1318,7 @@
       node, space, fragment->BreakToken());
   ASSERT_TRUE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:100x0
     offset:0,0 size:100x0
@@ -1329,7 +1330,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:100x0
     offset:0,0 size:100x0
@@ -1366,11 +1367,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x110
     offset:0,0 size:20x50
@@ -1383,7 +1384,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x0
     offset:0,0 size:100x0
@@ -1421,11 +1422,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x75
     offset:0,0 size:20x50
@@ -1438,7 +1439,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x50
     offset:0,0 size:100x50
@@ -1476,11 +1477,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x125
     offset:0,0 size:20x90
@@ -1493,7 +1494,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x10
     offset:0,0 size:120x10
@@ -1531,11 +1532,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x75
     offset:0,0 size:20x50
@@ -1548,7 +1549,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x50
     offset:0,0 size:100x50
@@ -1587,11 +1588,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x100
     offset:0,0 size:20x50
@@ -1604,7 +1605,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:1000x25
     offset:0,0 size:100x25
@@ -1643,11 +1644,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:100x110
     offset:0,0 size:0x90
@@ -1658,7 +1659,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:100x0
     offset:0,0 size:100x0
@@ -1691,11 +1692,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:220x60
     offset:60,5 size:10x50
@@ -1706,7 +1707,7 @@
       node, space, fragment->BreakToken());
   ASSERT_TRUE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:220x10
     offset:60,0 size:100x10
@@ -1717,7 +1718,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:220x60
 )DUMP";
@@ -1748,11 +1749,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:220x60
     offset:60,27.5 size:10x5
@@ -1763,7 +1764,7 @@
       node, space, fragment->BreakToken());
   ASSERT_TRUE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:220x10
     offset:60,0 size:100x10
@@ -1774,7 +1775,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:220x60
 )DUMP";
@@ -1810,11 +1811,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:300x100
     offset:0,0 size:33x70
@@ -1825,7 +1826,7 @@
       node, space, fragment->BreakToken());
   EXPECT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:300x90
     offset:0,0 size:160x90
@@ -1859,11 +1860,11 @@
       /* stretch_inline_size_if_auto */ true,
       node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
 
-  const NGPhysicalBoxFragment* fragment =
+  scoped_refptr<const NGPhysicalBoxFragment> fragment =
       NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
   ASSERT_TRUE(fragment->BreakToken());
 
-  String dump = DumpFragmentTree(fragment);
+  String dump = DumpFragmentTree(fragment.get());
   String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:220x60
     offset:60,27.5 size:10x5
@@ -1874,7 +1875,7 @@
       node, space, fragment->BreakToken());
   ASSERT_TRUE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:220x10
     offset:60,0 size:100x10
@@ -1885,7 +1886,7 @@
       node, space, fragment->BreakToken());
   ASSERT_FALSE(fragment->BreakToken());
 
-  dump = DumpFragmentTree(fragment);
+  dump = DumpFragmentTree(fragment.get());
   expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
   offset:unplaced size:220x60
 )DUMP";
diff --git a/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc
index 54a13f4..315c3f2a 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc
@@ -83,7 +83,7 @@
   // If we're resuming layout of this float after a fragmentainer break, the
   // margins of its children may be adjoining with the fragmentainer
   // block-start, in which case they may get truncated.
-  if (IsResumingLayout(unpositioned_float.token))
+  if (IsResumingLayout(unpositioned_float.token.get()))
     builder.SetDiscardingMarginStrut();
 
   builder.SetAvailableSize(unpositioned_float.available_size);
@@ -93,7 +93,7 @@
   return builder.ToConstraintSpace();
 }
 
-NGExclusionShapeData* CreateExclusionShapeData(
+std::unique_ptr<NGExclusionShapeData> CreateExclusionShapeData(
     const NGBoxStrut& margins,
     const NGUnpositionedFloat& unpositioned_float) {
   const LayoutBox* layout_box = unpositioned_float.node.GetLayoutBox();
@@ -129,13 +129,13 @@
       break;
   }
 
-  return MakeGarbageCollected<NGExclusionShapeData>(layout_box, new_margins,
-                                                    shape_insets);
+  return std::make_unique<NGExclusionShapeData>(layout_box, new_margins,
+                                                shape_insets);
 }
 
 // Creates an exclusion from the fragment that will be placed in the provided
 // layout opportunity.
-const NGExclusion* CreateExclusion(
+scoped_refptr<const NGExclusion> CreateExclusion(
     const NGFragment& fragment,
     const NGBfcOffset& float_margin_bfc_offset,
     const NGBoxStrut& margins,
@@ -148,7 +148,7 @@
       start_offset.block_offset +
           (fragment.BlockSize() + margins.BlockSum()).ClampNegativeToZero());
 
-  NGExclusionShapeData* shape_data =
+  std::unique_ptr<NGExclusionShapeData> shape_data =
       unpositioned_float.node.GetLayoutBox()->GetShapeOutsideInfo()
           ? CreateExclusionShapeData(margins, unpositioned_float)
           : nullptr;
@@ -192,8 +192,8 @@
       .ClampNegativeToZero();
 }
 
-NGPositionedFloat* PositionFloat(NGUnpositionedFloat* unpositioned_float,
-                                 NGExclusionSpace* exclusion_space) {
+NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float,
+                                NGExclusionSpace* exclusion_space) {
   DCHECK(unpositioned_float);
   const NGConstraintSpace& parent_space = unpositioned_float->parent_space;
   NGBlockNode node = unpositioned_float->node;
@@ -203,7 +203,7 @@
   bool is_fragmentable =
       is_same_writing_mode && parent_space.HasBlockFragmentation();
 
-  const NGLayoutResult* layout_result = nullptr;
+  scoped_refptr<const NGLayoutResult> layout_result;
   NGBoxStrut fragment_margins;
   NGLayoutOpportunity opportunity;
   bool need_break_before = false;
@@ -226,7 +226,8 @@
     fragment_margins = ComputeMarginsFor(
         node.Style(), unpositioned_float->percentage_size.inline_size,
         parent_space.GetWritingDirection());
-    AdjustMarginsForFragmentation(unpositioned_float->token, &fragment_margins);
+    AdjustMarginsForFragmentation(unpositioned_float->token.get(),
+                                  &fragment_margins);
 
     // When fragmenting, we need to set the block-offset of the node before
     // laying it out. This is a float, and in order to calculate its offset, we
@@ -260,14 +261,14 @@
       NGConstraintSpace space = CreateConstraintSpaceForFloat(
           *unpositioned_float, fragmentainer_delta);
 
-      layout_result = node.Layout(space, unpositioned_float->token);
+      layout_result = node.Layout(space, unpositioned_float->token.get());
 
       if (layout_result->Status() != NGLayoutResult::kSuccess) {
         DCHECK_EQ(layout_result->Status(),
                   NGLayoutResult::kOutOfFragmentainerSpace);
         need_break_before = true;
-        return MakeGarbageCollected<NGPositionedFloat>(
-            std::move(layout_result), NGBfcOffset(), need_break_before);
+        return NGPositionedFloat(std::move(layout_result), NGBfcOffset(),
+                                 need_break_before);
       }
 
       // If we knew the right block-offset up front, we're done.
@@ -360,12 +361,12 @@
     // current fragmentainer).
     NGBfcOffset past_everything(LayoutUnit(),
                                 FragmentainerSpaceAtBfcStart(parent_space));
-    const NGExclusion* exclusion =
+    scoped_refptr<const NGExclusion> exclusion =
         NGExclusion::Create(NGBfcRect(past_everything, past_everything),
                             node.Style().Floating(parent_space.Direction()));
     exclusion_space->Add(std::move(exclusion));
   } else {
-    const NGExclusion* exclusion = CreateExclusion(
+    scoped_refptr<const NGExclusion> exclusion = CreateExclusion(
         float_fragment, float_margin_bfc_offset, fragment_margins,
         *unpositioned_float, node.Style().Floating(parent_space.Direction()));
     exclusion_space->Add(std::move(exclusion));
@@ -377,8 +378,8 @@
           fragment_margins.LineLeft(parent_space.Direction()),
       float_margin_bfc_offset.block_offset + fragment_margins.block_start);
 
-  return MakeGarbageCollected<NGPositionedFloat>(
-      std::move(layout_result), float_bfc_offset, need_break_before);
+  return NGPositionedFloat(std::move(layout_result), float_bfc_offset,
+                           need_break_before);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h b/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h
index 7e291fe..826e8464 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h
@@ -8,7 +8,6 @@
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
@@ -17,13 +16,13 @@
 struct NGPositionedFloat;
 struct NGUnpositionedFloat;
 
-typedef HeapVector<Member<NGPositionedFloat>, 8> NGPositionedFloatVector;
+typedef Vector<NGPositionedFloat, 8> NGPositionedFloatVector;
 
 // Calculate and return the inline size of the unpositioned float.
 LayoutUnit ComputeMarginBoxInlineSizeForUnpositionedFloat(NGUnpositionedFloat*);
 
 // Position and lay out a float.
-NGPositionedFloat* PositionFloat(NGUnpositionedFloat*, NGExclusionSpace*);
+NGPositionedFloat PositionFloat(NGUnpositionedFloat*, NGExclusionSpace*);
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h
index 48f468d..fe47c29 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h
@@ -30,7 +30,8 @@
   void SetStyleVariant(NGStyleVariant style_variant) {
     style_variant_ = style_variant;
   }
-  void SetStyle(const ComputedStyle* style, NGStyleVariant style_variant) {
+  void SetStyle(scoped_refptr<const ComputedStyle> style,
+                NGStyleVariant style_variant) {
     DCHECK(style);
     style_ = std::move(style);
     style_variant_ = style_variant;
@@ -62,7 +63,7 @@
   const LayoutObject* GetLayoutObject() const { return layout_object_; }
 
  protected:
-  NGFragmentBuilder(const ComputedStyle* style,
+  NGFragmentBuilder(scoped_refptr<const ComputedStyle> style,
                     WritingDirectionMode writing_direction)
       : style_(std::move(style)),
         writing_direction_(writing_direction),
@@ -81,12 +82,12 @@
         is_hidden_for_paint_(fragment.IsHiddenForPaint()) {}
 
  protected:
-  const ComputedStyle* style_;
+  scoped_refptr<const ComputedStyle> style_;
   WritingDirectionMode writing_direction_;
   NGStyleVariant style_variant_;
   LogicalSize size_;
   LayoutObject* layout_object_ = nullptr;
-  const NGBreakToken* break_token_ = nullptr;
+  scoped_refptr<NGBreakToken> break_token_;
   bool is_hidden_for_paint_ = false;
   bool has_collapsed_borders_ = false;
   friend class NGPhysicalFragment;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc b/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc
index 5710a77..5dc4bff 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc
@@ -32,7 +32,7 @@
 NGFragmentChildIterator::NGFragmentChildIterator(
     const NGInlineCursor& parent,
     const NGBlockBreakToken* parent_break_token,
-    base::span<const Member<const NGBreakToken>> child_break_tokens)
+    base::span<const NGBreakToken* const> child_break_tokens)
     : parent_break_token_(parent_break_token),
       child_break_tokens_(child_break_tokens) {
   current_.block_break_token_ = parent_break_token;
@@ -62,7 +62,7 @@
   DCHECK(parent_fragment_);
   const auto children = parent_fragment_->Children();
   const NGPhysicalBoxFragment* previous_fragment =
-      To<NGPhysicalBoxFragment>(current_.link_.fragment.Get());
+      To<NGPhysicalBoxFragment>(current_.link_.fragment);
   DCHECK(previous_fragment);
   if (child_fragment_idx_ < children.size())
     child_fragment_idx_++;
@@ -88,8 +88,8 @@
   DCHECK(current_.link_.fragment);
   SkipToBlockBreakToken();
   if (child_break_token_idx_ < child_break_tokens_.size()) {
-    current_.block_break_token_ = To<NGBlockBreakToken>(
-        child_break_tokens_[child_break_token_idx_].Get());
+    current_.block_break_token_ =
+        To<NGBlockBreakToken>(child_break_tokens_[child_break_token_idx_]);
     // TODO(mstensho): Clean up this. What we're trying to do here is to detect
     // whether the incoming break token matches the current fragment or not.
     // Figuring out if a fragment is generated from a given node is currently
@@ -127,7 +127,7 @@
       current_.break_token_for_fragmentainer_only_ = true;
     }
   } else if (current_.link_.fragment->IsOutOfFlowPositioned() &&
-             !To<NGPhysicalBoxFragment>(current_.link_.fragment.Get())
+             !To<NGPhysicalBoxFragment>(current_.link_.fragment)
                   ->IsFirstForNode()) {
     // If an out-of-flow positioned element fragments beyond the last existing
     // fragmentainer in a nested fragmentation context, instead of creating a
@@ -139,7 +139,7 @@
     const auto* layout_object = current_.link_.fragment->GetLayoutObject();
     DCHECK(layout_object);
     for (wtf_size_t index = child_fragment_idx_; index > 0; index--) {
-      const auto* child_fragment = children[index - 1].fragment.Get();
+      const auto* child_fragment = children[index - 1].fragment;
       if (layout_object == child_fragment->GetLayoutObject()) {
         current_.block_break_token_ = To<NGBlockBreakToken>(
             To<NGPhysicalBoxFragment>(child_fragment)->BreakToken());
@@ -193,7 +193,7 @@
   // There may be inline break tokens here. Ignore them.
   while (child_break_token_idx_ < child_break_tokens_.size()) {
     const auto* current_break_token = DynamicTo<NGBlockBreakToken>(
-        child_break_tokens_[child_break_token_idx_].Get());
+        child_break_tokens_[child_break_token_idx_]);
     // Skip over any out-of-flow positioned break tokens that are the result of
     // a break before.
     if (current_break_token &&
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h b/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h
index a690a9b..bdd768d 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h
@@ -66,7 +66,7 @@
     const NGLink& Link() const { return link_; }
 
     const NGPhysicalBoxFragment* BoxFragment() const {
-      return To<NGPhysicalBoxFragment>(link_.fragment.Get());
+      return To<NGPhysicalBoxFragment>(link_.fragment);
     }
     const NGFragmentItem* FragmentItem() const {
       if (!cursor_)
@@ -118,7 +118,7 @@
   NGFragmentChildIterator(
       const NGInlineCursor& parent,
       const NGBlockBreakToken* parent_break_token,
-      base::span<const Member<const NGBreakToken>> child_break_tokens);
+      base::span<const NGBreakToken* const> child_break_tokens);
 
   bool AdvanceChildFragment();
   void UpdateSelfFromFragment(
@@ -132,7 +132,7 @@
   const NGPhysicalBoxFragment* parent_fragment_ = nullptr;
   const NGBlockBreakToken* parent_break_token_ = nullptr;
   Current current_;
-  base::span<const Member<const NGBreakToken>> child_break_tokens_;
+  base::span<const NGBreakToken* const> child_break_tokens_;
   wtf_size_t child_fragment_idx_ = 0;
   wtf_size_t child_break_token_idx_ = 0;
   bool is_fragmentation_context_root_ = false;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator_test.cc b/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator_test.cc
index e981a77ff..68de9194 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator_test.cc
@@ -17,7 +17,8 @@
   NGFragmentChildIteratorTest()
       : ScopedLayoutNGBlockFragmentationForTest(true) {}
 
-  const NGPhysicalBoxFragment* RunBlockLayoutAlgorithm(Element* element) {
+  scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
+      Element* element) {
     NGBlockNode container(element->GetLayoutBox());
     NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
         {WritingMode::kHorizontalTb, TextDirection::kLtr},
@@ -40,9 +41,9 @@
   const LayoutObject* child2 = GetLayoutObjectByElementId("child2");
   const LayoutObject* grandchild = GetLayoutObjectByElementId("grandchild");
 
-  const NGPhysicalBoxFragment* container =
+  scoped_refptr<const NGPhysicalBoxFragment> container =
       RunBlockLayoutAlgorithm(GetElementById("container"));
-  NGFragmentChildIterator iterator1(*container);
+  NGFragmentChildIterator iterator1(*container.get());
   EXPECT_FALSE(iterator1.IsAtEnd());
 
   const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment();
@@ -88,9 +89,9 @@
   const LayoutObject* span1 = GetLayoutObjectByElementId("span1");
   const LayoutObject* float1 = GetLayoutObjectByElementId("float1");
 
-  const NGPhysicalBoxFragment* container =
+  scoped_refptr<const NGPhysicalBoxFragment> container =
       RunBlockLayoutAlgorithm(GetElementById("container"));
-  NGFragmentChildIterator iterator1(*container);
+  NGFragmentChildIterator iterator1(*container.get());
 
   EXPECT_FALSE(iterator1->BoxFragment());
   const NGFragmentItem* fragment_item = iterator1->FragmentItem();
@@ -144,9 +145,9 @@
   const LayoutObject* inlineblock = GetLayoutObjectByElementId("inlineblock");
   const LayoutObject* float1 = GetLayoutObjectByElementId("float1");
 
-  const NGPhysicalBoxFragment* container =
+  scoped_refptr<const NGPhysicalBoxFragment> container =
       RunBlockLayoutAlgorithm(GetElementById("container"));
-  NGFragmentChildIterator iterator1(*container);
+  NGFragmentChildIterator iterator1(*container.get());
 
   EXPECT_FALSE(iterator1->BoxFragment());
   const NGFragmentItem* fragment_item = iterator1->FragmentItem();
@@ -196,9 +197,9 @@
   const LayoutObject* float1 = GetLayoutObjectByElementId("float1");
   const LayoutObject* child = GetLayoutObjectByElementId("child");
 
-  const NGPhysicalBoxFragment* container =
+  scoped_refptr<const NGPhysicalBoxFragment> container =
       RunBlockLayoutAlgorithm(GetElementById("container"));
-  NGFragmentChildIterator iterator1(*container);
+  NGFragmentChildIterator iterator1(*container.get());
 
   const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment();
   EXPECT_FALSE(fragment);
@@ -240,9 +241,9 @@
 
   const LayoutObject* abspos = GetLayoutObjectByElementId("abspos");
 
-  const NGPhysicalBoxFragment* container =
+  scoped_refptr<const NGPhysicalBoxFragment> container =
       RunBlockLayoutAlgorithm(GetElementById("container"));
-  NGFragmentChildIterator iterator1(*container);
+  NGFragmentChildIterator iterator1(*container.get());
 
   const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment();
   EXPECT_FALSE(fragment);
@@ -280,9 +281,9 @@
   const LayoutObject* mc = GetLayoutObjectByElementId("mc");
   const LayoutObject* child = GetLayoutObjectByElementId("child");
 
-  const NGPhysicalBoxFragment* container =
+  scoped_refptr<const NGPhysicalBoxFragment> container =
       RunBlockLayoutAlgorithm(GetElementById("container"));
-  NGFragmentChildIterator iterator(*container);
+  NGFragmentChildIterator iterator(*container.get());
 
   const NGPhysicalBoxFragment* fragment = iterator->BoxFragment();
   ASSERT_TRUE(fragment);
@@ -380,9 +381,9 @@
     </div>
   )HTML");
 
-  const NGPhysicalBoxFragment* container =
+  scoped_refptr<const NGPhysicalBoxFragment> container =
       RunBlockLayoutAlgorithm(GetElementById("container"));
-  NGFragmentChildIterator iterator1(*container);
+  NGFragmentChildIterator iterator1(*container.get());
 
   const LayoutObject* mc = GetLayoutObjectByElementId("mc");
   const LayoutObject* child = GetLayoutObjectByElementId("child");
@@ -560,9 +561,9 @@
     </div>
   )HTML");
 
-  const NGPhysicalBoxFragment* container =
+  scoped_refptr<const NGPhysicalBoxFragment> container =
       RunBlockLayoutAlgorithm(GetElementById("container"));
-  NGFragmentChildIterator iterator1(*container);
+  NGFragmentChildIterator iterator1(*container.get());
 
   const LayoutObject* mc1 = GetLayoutObjectByElementId("mc1");
   const LayoutObject* mc2 = GetLayoutObjectByElementId("mc2");
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_test.cc b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_test.cc
index 3f5d97f..948c111 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_test.cc
@@ -16,7 +16,8 @@
  protected:
   NGFragmentationTest() : ScopedLayoutNGBlockFragmentationForTest(true) {}
 
-  const NGPhysicalBoxFragment* RunBlockLayoutAlgorithm(Element* element) {
+  scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
+      Element* element) {
     NGBlockNode container(element->GetLayoutBox());
     NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
         {WritingMode::kHorizontalTb, TextDirection::kLtr},
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
index 12a80b2..4dd8301 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
@@ -726,13 +726,13 @@
 
   // See if there's a good breakpoint inside the child.
   NGBreakAppeal appeal_inside = kBreakAppealLastResort;
-  if (const NGEarlyBreak* breakpoint = layout_result.GetEarlyBreak()) {
+  if (scoped_refptr<const NGEarlyBreak> breakpoint =
+          layout_result.GetEarlyBreak()) {
     appeal_inside = CalculateBreakAppealInside(space, child, layout_result);
     if (builder->BreakAppeal() <= appeal_inside) {
       // Found a good breakpoint inside the child. Add the child to the early
       // break container chain, and store it.
-      auto* parent_break =
-          MakeGarbageCollected<NGEarlyBreak>(child, breakpoint);
+      auto parent_break = base::AdoptRef(new NGEarlyBreak(child, breakpoint));
       builder->SetEarlyBreak(parent_break, appeal_inside);
     }
   }
@@ -744,7 +744,7 @@
   if (appeal_before < builder->BreakAppeal() || appeal_before == appeal_inside)
     return;
 
-  builder->SetEarlyBreak(MakeGarbageCollected<NGEarlyBreak>(child),
+  builder->SetEarlyBreak(base::AdoptRef(new NGEarlyBreak(child)),
                          appeal_before);
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_inline_layout_test.cc b/third_party/blink/renderer/core/layout/ng/ng_inline_layout_test.cc
index cf8c4f2a..8de01294 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_inline_layout_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_inline_layout_test.cc
@@ -49,7 +49,7 @@
 
   NGFragmentGeometry fragment_geometry =
       CalculateInitialFragmentGeometry(constraint_space, node);
-  const NGLayoutResult* result =
+  scoped_refptr<const NGLayoutResult> result =
       NGBlockLayoutAlgorithm({node, fragment_geometry, constraint_space})
           .Layout();
   EXPECT_TRUE(result);
@@ -77,7 +77,7 @@
 
   NGFragmentGeometry fragment_geometry =
       CalculateInitialFragmentGeometry(constraint_space, node);
-  const NGLayoutResult* result =
+  scoped_refptr<const NGLayoutResult> result =
       NGBlockLayoutAlgorithm({node, fragment_geometry, constraint_space})
           .Layout();
   EXPECT_TRUE(result);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h
index d7975b1..f62d94d 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h
@@ -27,7 +27,7 @@
   // constraints given by the NGConstraintSpace. Returns a layout result with
   // the resulting layout information.
   // TODO(layout-dev): attempt to make this function const.
-  virtual const NGLayoutResult* Layout() = 0;
+  virtual scoped_refptr<const NGLayoutResult> Layout() = 0;
 
   // Computes the min-content and max-content intrinsic sizes for the given box.
   // The result will not take any min-width, max-width or width properties into
@@ -68,7 +68,7 @@
   STACK_ALLOCATED();
  public:
   NGLayoutAlgorithm(NGInputNodeType node,
-                    const ComputedStyle* style,
+                    scoped_refptr<const ComputedStyle> style,
                     const NGConstraintSpace& space,
                     TextDirection direction,
                     const NGBreakTokenType* break_token)
@@ -117,7 +117,7 @@
 
   NGInputNodeType Node() const { return node_; }
 
-  const NGBreakTokenType* BreakToken() const { return break_token_; }
+  const NGBreakTokenType* BreakToken() const { return break_token_.get(); }
 
   const NGBoxStrut& BorderPadding() const {
     return container_builder_.BorderPadding();
@@ -134,7 +134,7 @@
   // fragmentainer at an less-than-ideal location, due to breaking restrictions,
   // such as orphans, widows, break-before:avoid or break-after:avoid.
   template <typename Algorithm>
-  const NGLayoutResult* RelayoutAndBreakEarlier(
+  scoped_refptr<const NGLayoutResult> RelayoutAndBreakEarlier(
       const NGEarlyBreak& breakpoint) {
     // Not allowed to recurse!
     DCHECK(!early_break_);
@@ -158,7 +158,7 @@
   // wants to break. We don't want any zero-sized clipped fragments that
   // contribute to superfluous fragmentainers.
   template <typename Algorithm>
-  const NGLayoutResult* RelayoutWithoutFragmentation() {
+  scoped_refptr<const NGLayoutResult> RelayoutWithoutFragmentation() {
     DCHECK(ConstraintSpace().HasBlockFragmentation());
     // We'll relayout with a special cloned constraint space that disables
     // further fragmentation (but rather lets clipped child content "overflow"
@@ -186,7 +186,7 @@
   const NGEarlyBreak* early_break_ = nullptr;
 
   // The break token from which we are currently resuming layout.
-  const NGBreakTokenType* break_token_;
+  scoped_refptr<const NGBreakTokenType> break_token_;
 
   NGBoxFragmentBuilderType container_builder_;
 };
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
index 828a269..673ba5f 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
@@ -81,23 +81,22 @@
 }
 
 bool NGLayoutInputNode::IsEmptyTableSection() const {
-  return box_->IsTableSection() &&
-         To<LayoutNGTableSection>(box_.Get())->IsEmpty();
+  return box_->IsTableSection() && To<LayoutNGTableSection>(box_)->IsEmpty();
 }
 
 wtf_size_t NGLayoutInputNode::TableColumnSpan() const {
   DCHECK(IsTableCol() || IsTableColgroup());
-  return To<LayoutNGTableColumn>(box_.Get())->Span();
+  return To<LayoutNGTableColumn>(box_)->Span();
 }
 
 wtf_size_t NGLayoutInputNode::TableCellColspan() const {
   DCHECK(box_->IsTableCell());
-  return To<LayoutNGTableCell>(box_.Get())->ColSpan();
+  return To<LayoutNGTableCell>(box_)->ColSpan();
 }
 
 wtf_size_t NGLayoutInputNode::TableCellRowspan() const {
   DCHECK(box_->IsTableCell());
-  return To<LayoutNGTableCell>(box_.Get())->ComputedRowSpan();
+  return To<LayoutNGTableCell>(box_)->ComputedRowSpan();
 }
 
 bool NGLayoutInputNode::IsTextControlPlaceholder() const {
@@ -115,8 +114,7 @@
 
   IntrinsicSizingInfo legacy_sizing_info;
 
-  To<LayoutReplaced>(box_.Get())
-      ->ComputeIntrinsicSizingInfo(legacy_sizing_info);
+  To<LayoutReplaced>(box_)->ComputeIntrinsicSizingInfo(legacy_sizing_info);
   if (!*computed_inline_size && legacy_sizing_info.has_width)
     *computed_inline_size = LayoutUnit(legacy_sizing_info.size.Width());
   if (!*computed_block_size && legacy_sizing_info.has_height)
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
index d143033..65bcca6 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
@@ -112,7 +112,7 @@
   }
   bool ListMarkerOccupiesWholeLine() const {
     DCHECK(IsListMarker());
-    return To<LayoutNGOutsideListMarker>(box_.Get())->NeedsOccupyWholeLine();
+    return To<LayoutNGOutsideListMarker>(box_)->NeedsOccupyWholeLine();
   }
   bool IsButton() const { return IsBlock() && box_->IsLayoutNGButton(); }
   bool IsFieldsetContainer() const {
@@ -190,7 +190,7 @@
   // Returns true if this node should pass its percentage resolution block-size
   // to its children. Typically only quirks-mode, auto block-size, block nodes.
   bool UseParentPercentageResolutionBlockSizeForChildren() const {
-    auto* layout_block = DynamicTo<LayoutBlock>(box_.Get());
+    auto* layout_block = DynamicTo<LayoutBlock>(box_);
     if (IsBlock() && layout_block) {
       return LayoutBoxUtils::SkipContainingBlockForPercentHeightCalculation(
           layout_block);
@@ -315,8 +315,6 @@
   void ShowNodeTree() const;
 #endif
 
-  void Trace(Visitor* visitor) const { visitor->Trace(box_); }
-
  protected:
   NGLayoutInputNode(LayoutBox* box, NGLayoutInputNodeType type)
       : box_(box), type_(type) {}
@@ -325,7 +323,7 @@
       base::Optional<LayoutUnit>* computed_inline_size,
       base::Optional<LayoutUnit>* computed_block_size) const;
 
-  Member<LayoutBox> box_;
+  LayoutBox* box_;
 
   unsigned type_ : 1;  // NGLayoutInputNodeType
 };
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator.cc
index 6f864b4..53003f9 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/layout/ng/ng_layout_overflow_calculator.h"
 
+#include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
 #include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h"
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
index e51269b7..543c18f6f 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
@@ -13,21 +13,19 @@
 #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_positioned_float.h"
 #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/wtf/size_assertions.h"
 
 namespace blink {
 
 namespace {
 
-struct SameSizeAsNGLayoutResult
-    : public GarbageCollected<SameSizeAsNGLayoutResult> {
+struct SameSizeAsNGLayoutResult : public RefCounted<SameSizeAsNGLayoutResult> {
   const NGConstraintSpace space;
-  Member<void*> physical_fragment;
-  Member<void*> rare_data_;
+  void* physical_fragment;
   union {
     NGBfcOffset bfc_offset;
     LogicalOffset oof_positioned_offset;
+    void* rare_data;
   };
   LayoutUnit intrinsic_block_size;
   unsigned bitfields[1];
@@ -42,18 +40,20 @@
 }  // namespace
 
 // static
-const NGLayoutResult* NGLayoutResult::CloneWithPostLayoutFragments(
+scoped_refptr<const NGLayoutResult>
+NGLayoutResult::CloneWithPostLayoutFragments(
     const NGLayoutResult& other,
     const base::Optional<PhysicalRect> updated_layout_overflow) {
-  return MakeGarbageCollected<NGLayoutResult>(
+  return base::AdoptRef(new NGLayoutResult(
       other, NGPhysicalBoxFragment::CloneWithPostLayoutFragments(
                  To<NGPhysicalBoxFragment>(other.PhysicalFragment()),
-                 updated_layout_overflow));
+                 updated_layout_overflow)));
 }
 
-NGLayoutResult::NGLayoutResult(NGBoxFragmentBuilderPassKey passkey,
-                               const NGPhysicalFragment* physical_fragment,
-                               NGBoxFragmentBuilder* builder)
+NGLayoutResult::NGLayoutResult(
+    NGBoxFragmentBuilderPassKey passkey,
+    scoped_refptr<const NGPhysicalFragment> physical_fragment,
+    NGBoxFragmentBuilder* builder)
     : NGLayoutResult(std::move(physical_fragment),
                      static_cast<NGContainerFragmentBuilder*>(builder)) {
   bitfields_.is_initial_block_size_indefinite =
@@ -107,9 +107,10 @@
     EnsureRareData()->grid_layout_data_ = std::move(builder->grid_data_);
 }
 
-NGLayoutResult::NGLayoutResult(NGLineBoxFragmentBuilderPassKey passkey,
-                               const NGPhysicalFragment* physical_fragment,
-                               NGLineBoxFragmentBuilder* builder)
+NGLayoutResult::NGLayoutResult(
+    NGLineBoxFragmentBuilderPassKey passkey,
+    scoped_refptr<const NGPhysicalFragment> physical_fragment,
+    NGLineBoxFragmentBuilder* builder)
     : NGLayoutResult(std::move(physical_fragment),
                      static_cast<NGContainerFragmentBuilder*>(builder)) {}
 
@@ -136,7 +137,7 @@
       intrinsic_block_size_(other.intrinsic_block_size_),
       bitfields_(other.bitfields_) {
   if (HasRareData()) {
-    rare_data_ = MakeGarbageCollected<RareData>(*other.rare_data_);
+    rare_data_ = new RareData(*other.rare_data_);
     rare_data_->bfc_line_offset = bfc_line_offset;
     rare_data_->bfc_block_offset = bfc_block_offset;
   } else if (!bitfields_.has_oof_positioned_offset) {
@@ -168,14 +169,15 @@
 #endif
 }
 
-NGLayoutResult::NGLayoutResult(const NGLayoutResult& other,
-                               const NGPhysicalFragment* physical_fragment)
+NGLayoutResult::NGLayoutResult(
+    const NGLayoutResult& other,
+    scoped_refptr<const NGPhysicalFragment> physical_fragment)
     : space_(other.space_),
       physical_fragment_(std::move(physical_fragment)),
       intrinsic_block_size_(other.intrinsic_block_size_),
       bitfields_(other.bitfields_) {
   if (HasRareData()) {
-    rare_data_ = MakeGarbageCollected<RareData>(*other.rare_data_);
+    rare_data_ = new RareData(*other.rare_data_);
   } else if (!bitfields_.has_oof_positioned_offset) {
     bfc_offset_ = other.bfc_offset_;
   } else {
@@ -190,8 +192,9 @@
 #endif
 }
 
-NGLayoutResult::NGLayoutResult(const NGPhysicalFragment* physical_fragment,
-                               NGContainerFragmentBuilder* builder)
+NGLayoutResult::NGLayoutResult(
+    scoped_refptr<const NGPhysicalFragment> physical_fragment,
+    NGContainerFragmentBuilder* builder)
     : space_(builder->space_ ? NGConstraintSpace(*builder->space_)
                              : NGConstraintSpace()),
       physical_fragment_(std::move(physical_fragment)),
@@ -261,6 +264,11 @@
 #endif
 }
 
+NGLayoutResult::~NGLayoutResult() {
+  if (HasRareData())
+    delete rare_data_;
+}
+
 NGExclusionSpace NGLayoutResult::MergeExclusionSpaces(
     const NGLayoutResult& other,
     const NGExclusionSpace& new_input_exclusion_space,
@@ -280,8 +288,7 @@
     base::Optional<LayoutUnit> bfc_block_offset;
     if (!bitfields_.is_bfc_block_offset_nullopt)
       bfc_block_offset = bfc_offset_.block_offset;
-    rare_data_ = MakeGarbageCollected<RareData>(bfc_offset_.line_offset,
-                                                bfc_block_offset);
+    rare_data_ = new RareData(bfc_offset_.line_offset, bfc_block_offset);
     bitfields_.has_rare_data = true;
   }
 
@@ -342,17 +349,4 @@
 }
 #endif
 
-void NGLayoutResult::Trace(Visitor* visitor) const {
-  visitor->Trace(space_);
-  visitor->Trace(physical_fragment_);
-  visitor->Trace(rare_data_);
-}
-
-void NGLayoutResult::RareData::Trace(Visitor* visitor) const {
-  visitor->Trace(early_break);
-  visitor->Trace(unpositioned_list_marker);
-  visitor->Trace(column_spanner);
-  visitor->Trace(exclusion_space);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
index 664ad19..49db829 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_LAYOUT_RESULT_H_
 
 #include "base/dcheck_is_on.h"
+#include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h"
@@ -21,7 +22,6 @@
 #include "third_party/blink/renderer/core/layout/ng/ng_link.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
 #include "third_party/blink/renderer/core/style/computed_style_constants.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
@@ -37,8 +37,7 @@
 // necessary during layout and stored on this object.
 // Layout code should access the NGPhysicalFragment through the wrappers in
 // NGFragment et al.
-class CORE_EXPORT NGLayoutResult final
-    : public GarbageCollected<NGLayoutResult> {
+class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
  public:
   enum EStatus {
     kSuccess = 0,
@@ -53,7 +52,7 @@
 
   // Creates a copy of |other| but uses the "post-layout" fragments to ensure
   // fragment-tree consistency.
-  static const NGLayoutResult* CloneWithPostLayoutFragments(
+  static scoped_refptr<const NGLayoutResult> CloneWithPostLayoutFragments(
       const NGLayoutResult& other,
       const base::Optional<PhysicalRect> updated_layout_overflow =
           base::nullopt);
@@ -67,29 +66,7 @@
                  LayoutUnit bfc_line_offset,
                  base::Optional<LayoutUnit> bfc_block_offset,
                  LayoutUnit block_offset_delta);
-
-  // Creates a copy of NGLayoutResult with a new (but "identical") fragment.
-  NGLayoutResult(const NGLayoutResult& other,
-                 const NGPhysicalFragment* physical_fragment);
-
-  // Delegate constructor that sets up what it can, based on the builder.
-  NGLayoutResult(const NGPhysicalFragment* physical_fragment,
-                 NGContainerFragmentBuilder* builder);
-
-  // We don't need the copy constructor, move constructor, copy
-  // assigmnment-operator, or move assignment-operator today.
-  // Delete these to clarify that they will not work because a |RefCounted|
-  // object can't be copied directly.
-  //
-  // If at some point we do need these constructors particular care will need
-  // to be taken with the |rare_data_| field which is manually memory managed.
-  NGLayoutResult(const NGLayoutResult&) = delete;
-  NGLayoutResult(NGLayoutResult&&) = delete;
-  NGLayoutResult& operator=(const NGLayoutResult& other) = delete;
-  NGLayoutResult& operator=(NGLayoutResult&& other) = delete;
-  NGLayoutResult() = delete;
-
-  ~NGLayoutResult() = default;
+  ~NGLayoutResult();
 
   const NGPhysicalFragment& PhysicalFragment() const {
     DCHECK(physical_fragment_);
@@ -141,7 +118,7 @@
     return HasRareData() ? rare_data_->column_spanner : NGBlockNode(nullptr);
   }
 
-  const NGEarlyBreak* GetEarlyBreak() const {
+  scoped_refptr<const NGEarlyBreak> GetEarlyBreak() const {
     if (!HasRareData())
       return nullptr;
     return rare_data_->early_break;
@@ -385,17 +362,15 @@
   NGLayoutResult(NGBoxFragmentBuilderPassKey, EStatus, NGBoxFragmentBuilder*);
   // This constructor requires a non-null fragment and sets a success status.
   NGLayoutResult(NGBoxFragmentBuilderPassKey,
-                 const NGPhysicalFragment* physical_fragment,
+                 scoped_refptr<const NGPhysicalFragment> physical_fragment,
                  NGBoxFragmentBuilder*);
   using NGLineBoxFragmentBuilderPassKey =
       base::PassKey<NGLineBoxFragmentBuilder>;
   // This constructor requires a non-null fragment and sets a success status.
   NGLayoutResult(NGLineBoxFragmentBuilderPassKey,
-                 const NGPhysicalFragment* physical_fragment,
+                 scoped_refptr<const NGPhysicalFragment> physical_fragment,
                  NGLineBoxFragmentBuilder*);
 
-  void Trace(Visitor*) const;
-
   // See https://mathml-refresh.github.io/mathml-core/#box-model
   struct MathData {
     LayoutUnit italic_correction_;
@@ -404,6 +379,26 @@
  private:
   friend class MutableForOutOfFlow;
 
+  // Creates a copy of NGLayoutResult with a new (but "identical") fragment.
+  NGLayoutResult(const NGLayoutResult& other,
+                 scoped_refptr<const NGPhysicalFragment> physical_fragment);
+
+  // Delegate constructor that sets up what it can, based on the builder.
+  NGLayoutResult(scoped_refptr<const NGPhysicalFragment> physical_fragment,
+                 NGContainerFragmentBuilder* builder);
+
+  // We don't need the copy constructor, move constructor, copy
+  // assigmnment-operator, or move assignment-operator today.
+  // Delete these to clarify that they will not work because a |RefCounted|
+  // object can't be copied directly.
+  //
+  // If at some point we do need these constructors particular care will need
+  // to be taken with the |rare_data_| field which is manually memory managed.
+  NGLayoutResult(const NGLayoutResult&) = delete;
+  NGLayoutResult(NGLayoutResult&&) = delete;
+  NGLayoutResult& operator=(const NGLayoutResult& other) = delete;
+  NGLayoutResult& operator=(NGLayoutResult&& other) = delete;
+  NGLayoutResult() = delete;
 
   static NGExclusionSpace MergeExclusionSpaces(
       const NGLayoutResult& other,
@@ -411,7 +406,9 @@
       LayoutUnit bfc_line_offset,
       LayoutUnit block_offset_delta);
 
-  struct RareData final : public GarbageCollected<RareData> {
+  struct RareData {
+    USING_FAST_MALLOC(RareData);
+
    public:
     RareData(LayoutUnit bfc_line_offset,
              base::Optional<LayoutUnit> bfc_block_offset)
@@ -442,12 +439,10 @@
       }
     }
 
-    void Trace(Visitor* visitor) const;
-
     LayoutUnit bfc_line_offset;
     base::Optional<LayoutUnit> bfc_block_offset;
 
-    Member<const NGEarlyBreak> early_break;
+    scoped_refptr<const NGEarlyBreak> early_break;
     NGBreakAppeal early_break_appeal = kBreakAppealLastResort;
     LogicalOffset oof_positioned_offset;
     NGMarginStrut end_margin_strut;
@@ -477,9 +472,7 @@
     std::unique_ptr<const NGGridData> grid_layout_data_;
     base::Optional<MathData> math_layout_data_;
   };
-  // |HasRareData()| should always return the same value to ensure that Trace()
-  // method works correctly, so |EnsureRareData()| cannot be called except in
-  // ctor.
+
   bool HasRareData() const { return bitfields_.has_rare_data; }
   RareData* EnsureRareData();
 
@@ -491,6 +484,8 @@
     DISALLOW_NEW();
 
    public:
+    // We define the default constructor so that the |has_rare_data| bit is
+    // never uninitialized (potentially allowing a dangling pointer).
     Bitfields()
         : Bitfields(
               /* is_self_collapsing */ false,
@@ -546,11 +541,9 @@
   // as indicated by |has_valid_space_|.
   const NGConstraintSpace space_;
 
-  Member<const NGPhysicalFragment> physical_fragment_;
+  scoped_refptr<const NGPhysicalFragment> physical_fragment_;
 
-  // |rare_data_| is not stored in the union because |Bitfields::has_rare_data|
-  // is not initialized in constructor's initializer list and it cannot be
-  // checked in Trace() in this case.
+  // To save space, we union these fields.
   //  - |rare_data_| is valid if the |Bitfields::has_rare_data| bit is set.
   //    |bfc_offset_| and |oof_positioned_offset_| are stored within the
   //    |RareData| object for this case.
@@ -558,13 +551,13 @@
   //    |Bitfields::has_oof_positioned_offset| bit is set. As the node is
   //    OOF-positioned the |bfc_offset_| is *always* the initial value.
   //  - Otherwise |bfc_offset_| is valid.
-  Member<RareData> rare_data_;
   union {
     NGBfcOffset bfc_offset_;
     // This is the final position of an OOF-positioned object in its parent's
     // writing-mode. This is set by the |NGOutOfFlowLayoutPart| while
     // generating this layout result.
     LogicalOffset oof_positioned_offset_;
+    RareData* rare_data_;
   };
 
   LayoutUnit intrinsic_block_size_;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc
index b43a3914..2336a94 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc
@@ -46,11 +46,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
   EXPECT_EQ(result->BfcBlockOffset().value(), LayoutUnit(50));
   EXPECT_EQ(result->BfcLineOffset(), LayoutUnit());
 }
@@ -87,11 +87,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
   EXPECT_EQ(result->BfcBlockOffset().value(), LayoutUnit(40));
   EXPECT_EQ(result->BfcLineOffset(), LayoutUnit());
 
@@ -151,11 +151,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissDescendantAboveBlockStart1) {
@@ -189,11 +189,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissDescendantAboveBlockStart2) {
@@ -227,11 +227,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitOOFDescendantAboveBlockStart) {
@@ -265,11 +265,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitLineBoxDescendantAboveBlockStart) {
@@ -308,11 +308,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissFloatInitiallyIntruding1) {
@@ -344,11 +344,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissFloatInitiallyIntruding2) {
@@ -380,11 +380,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissFloatWillIntrude1) {
@@ -415,11 +415,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissFloatWillIntrude2) {
@@ -450,11 +450,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitPushedByFloats1) {
@@ -485,11 +485,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitPushedByFloats2) {
@@ -520,11 +520,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissPushedByFloats1) {
@@ -556,11 +556,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissPushedByFloats2) {
@@ -592,11 +592,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitDifferentRareData) {
@@ -621,11 +621,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitPercentageMinWidth) {
@@ -650,11 +650,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitFixedMinWidth) {
@@ -679,11 +679,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitShrinkToFit) {
@@ -721,12 +721,12 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
   // test1 was sized to its max-content size, passing an available size larger
   // than the fragment should hit the cache.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   fragment_geometry.reset();
   space = src2->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
@@ -735,7 +735,7 @@
   // test2 was sized to its min-content size in, passing an available size
   // smaller than the fragment should hit the cache.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissShrinkToFit) {
@@ -795,12 +795,12 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
   // test1 was sized to its max-content size, passing an available size smaller
   // than the fragment should miss the cache.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 
   fragment_geometry.reset();
   space = src2->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
@@ -809,7 +809,7 @@
   // test2 was sized to its min-content size, passing an available size
   // larger than the fragment should miss the cache.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 
   fragment_geometry.reset();
   space = src3->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
@@ -818,7 +818,7 @@
   // test3 was sized to its min-content size, however it should miss the cache
   // as it has a %-min-size.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 
   fragment_geometry.reset();
   space = src4->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
@@ -827,7 +827,7 @@
   // test4 was sized to its max-content size, however it should miss the cache
   // due to its margin.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitShrinkToFitSameIntrinsicSizes) {
@@ -858,11 +858,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitShrinkToFitDifferentParent) {
@@ -892,11 +892,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissQuirksModePercentageBasedChild) {
@@ -926,11 +926,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitQuirksModePercentageBasedParentAndChild) {
@@ -965,11 +965,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitStandardsModePercentageBasedChild) {
@@ -998,11 +998,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, ChangeTableCellBlockSizeConstrainedness) {
@@ -1044,12 +1044,12 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
   // The first child has a fixed height, and shouldn't be affected by the cell
   // height.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   fragment_geometry.reset();
   space = src2->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
@@ -1059,7 +1059,7 @@
   // intrinsic height is identical to its extrinsic height (when the cell has a
   // height). So it won't need layout, either.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   fragment_geometry.reset();
   space = src3->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
@@ -1151,13 +1151,13 @@
 
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   // Case 1: We have a different set of constraints, but as the child has no
   // adjoining descendants it can be shifted anywhere.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   fragment_geometry.reset();
   space = src2->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
@@ -1167,7 +1167,7 @@
   // Case 2: We have a different set of constraints, but the child has an
   // adjoining object and isn't "past" the floats - it can't be reused.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 
   fragment_geometry.reset();
   space = src3->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
@@ -1177,7 +1177,7 @@
   // Case 3: We have a different set of constraints, and adjoining descendants,
   // but have a position past where they might affect us.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, ClearancePastAdjoiningFloatsMovement) {
@@ -1227,12 +1227,12 @@
 
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   // Case 1: We have forced clearance, but floats won't impact our children.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   fragment_geometry.reset();
   space = src2->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
@@ -1241,7 +1241,7 @@
 
   // Case 2: We have forced clearance, and floats will impact our children.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MarginStrutMovementSelfCollapsing) {
@@ -1289,13 +1289,13 @@
 
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   // Case 1: We can safely re-use this fragment as it doesn't append anything
   // to the margin-strut within the sub-tree.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   // The "end" margin-strut should be updated.
   NGMarginStrut expected_margin_strut;
@@ -1310,7 +1310,7 @@
   // Case 2: We can't re-use this fragment as it appended a non-zero value to
   // the margin-strut within the sub-tree.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MarginStrutMovementInFlow) {
@@ -1380,13 +1380,13 @@
 
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   // Case 1: We can safely re-use this fragment as it doesn't append anything
   // to the margin-strut within the sub-tree.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   fragment_geometry.reset();
   space = src2->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
@@ -1396,7 +1396,7 @@
   // Case 2: We can't re-use this fragment as it appended a non-zero value to
   // the margin-strut within the sub-tree.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 
   fragment_geometry.reset();
   space = src3->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
@@ -1406,7 +1406,7 @@
   // Case 3: We can't re-use this fragment as a (inner) self-collapsing block
   // appended a non-zero value to the margin-strut within the sub-tree.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MarginStrutMovementPercentage) {
@@ -1438,13 +1438,13 @@
 
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   // We can't re-use this fragment as it appended a non-zero value (50%) to the
   // margin-strut within the sub-tree.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitIsFixedBlockSizeIndefinite) {
@@ -1469,14 +1469,14 @@
 
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   // Even though the "align-items: stretch" will make the final fixed
   // block-size indefinite, we don't have any %-block-size children, so we can
   // hit the cache.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissIsFixedBlockSizeIndefinite) {
@@ -1502,14 +1502,14 @@
 
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   // The "align-items: stretch" will make the final fixed block-size
   // indefinite, and we have a %-block-size child, so we need to miss the
   // cache.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitColumnFlexBoxMeasureAndLayout) {
@@ -1546,12 +1546,12 @@
   // cache-slot for "test1".
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(space.CacheSlot(), NGCacheSlot::kMeasure);
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   // "src2" had both a "measure" and "layout" pass performed, and should hit
   // the "layout" cache-slot for "test1".
@@ -1561,7 +1561,7 @@
 
   EXPECT_EQ(space.CacheSlot(), NGCacheSlot::kLayout);
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitRowFlexBoxMeasureAndLayout) {
@@ -1600,12 +1600,12 @@
   // cache-slot for "test1".
   NGConstraintSpace space =
       src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test1->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(space.CacheSlot(), NGCacheSlot::kMeasure);
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 
   // "src2" had both a "measure" and "layout" pass performed, and should hit
   // the "layout" cache-slot for "test1".
@@ -1615,7 +1615,7 @@
 
   EXPECT_EQ(space.CacheSlot(), NGCacheSlot::kLayout);
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitFlexLegacyImg) {
@@ -1643,11 +1643,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitFlexLegacyGrid) {
@@ -1676,11 +1676,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitFlexDefiniteChange) {
@@ -1694,14 +1694,16 @@
 
   auto* target1 = To<LayoutBlock>(GetLayoutObjectByElementId("target1"));
 
-  const NGLayoutResult* result1 = target1->GetCachedLayoutResult();
-  const NGLayoutResult* measure1 = target1->GetCachedMeasureResult();
+  scoped_refptr<const NGLayoutResult> result1 =
+      target1->GetCachedLayoutResult();
+  scoped_refptr<const NGLayoutResult> measure1 =
+      target1->GetCachedMeasureResult();
   EXPECT_EQ(measure1->IntrinsicBlockSize(), 100);
   EXPECT_EQ(result1->PhysicalFragment().Size().height, 200);
 
   EXPECT_EQ(result1->GetConstraintSpaceForCaching().CacheSlot(),
             NGCacheSlot::kMeasure);
-  EXPECT_EQ(result1, measure1);
+  EXPECT_EQ(result1.get(), measure1.get());
 }
 
 TEST_F(NGLayoutResultCachingTest, HitOrthogonalRoot) {
@@ -1722,12 +1724,12 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       target->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = target->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = target->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   // We should hit the cache using the same constraint space.
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, SimpleTable) {
@@ -1745,19 +1747,23 @@
 
   // Both "target1", and "target1" should have  only had one "measure" pass
   // performed.
-  const NGLayoutResult* result1 = target1->GetCachedLayoutResult();
-  const NGLayoutResult* measure1 = target1->GetCachedMeasureResult();
+  scoped_refptr<const NGLayoutResult> result1 =
+      target1->GetCachedLayoutResult();
+  scoped_refptr<const NGLayoutResult> measure1 =
+      target1->GetCachedMeasureResult();
   EXPECT_EQ(result1->GetConstraintSpaceForCaching().CacheSlot(),
             NGCacheSlot::kMeasure);
-  EXPECT_NE(result1, nullptr);
-  EXPECT_EQ(result1, measure1);
+  EXPECT_NE(result1.get(), nullptr);
+  EXPECT_EQ(result1.get(), measure1.get());
 
-  const NGLayoutResult* result2 = target2->GetCachedLayoutResult();
-  const NGLayoutResult* measure2 = target2->GetCachedMeasureResult();
+  scoped_refptr<const NGLayoutResult> result2 =
+      target2->GetCachedLayoutResult();
+  scoped_refptr<const NGLayoutResult> measure2 =
+      target2->GetCachedMeasureResult();
   EXPECT_EQ(result2->GetConstraintSpaceForCaching().CacheSlot(),
             NGCacheSlot::kMeasure);
-  EXPECT_NE(result2, nullptr);
-  EXPECT_EQ(result2, measure2);
+  EXPECT_NE(result2.get(), nullptr);
+  EXPECT_EQ(result2.get(), measure2.get());
 }
 
 TEST_F(NGLayoutResultCachingTest, MissTableCellMiddleAlignment) {
@@ -1773,15 +1779,16 @@
   auto* target = To<LayoutBlock>(GetLayoutObjectByElementId("target"));
 
   // "target" should be stretched, and miss the measure cache.
-  const NGLayoutResult* result = target->GetCachedLayoutResult();
-  const NGLayoutResult* measure = target->GetCachedMeasureResult();
-  EXPECT_NE(measure, nullptr);
-  EXPECT_NE(result, nullptr);
+  scoped_refptr<const NGLayoutResult> result = target->GetCachedLayoutResult();
+  scoped_refptr<const NGLayoutResult> measure =
+      target->GetCachedMeasureResult();
+  EXPECT_NE(measure.get(), nullptr);
+  EXPECT_NE(result.get(), nullptr);
   EXPECT_EQ(measure->GetConstraintSpaceForCaching().CacheSlot(),
             NGCacheSlot::kMeasure);
   EXPECT_EQ(result->GetConstraintSpaceForCaching().CacheSlot(),
             NGCacheSlot::kLayout);
-  EXPECT_NE(result, measure);
+  EXPECT_NE(result.get(), measure.get());
 }
 
 TEST_F(NGLayoutResultCachingTest, MissTableCellBottomAlignment) {
@@ -1797,15 +1804,16 @@
   auto* target = To<LayoutBlock>(GetLayoutObjectByElementId("target"));
 
   // "target" should be stretched, and miss the measure cache.
-  const NGLayoutResult* result = target->GetCachedLayoutResult();
-  const NGLayoutResult* measure = target->GetCachedMeasureResult();
-  EXPECT_NE(measure, nullptr);
-  EXPECT_NE(result, nullptr);
+  scoped_refptr<const NGLayoutResult> result = target->GetCachedLayoutResult();
+  scoped_refptr<const NGLayoutResult> measure =
+      target->GetCachedMeasureResult();
+  EXPECT_NE(measure.get(), nullptr);
+  EXPECT_NE(result.get(), nullptr);
   EXPECT_EQ(measure->GetConstraintSpaceForCaching().CacheSlot(),
             NGCacheSlot::kMeasure);
   EXPECT_EQ(result->GetConstraintSpaceForCaching().CacheSlot(),
             NGCacheSlot::kLayout);
-  EXPECT_NE(result, measure);
+  EXPECT_NE(result.get(), measure.get());
 }
 
 TEST_F(NGLayoutResultCachingTest, HitTableCellBaselineAlignment) {
@@ -1824,12 +1832,13 @@
   auto* target = To<LayoutBlock>(GetLayoutObjectByElementId("target"));
 
   // "target" should align to the baseline, but hit the cache.
-  const NGLayoutResult* result = target->GetCachedLayoutResult();
-  const NGLayoutResult* measure = target->GetCachedMeasureResult();
+  scoped_refptr<const NGLayoutResult> result = target->GetCachedLayoutResult();
+  scoped_refptr<const NGLayoutResult> measure =
+      target->GetCachedMeasureResult();
   EXPECT_EQ(result->GetConstraintSpaceForCaching().CacheSlot(),
             NGCacheSlot::kMeasure);
-  EXPECT_NE(result, nullptr);
-  EXPECT_EQ(result, measure);
+  EXPECT_NE(result.get(), nullptr);
+  EXPECT_EQ(result.get(), measure.get());
 }
 
 TEST_F(NGLayoutResultCachingTest, MissTableCellBaselineAlignment) {
@@ -1848,15 +1857,16 @@
   auto* target = To<LayoutBlock>(GetLayoutObjectByElementId("target"));
 
   // "target" should align to the baseline, but miss the cache.
-  const NGLayoutResult* result = target->GetCachedLayoutResult();
-  const NGLayoutResult* measure = target->GetCachedMeasureResult();
-  EXPECT_NE(measure, nullptr);
-  EXPECT_NE(result, nullptr);
+  scoped_refptr<const NGLayoutResult> result = target->GetCachedLayoutResult();
+  scoped_refptr<const NGLayoutResult> measure =
+      target->GetCachedMeasureResult();
+  EXPECT_NE(measure.get(), nullptr);
+  EXPECT_NE(result.get(), nullptr);
   EXPECT_EQ(measure->GetConstraintSpaceForCaching().CacheSlot(),
             NGCacheSlot::kMeasure);
   EXPECT_EQ(result->GetConstraintSpaceForCaching().CacheSlot(),
             NGCacheSlot::kLayout);
-  EXPECT_NE(result, measure);
+  EXPECT_NE(result.get(), measure.get());
 }
 
 TEST_F(NGLayoutResultCachingTest, MissTablePercent) {
@@ -1889,11 +1899,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitTableRowAdd) {
@@ -1916,11 +1926,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissTableRowAdd) {
@@ -1943,11 +1953,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitTableRowRemove) {
@@ -1970,11 +1980,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissTableRowRemove) {
@@ -1997,11 +2007,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
-  EXPECT_EQ(result, nullptr);
+  EXPECT_EQ(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitTableSectionAdd) {
@@ -2024,11 +2034,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, HitTableSectionRemove) {
@@ -2051,11 +2061,11 @@
   base::Optional<NGFragmentGeometry> fragment_geometry;
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
-  EXPECT_NE(result, nullptr);
+  EXPECT_NE(result.get(), nullptr);
 }
 
 TEST_F(NGLayoutResultCachingTest, MissFragmentainerSizeChange) {
@@ -2165,7 +2175,7 @@
   ASSERT_NE(test->GetCachedLayoutResult(), nullptr);
   const NGConstraintSpace& space =
       src->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
-  const NGLayoutResult* result = test->CachedLayoutResult(
+  scoped_refptr<const NGLayoutResult> result = test->CachedLayoutResult(
       space, nullptr, nullptr, &fragment_geometry, &cache_status);
 
   EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc
index e1a564d..ea00c7f63 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc
@@ -86,7 +86,7 @@
         constraint_space, *style_, border_padding, length, content_size);
   }
 
-  Persistent<ComputedStyle> style_;
+  scoped_refptr<ComputedStyle> style_;
 };
 
 class NGLengthUtilsTestWithNode : public NGLayoutTest {
@@ -124,7 +124,7 @@
         constraint_space, *style_, border_padding, content_size, inline_size);
   }
 
-  Persistent<ComputedStyle> style_;
+  scoped_refptr<ComputedStyle> style_;
 };
 
 TEST_F(NGLengthUtilsTest, TestResolveInlineLength) {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_link.h b/third_party/blink/renderer/core/layout/ng/ng_link.h
index ca29701..880e83dd 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_link.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_link.h
@@ -19,9 +19,6 @@
 // NGPhysicalFragment. It cannot have destructors. Fragment reference
 // counting is done manually.
 struct CORE_EXPORT NGLink {
-  DISALLOW_NEW();
-
- public:
   PhysicalOffset Offset() const { return offset; }
   const NGPhysicalFragment* get() const { return fragment; }
 
@@ -29,14 +26,10 @@
   const NGPhysicalFragment& operator*() const { return *fragment; }
   const NGPhysicalFragment* operator->() const { return fragment; }
 
-  void Trace(Visitor* visitor) const { visitor->Trace(fragment); }
-
-  Member<const NGPhysicalFragment> fragment;
+  const NGPhysicalFragment* fragment;
   PhysicalOffset offset;
 };
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::NGLink)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_LINK_H_
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
index 20f89ce..c35d5a59 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -131,9 +131,7 @@
            container_builder_->HasMulticolsWithPendingOOFs()) {
       HandleMulticolsWithPendingOOFs(container_builder_);
       if (container_builder_->HasOutOfFlowFragmentainerDescendants()) {
-        HeapVector<NGLogicalOutOfFlowPositionedNode> fragmentainer_descendants;
-        ClearCollectionScope<HeapVector<NGLogicalOutOfFlowPositionedNode>>
-            clear_scope(&fragmentainer_descendants);
+        Vector<NGLogicalOutOfFlowPositionedNode> fragmentainer_descendants;
         container_builder_->SwapOutOfFlowFragmentainerDescendants(
             &fragmentainer_descendants);
         DCHECK(!fragmentainer_descendants.IsEmpty());
@@ -160,9 +158,7 @@
   if (current_container->ChildLayoutBlockedByDisplayLock())
     return;
 
-  HeapVector<NGLogicalOutOfFlowPositionedNode> candidates;
-  ClearCollectionScope<HeapVector<NGLogicalOutOfFlowPositionedNode>>
-      clear_scope(&candidates);
+  Vector<NGLogicalOutOfFlowPositionedNode> candidates;
   container_builder_->SwapOutOfFlowPositionedCandidates(&candidates);
 
   // Special case: containing block is a split inline.
@@ -196,7 +192,7 @@
     return;
   }
 
-  HeapHashSet<Member<const LayoutObject>> placed_objects;
+  HashSet<const LayoutObject*> placed_objects;
   LayoutCandidates(&candidates, only_layout, &placed_objects);
 
   if (only_layout)
@@ -245,7 +241,7 @@
 // </div>
 // Returns false if no new candidates were found.
 bool NGOutOfFlowLayoutPart::SweepLegacyCandidates(
-    HeapHashSet<Member<const LayoutObject>>* placed_objects) {
+    HashSet<const LayoutObject*>* placed_objects) {
   const auto* container_block =
       DynamicTo<LayoutBlock>(container_builder_->GetLayoutObject());
   if (!container_block)
@@ -320,7 +316,7 @@
     DCHECK(container_builder_->IsBlockFragmentationContextRoot());
 
     const NGPhysicalFragment* containing_block_fragment =
-        candidate.containing_block.fragment;
+        candidate.containing_block.fragment.get();
     const LayoutObject* containing_block =
         containing_block_fragment->GetLayoutObject();
     DCHECK(containing_block);
@@ -361,14 +357,14 @@
 }
 
 void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
-    const HeapVector<NGLogicalOutOfFlowPositionedNode>& candidates) {
+    const Vector<NGLogicalOutOfFlowPositionedNode>& candidates) {
   NGBoxFragmentBuilder::InlineContainingBlockMap inline_container_fragments;
 
   for (auto& candidate : candidates) {
     if (candidate.inline_container &&
         !inline_container_fragments.Contains(candidate.inline_container)) {
       NGBoxFragmentBuilder::InlineContainingBlockGeometry inline_geometry = {};
-      inline_container_fragments.insert(candidate.inline_container.Get(),
+      inline_container_fragments.insert(candidate.inline_container,
                                         inline_geometry);
     }
   }
@@ -504,9 +500,9 @@
 }
 
 void NGOutOfFlowLayoutPart::LayoutCandidates(
-    HeapVector<NGLogicalOutOfFlowPositionedNode>* candidates,
+    Vector<NGLogicalOutOfFlowPositionedNode>* candidates,
     const LayoutBox* only_layout,
-    HeapHashSet<Member<const LayoutObject>>* placed_objects) {
+    HashSet<const LayoutObject*>* placed_objects) {
   while (candidates->size() > 0) {
     ComputeInlineContainingBlocks(*candidates);
     for (auto& candidate : *candidates) {
@@ -527,7 +523,7 @@
         NodeInfo node_info = SetupNodeInfo(candidate);
         NodeToLayout node_to_layout = {node_info,
                                        CalculateOffset(node_info, only_layout)};
-        const NGLayoutResult* result =
+        scoped_refptr<const NGLayoutResult> result =
             LayoutOOFNode(node_to_layout, only_layout);
         container_builder_->AddChild(result->PhysicalFragment(),
                                      result->OutOfFlowPositionedOffset(),
@@ -555,7 +551,7 @@
 
   while (!multicols_with_pending_oofs.IsEmpty()) {
     for (auto& multicol : multicols_with_pending_oofs)
-      LayoutOOFsInMulticol(NGBlockNode(multicol.key), multicol.value);
+      LayoutOOFsInMulticol(NGBlockNode(multicol.key), &multicol.value);
     multicols_with_pending_oofs.clear();
     container_builder->SwapMulticolsWithPendingOOFs(
         &multicols_with_pending_oofs);
@@ -565,8 +561,8 @@
 void NGOutOfFlowLayoutPart::LayoutOOFsInMulticol(
     const NGBlockNode& multicol,
     const NGMulticolWithPendingOOFs<LogicalOffset>* multicol_info) {
-  HeapVector<NGLogicalOutOfFlowPositionedNode> oof_nodes_to_layout;
-  HeapVector<MulticolChildInfo> multicol_children;
+  Vector<NGLogicalOutOfFlowPositionedNode> oof_nodes_to_layout;
+  Vector<MulticolChildInfo> multicol_children;
 
   const NGBlockBreakToken* current_column_break_token = nullptr;
   const NGBlockBreakToken* previous_multicol_break_token = nullptr;
@@ -641,7 +637,7 @@
       // parent's list of break tokens.
       const auto children = break_token->ChildBreakTokens();
       const NGBlockBreakToken* child_token =
-          To<NGBlockBreakToken>(children[children.size() - 1].Get());
+          To<NGBlockBreakToken>(children[children.size() - 1]);
       if (child_token == current_column_break_token) {
         MulticolChildInfo& child_info = multicol_children[current_column_index];
         child_info.parent_break_token = break_token;
@@ -664,7 +660,7 @@
             previous_multicol_break_token->ConsumedBlockSize();
       }
       const NGPhysicalFragment* containing_block_fragment =
-          descendant.containing_block.fragment;
+          descendant.containing_block.fragment.get();
       LogicalOffset containing_block_offset =
           converter.ToLogical(descendant.containing_block.offset,
                               containing_block_fragment->Size());
@@ -673,7 +669,7 @@
                               containing_block_fragment->Size());
 
       const NGPhysicalFragment* fixedpos_containing_block_fragment =
-          descendant.fixedpos_containing_block.fragment;
+          descendant.fixedpos_containing_block.fragment.get();
       LogicalOffset fixedpos_containing_block_offset;
       LogicalOffset fixedpos_containing_block_rel_offset;
       if (fixedpos_containing_block_fragment) {
@@ -716,7 +712,7 @@
                         &multicol_container_builder)
       .LayoutFragmentainerDescendants(
           &oof_nodes_to_layout, column_inline_progression,
-          multicol_info->fixedpos_containing_block.fragment,
+          multicol_info->fixedpos_containing_block.fragment.get(),
           &multicol_children);
 
   // Any descendants should have been handled in
@@ -734,10 +730,10 @@
 }
 
 void NGOutOfFlowLayoutPart::LayoutFragmentainerDescendants(
-    HeapVector<NGLogicalOutOfFlowPositionedNode>* descendants,
+    Vector<NGLogicalOutOfFlowPositionedNode>* descendants,
     LayoutUnit column_inline_progression,
     bool outer_context_has_fixedpos_container,
-    HeapVector<MulticolChildInfo>* multicol_children) {
+    Vector<MulticolChildInfo>* multicol_children) {
   multicol_children_ = multicol_children;
   outer_context_has_fixedpos_container_ = outer_context_has_fixedpos_container;
   DCHECK(multicol_children_ || !outer_context_has_fixedpos_container_);
@@ -747,7 +743,7 @@
                         container_builder_->BorderScrollbarPadding())
           .block_size;
 
-  HeapVector<HeapVector<NodeToLayout>> descendants_to_layout;
+  Vector<Vector<NodeToLayout>> descendants_to_layout;
   while (descendants->size() > 0) {
     // Sort the descendants by fragmentainer index in |descendants_to_layout|.
     // This will ensure that the descendants are laid out in the correct order.
@@ -756,7 +752,7 @@
       NodeToLayout node_to_layout = {
           node_info, CalculateOffset(node_info, /* only_layout */ nullptr)};
       node_to_layout.containing_block_fragment =
-          descendant.containing_block.fragment;
+          descendant.containing_block.fragment.get();
       node_to_layout.offset_info.original_offset =
           node_to_layout.offset_info.offset;
 
@@ -773,7 +769,7 @@
       descendants_to_layout[start_index].emplace_back(node_to_layout);
     }
 
-    HeapVector<NodeToLayout> fragmented_descendants;
+    Vector<NodeToLayout> fragmented_descendants;
     fragmentainer_consumed_block_size_ = LayoutUnit();
     wtf_size_t num_children = container_builder_->Children().size();
 
@@ -781,11 +777,12 @@
     for (wtf_size_t index = 0; index < descendants_to_layout.size(); index++) {
       const NGPhysicalFragment* fragment = nullptr;
       if (index < num_children)
-        fragment = container_builder_->Children()[index].fragment;
+        fragment = container_builder_->Children()[index].fragment.get();
 
       // Skip over any column spanners.
       if (!fragment || fragment->IsFragmentainerBox()) {
-        const auto& pending_descendants = descendants_to_layout[index];
+        const Vector<NodeToLayout>& pending_descendants =
+            descendants_to_layout[index];
         LayoutOOFsInFragmentainer(pending_descendants, index,
                                   column_inline_progression,
                                   &fragmented_descendants);
@@ -796,7 +793,7 @@
         // offset).
         wtf_size_t used_index =
             (!fragment && multicol_children_) ? num_children - 1 : index;
-        fragment = container_builder_->Children()[used_index].fragment;
+        fragment = container_builder_->Children()[used_index].fragment.get();
         fragmentainer_consumed_block_size_ +=
             fragment->Size()
                 .ConvertToLogical(container_builder_->Style().GetWritingMode())
@@ -823,7 +820,7 @@
     const NGLogicalOutOfFlowPositionedNode& oof_node) {
   NGBlockNode node = oof_node.Node();
   const NGPhysicalFragment* containing_block_fragment =
-      oof_node.containing_block.fragment;
+      oof_node.containing_block.fragment.get();
 
 #if DCHECK_IS_ON()
   const LayoutObject* container =
@@ -888,7 +885,7 @@
                   oof_node.inline_container);
 }
 
-const NGLayoutResult* NGOutOfFlowLayoutPart::LayoutOOFNode(
+scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::LayoutOOFNode(
     const NodeToLayout& oof_node_to_layout,
     const LayoutBox* only_layout,
     const NGConstraintSpace* fragmentainer_constraint_space) {
@@ -901,7 +898,7 @@
 
   NGBoxStrut scrollbars_before =
       ComputeScrollbarsForNonAnonymous(node_info.node);
-  const NGLayoutResult* layout_result =
+  scoped_refptr<const NGLayoutResult> layout_result =
       Layout(oof_node_to_layout, fragmentainer_constraint_space);
   NGBoxStrut scrollbars_after =
       ComputeScrollbarsForNonAnonymous(node_info.node);
@@ -972,7 +969,7 @@
   // Note: Only check for cache results if this is our first layout pass.
   if (is_first_run && allow_first_tier_oof_cache_ &&
       !node_info.inline_container) {
-    if (const NGLayoutResult* cached_result =
+    if (scoped_refptr<const NGLayoutResult> cached_result =
             node_info.node.CachedLayoutResultForOutOfFlowPositioned(
                 container_content_size_in_candidate_writing_mode)) {
       offset_info.initial_layout_result = cached_result;
@@ -1012,7 +1009,8 @@
   // fragmentation, we *need* to know the block-offset before layout. In other
   // words, in that case, we may have to lay out, calculate the offset, and
   // then lay out again at the correct block-offset.
-  offset_info.block_size_depends_on_layout = offset_info.initial_layout_result;
+  offset_info.block_size_depends_on_layout =
+      offset_info.initial_layout_result.get();
 
   // Calculate the offsets.
   NGBoxStrut inset = offset_info.node_dimensions.inset
@@ -1033,7 +1031,7 @@
   return offset_info;
 }
 
-const NGLayoutResult* NGOutOfFlowLayoutPart::Layout(
+scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout(
     const NodeToLayout& oof_node_to_layout,
     const NGConstraintSpace* fragmentainer_constraint_space) {
   const NodeInfo& node_info = oof_node_to_layout.node_info;
@@ -1047,9 +1045,9 @@
 
   // Reset the |layout_result| computed earlier to allow fragmentation in the
   // next layout pass, if needed.
-  const NGLayoutResult* layout_result = !fragmentainer_constraint_space
-                                            ? offset_info.initial_layout_result
-                                            : nullptr;
+  scoped_refptr<const NGLayoutResult> layout_result =
+      !fragmentainer_constraint_space ? offset_info.initial_layout_result
+                                      : nullptr;
 
   // Skip this step if we produced a fragment that can be reused when
   // estimating the block-size.
@@ -1113,7 +1111,7 @@
 //    container's available size.
 // 2. To compute final fragment, when block size is known from the absolute
 //    position calculation.
-const NGLayoutResult* NGOutOfFlowLayoutPart::GenerateFragment(
+scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::GenerateFragment(
     NGBlockNode node,
     const LogicalSize& container_content_size_in_candidate_writing_mode,
     const base::Optional<LayoutUnit>& block_estimate,
@@ -1152,15 +1150,15 @@
 }
 
 void NGOutOfFlowLayoutPart::LayoutOOFsInFragmentainer(
-    const HeapVector<NodeToLayout>& pending_descendants,
+    const Vector<NodeToLayout>& pending_descendants,
     wtf_size_t index,
     LayoutUnit column_inline_progression,
-    HeapVector<NodeToLayout>* fragmented_descendants) {
+    Vector<NodeToLayout>* fragmented_descendants) {
   wtf_size_t num_children = container_builder_->Children().size();
   bool is_new_fragment = index >= num_children;
 
   DCHECK(fragmented_descendants);
-  HeapVector<NodeToLayout> descendants_continued;
+  Vector<NodeToLayout> descendants_continued;
   std::swap(*fragmented_descendants, descendants_continued);
 
   // If |index| is greater than the number of current children, and there are
@@ -1199,7 +1197,8 @@
   const auto& fragmentainer = container_builder_->Children()[index];
   DCHECK(fragmentainer.fragment->IsFragmentainerBox());
   const NGBlockNode& node = container_builder_->Node();
-  const auto& fragment = To<NGPhysicalBoxFragment>(*fragmentainer.fragment);
+  const auto& fragment =
+      To<NGPhysicalBoxFragment>(*fragmentainer.fragment.get());
   LogicalOffset fragmentainer_offset = UpdatedFragmentainerOffset(
       fragmentainer.offset, index, column_inline_progression,
       create_new_fragment);
@@ -1247,8 +1246,8 @@
     LogicalOffset fragmentainer_offset,
     wtf_size_t index,
     NGSimplifiedOOFLayoutAlgorithm* algorithm,
-    HeapVector<NodeToLayout>* fragmented_descendants) {
-  const NGLayoutResult* result =
+    Vector<NodeToLayout>* fragmented_descendants) {
+  scoped_refptr<const NGLayoutResult> result =
       LayoutOOFNode(descendant, /* only_layout */ nullptr, fragmentainer_space);
 
   // Apply the relative positioned offset now that fragmentation is complete.
@@ -1358,10 +1357,10 @@
   const NGBlockNode& node = container_builder_->Node();
   const auto& fragmentainer = container_builder_->Children()[index];
   const NGPhysicalBoxFragment& fragment =
-      To<NGPhysicalBoxFragment>(*fragmentainer.fragment);
+      To<NGPhysicalBoxFragment>(*fragmentainer.fragment.get());
 
   if (create_new_fragment) {
-    const NGLayoutResult* new_result = algorithm->Layout();
+    scoped_refptr<const NGLayoutResult> new_result = algorithm->Layout();
     node.AddColumnResult(new_result);
     container_builder_->AddChild(
         new_result->PhysicalFragment(), offset, /* inline_container */ nullptr,
@@ -1369,7 +1368,7 @@
         /* relative_offset */ base::nullopt,
         /* adjustment_for_oof_propagation */ base::nullopt);
   } else {
-    const NGLayoutResult* new_result = algorithm->Layout();
+    scoped_refptr<const NGLayoutResult> new_result = algorithm->Layout();
     node.ReplaceColumnResult(new_result, fragment);
     const NGPhysicalFragment* new_fragment = &new_result->PhysicalFragment();
     container_builder_->ReplaceChild(index, *new_fragment, offset);
@@ -1378,13 +1377,15 @@
       // We are in a nested fragmentation context. Replace the column entry
       // and break token directly in the existing multicol fragment.;
       MulticolChildInfo& column_info = (*multicol_children_)[index];
-      if (auto& parent_break_token = column_info.parent_break_token) {
+      if (auto* parent_break_token = column_info.parent_break_token) {
         DCHECK_GT(parent_break_token->ChildBreakTokens().size(), 0u);
         parent_break_token->GetMutableForOutOfFlow().ReplaceChildBreakToken(
             new_fragment->BreakToken(),
             parent_break_token->ChildBreakTokens().size() - 1);
       }
-      column_info.mutable_link->fragment = new_fragment;
+      column_info.mutable_link->fragment->Release();
+      new (&column_info.mutable_link->fragment)
+          scoped_refptr<const NGPhysicalFragment>(std::move(new_fragment));
     }
   }
 }
@@ -1441,7 +1442,8 @@
 
   const auto& fragmentainer = container_builder_->Children()[index];
   DCHECK(fragmentainer.fragment->IsFragmentainerBox());
-  const auto& fragment = To<NGPhysicalBoxFragment>(*fragmentainer.fragment);
+  const auto& fragment =
+      To<NGPhysicalBoxFragment>(*fragmentainer.fragment.get());
   const WritingMode container_writing_mode =
       container_builder_->Style().GetWritingMode();
   LogicalSize column_size =
@@ -1475,10 +1477,11 @@
     wtf_size_t index) const {
   const NGBlockBreakToken* previous_break_token = nullptr;
   for (wtf_size_t i = index; i > 0; --i) {
-    auto& previous_fragment = container_builder_->Children()[i - 1].fragment;
+    auto* previous_fragment =
+        container_builder_->Children()[i - 1].fragment.get();
     if (previous_fragment->IsFragmentainerBox()) {
       previous_break_token = To<NGBlockBreakToken>(
-          To<NGPhysicalBoxFragment>(previous_fragment.Get())->BreakToken());
+          To<NGPhysicalBoxFragment>(previous_fragment)->BreakToken());
       break;
     }
   }
@@ -1575,25 +1578,4 @@
   return position;
 }
 
-void blink::NGOutOfFlowLayoutPart::MulticolChildInfo::Trace(
-    Visitor* visitor) const {
-  visitor->Trace(parent_break_token);
-}
-
-void NGOutOfFlowLayoutPart::NodeInfo::Trace(Visitor* visitor) const {
-  visitor->Trace(node);
-  visitor->Trace(constraint_space);
-}
-
-void NGOutOfFlowLayoutPart::OffsetInfo::Trace(Visitor* visitor) const {
-  visitor->Trace(initial_layout_result);
-}
-
-void NGOutOfFlowLayoutPart::NodeToLayout::Trace(Visitor* visitor) const {
-  visitor->Trace(node_info);
-  visitor->Trace(offset_info);
-  visitor->Trace(break_token);
-  visitor->Trace(containing_block_fragment);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
index 9df877b..e756929b 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -15,7 +15,6 @@
 #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
 #include "third_party/blink/renderer/core/style/computed_style_base_constants.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
 
@@ -70,6 +69,7 @@
   // LayoutResult::OutOfFlowPositionedDescendants.
   void Run(const LayoutBox* only_layout = nullptr);
 
+ private:
   // Information needed to position descendant within a containing block.
   // Geometry expressed here is complicated:
   // There are two types of containing blocks:
@@ -98,28 +98,20 @@
   // existing multicol fragment. This is used during nested fragmentation of an
   // OOF positioned element.
   struct MulticolChildInfo {
-    DISALLOW_NEW();
-
-   public:
     // The mutable link of a multicol child.
     NGLink* mutable_link;
 
     // The multicol break token that stores a reference to |mutable_link|'s
     // break token in its list of child break tokens.
-    Member<const NGBlockBreakToken> parent_break_token;
+    const NGBlockBreakToken* parent_break_token;
 
     explicit MulticolChildInfo(NGLink* mutable_link,
                                NGBlockBreakToken* parent_break_token = nullptr)
         : mutable_link(mutable_link), parent_break_token(parent_break_token) {}
-
-    void Trace(Visitor* visitor) const;
   };
 
   // Info needed to perform Layout() on an OOF positioned node.
   struct NodeInfo {
-    DISALLOW_NEW();
-
-   public:
     NGBlockNode node;
     const NGConstraintSpace constraint_space;
     const NGLogicalStaticPosition static_position;
@@ -146,8 +138,6 @@
           default_writing_direction(default_writing_direction),
           fixedpos_containing_block(fixedpos_containing_block),
           inline_container(inline_container) {}
-
-    void Trace(Visitor* visitor) const;
   };
 
   // Stores the calculated offset for an OOF positioned node, along with the
@@ -155,16 +145,13 @@
   // addition to the information in NodeInfo, to perform a final layout
   // pass.
   struct OffsetInfo {
-    DISALLOW_NEW();
-
-   public:
     LogicalOffset offset;
     // If |has_cached_layout_result| is true, this will hold the cached layout
     // result that should be returned. Otherwise, this will hold the initial
     // layout result if we needed to know the size in order to calculate the
     // offset. If an initial result is set, it will either be re-used or
     // replaced in the final layout pass.
-    Member<const NGLayoutResult> initial_layout_result;
+    scoped_refptr<const NGLayoutResult> initial_layout_result;
     // The |block_estimate| is wrt. the candidate's writing mode.
     base::Optional<LayoutUnit> block_estimate;
     NGLogicalOutOfFlowDimensions node_dimensions;
@@ -179,42 +166,32 @@
     // The offset from the OOF to the top of the fragmentation context root.
     // This should only be used when laying out a fragmentainer descendant.
     LogicalOffset original_offset;
-
-    void Trace(Visitor* visitor) const;
   };
 
   struct NodeToLayout {
-    DISALLOW_NEW();
-
-   public:
     NodeInfo node_info;
     OffsetInfo offset_info;
-    Member<const NGBlockBreakToken> break_token;
+    const NGBlockBreakToken* break_token = nullptr;
 
     // The physical fragment of the containing block used when laying out a
     // fragmentainer descendant. This is the containing block as defined by the
     // spec: https://www.w3.org/TR/css-position-3/#absolute-cb.
     // TODO(almaher): Ensure that this is correct in the case of an inline
     // ancestor.
-    Member<const NGPhysicalFragment> containing_block_fragment = nullptr;
-
-    void Trace(Visitor* visitor) const;
+    scoped_refptr<const NGPhysicalFragment> containing_block_fragment = nullptr;
   };
 
- private:
-  bool SweepLegacyCandidates(
-      HeapHashSet<Member<const LayoutObject>>* placed_objects);
+  bool SweepLegacyCandidates(HashSet<const LayoutObject*>* placed_objects);
 
   const ContainingBlockInfo GetContainingBlockInfo(
       const NGLogicalOutOfFlowPositionedNode&);
 
   void ComputeInlineContainingBlocks(
-      const HeapVector<NGLogicalOutOfFlowPositionedNode>&);
+      const Vector<NGLogicalOutOfFlowPositionedNode>&);
 
-  void LayoutCandidates(
-      HeapVector<NGLogicalOutOfFlowPositionedNode>* candidates,
-      const LayoutBox* only_layout,
-      HeapHashSet<Member<const LayoutObject>>* placed_objects);
+  void LayoutCandidates(Vector<NGLogicalOutOfFlowPositionedNode>* candidates,
+                        const LayoutBox* only_layout,
+                        HashSet<const LayoutObject*>* placed_objects);
 
   void HandleMulticolsWithPendingOOFs(NGBoxFragmentBuilder* container_builder);
   void LayoutOOFsInMulticol(
@@ -225,14 +202,14 @@
   // |multicol_children| holds the children of an inner multicol if
   // we are laying out OOF elements inside a nested fragmentation context.
   void LayoutFragmentainerDescendants(
-      HeapVector<NGLogicalOutOfFlowPositionedNode>* descendants,
+      Vector<NGLogicalOutOfFlowPositionedNode>* descendants,
       LayoutUnit column_inline_progression,
       bool outer_context_has_fixedpos_container = false,
-      HeapVector<MulticolChildInfo>* multicol_children = nullptr);
+      Vector<MulticolChildInfo>* multicol_children = nullptr);
 
   NodeInfo SetupNodeInfo(const NGLogicalOutOfFlowPositionedNode& oof_node);
 
-  const NGLayoutResult* LayoutOOFNode(
+  scoped_refptr<const NGLayoutResult> LayoutOOFNode(
       const NodeToLayout& oof_node_to_layout,
       const LayoutBox* only_layout,
       const NGConstraintSpace* fragmentainer_constraint_space = nullptr);
@@ -243,13 +220,13 @@
                              const LayoutBox* only_layout,
                              bool is_first_run = true);
 
-  const NGLayoutResult* Layout(
+  scoped_refptr<const NGLayoutResult> Layout(
       const NodeToLayout& oof_node_to_layout,
       const NGConstraintSpace* fragmentainer_constraint_space);
 
   bool IsContainingBlockForCandidate(const NGLogicalOutOfFlowPositionedNode&);
 
-  const NGLayoutResult* GenerateFragment(
+  scoped_refptr<const NGLayoutResult> GenerateFragment(
       NGBlockNode node,
       const LogicalSize& container_content_size_in_child_writing_mode,
       const base::Optional<LayoutUnit>& block_estimate,
@@ -269,10 +246,10 @@
   // has not finished layout in the current pass will be added back to
   // |fragmented_descendants| to continue layout in the next fragmentainer.
   void LayoutOOFsInFragmentainer(
-      const HeapVector<NodeToLayout>& pending_descendants,
+      const Vector<NodeToLayout>& pending_descendants,
       wtf_size_t index,
       LayoutUnit column_inline_progression,
-      HeapVector<NodeToLayout>* fragmented_descendants);
+      Vector<NodeToLayout>* fragmented_descendants);
   void AddOOFToFragmentainer(const NodeToLayout& descendant,
                              const NGConstraintSpace* fragmentainer_space,
                              LayoutUnit additional_inline_offset,
@@ -280,7 +257,7 @@
                              LogicalOffset fragmentainer_offset,
                              wtf_size_t index,
                              NGSimplifiedOOFLayoutAlgorithm* algorithm,
-                             HeapVector<NodeToLayout>* fragmented_descendants);
+                             Vector<NodeToLayout>* fragmented_descendants);
   void ReplaceFragmentainer(wtf_size_t index,
                             LogicalOffset offset,
                             bool create_new_fragment,
@@ -310,14 +287,13 @@
   NGBoxFragmentBuilder* container_builder_;
   ContainingBlockInfo default_containing_block_info_for_absolute_;
   ContainingBlockInfo default_containing_block_info_for_fixed_;
-  HeapHashMap<Member<const LayoutObject>, ContainingBlockInfo>
-      containing_blocks_map_;
+  HashMap<const LayoutObject*, ContainingBlockInfo> containing_blocks_map_;
   const WritingMode writing_mode_;
   const WritingDirectionMode default_writing_direction_;
 
   // Holds the children of an inner multicol if we are laying out OOF elements
   // inside a nested fragmentation context.
-  HeapVector<MulticolChildInfo>* multicol_children_;
+  Vector<MulticolChildInfo>* multicol_children_;
   // The block size of the multi-column (before adjustment for spanners, etc.)
   // This is used to calculate the column size of any newly added proxy
   // fragments when handling fragmentation for abspos elements.
@@ -336,9 +312,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGOutOfFlowLayoutPart::MulticolChildInfo)
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGOutOfFlowLayoutPart::NodeToLayout)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_OUT_OF_FLOW_LAYOUT_PART_H_
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc
index f19266f..9f05260 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc
@@ -20,7 +20,8 @@
  protected:
   NGOutOfFlowLayoutPartTest() : ScopedLayoutNGBlockFragmentationForTest(true) {}
 
-  const NGPhysicalBoxFragment* RunBlockLayoutAlgorithm(Element* element) {
+  scoped_refptr<const NGPhysicalBoxFragment> RunBlockLayoutAlgorithm(
+      Element* element) {
     NGBlockNode container(element->GetLayoutBox());
     NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
         {WritingMode::kHorizontalTb, TextDirection::kLtr},
@@ -29,8 +30,8 @@
   }
 
   String DumpFragmentTree(Element* element) {
-    auto* fragment = RunBlockLayoutAlgorithm(element);
-    return DumpFragmentTree(fragment);
+    auto fragment = RunBlockLayoutAlgorithm(element);
+    return DumpFragmentTree(fragment.get());
   }
 
   String DumpFragmentTree(const blink::NGPhysicalBoxFragment* fragment) {
@@ -87,7 +88,8 @@
   // Test whether the oof fragments have been collected at NG->Legacy boundary.
   Element* rel = GetDocument().getElementById("rel");
   auto* block_flow = To<LayoutBlockFlow>(rel->GetLayoutObject());
-  const NGLayoutResult* result = block_flow->GetCachedLayoutResult();
+  scoped_refptr<const NGLayoutResult> result =
+      block_flow->GetCachedLayoutResult();
   EXPECT_TRUE(result);
   EXPECT_EQ(result->PhysicalFragment().OutOfFlowPositionedDescendants().size(),
             2u);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.cc
deleted file mode 100644
index 292d3b7d..0000000
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.cc
+++ /dev/null
@@ -1,31 +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/core/layout/ng/ng_out_of_flow_positioned_node.h"
-
-namespace blink {
-
-void NGPhysicalOutOfFlowPositionedNode::Trace(Visitor* visitor) const {
-  if (is_for_fragmentation) {
-    static_cast<const NGPhysicalOOFNodeForFragmentation*>(this)
-        ->TraceAfterDispatch(visitor);
-  } else {
-    TraceAfterDispatch(visitor);
-  }
-}
-
-void NGPhysicalOutOfFlowPositionedNode::TraceAfterDispatch(
-    Visitor* visitor) const {
-  visitor->Trace(box);
-  visitor->Trace(inline_container);
-}
-
-void NGPhysicalOOFNodeForFragmentation::TraceAfterDispatch(
-    Visitor* visitor) const {
-  NGPhysicalOutOfFlowPositionedNode::TraceAfterDispatch(visitor);
-  visitor->Trace(containing_block);
-  visitor->Trace(fixedpos_containing_block);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h
index 3923046..79aee3fa 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h
@@ -30,18 +30,16 @@
   // The relative offset is stored separately to ensure that it is applied after
   // fragmentation: https://www.w3.org/TR/css-break-3/#transforms.
   OffsetType relative_offset;
-  Member<const NGPhysicalFragment> fragment;
+  scoped_refptr<const NGPhysicalFragment> fragment;
 
   NGContainingBlock() : fragment(nullptr) {}
 
   NGContainingBlock(OffsetType offset,
                     OffsetType relative_offset,
-                    const NGPhysicalFragment* fragment)
+                    scoped_refptr<const NGPhysicalFragment> fragment)
       : offset(offset),
         relative_offset(relative_offset),
         fragment(std::move(fragment)) {}
-
-  void Trace(Visitor* visitor) const { visitor->Trace(fragment); }
 };
 
 // If an out-of-flow positioned element is inside a nested fragmentation
@@ -50,8 +48,7 @@
 // needed to perform layout on the OOF descendants once they make their way to
 // the outermost context.
 template <typename OffsetType>
-struct NGMulticolWithPendingOOFs
-    : public GarbageCollected<NGMulticolWithPendingOOFs<OffsetType>> {
+struct NGMulticolWithPendingOOFs {
  public:
   // If no fixedpos containing block was found, |multicol_offset| will be
   // relative to the outer fragmentation context root. Otherwise, it will be
@@ -70,10 +67,6 @@
       NGContainingBlock<OffsetType> fixedpos_containing_block)
       : multicol_offset(multicol_offset),
         fixedpos_containing_block(fixedpos_containing_block) {}
-
-  void Trace(Visitor* visitor) const {
-    visitor->Trace(fixedpos_containing_block);
-  }
 };
 
 // A physical out-of-flow positioned-node is an element with the style
@@ -95,7 +88,7 @@
   using VerticalEdge = NGPhysicalStaticPosition::VerticalEdge;
 
  public:
-  Member<LayoutBox> box;
+  LayoutBox* box;
   // Unpacked NGPhysicalStaticPosition.
   PhysicalOffset static_position;
   unsigned static_position_horizontal_edge : 2;
@@ -103,7 +96,7 @@
   // Whether or not this is an NGPhysicalOOFNodeForFragmentation.
   unsigned is_for_fragmentation : 1;
   // Continuation root of the optional inline container.
-  Member<const LayoutInline> inline_container;
+  const LayoutInline* inline_container;
 
   NGPhysicalOutOfFlowPositionedNode(
       NGBlockNode node,
@@ -131,9 +124,6 @@
     return {static_position, GetStaticPositionHorizontalEdge(),
             GetStaticPositionVerticalEdge()};
   }
-
-  void Trace(Visitor* visitor) const;
-  void TraceAfterDispatch(Visitor*) const;
 };
 
 // When fragmentation comes into play, we no longer place a positioned-node as
@@ -176,8 +166,6 @@
         fixedpos_containing_block(fixedpos_containing_block) {
     is_for_fragmentation = true;
   }
-
-  void TraceAfterDispatch(Visitor* visitor) const;
 };
 
 // The logical version of above. It is used within a an algorithm pass (within
@@ -190,10 +178,10 @@
   DISALLOW_NEW();
 
  public:
-  Member<LayoutBox> box;
+  LayoutBox* box;
   NGLogicalStaticPosition static_position;
   // Continuation root of the optional inline container.
-  Member<const LayoutInline> inline_container;
+  const LayoutInline* inline_container;
   bool needs_block_offset_adjustment;
   const LayoutUnit fragmentainer_consumed_block_size;
   NGContainingBlock<LogicalOffset> containing_block;
@@ -223,22 +211,8 @@
   }
 
   NGBlockNode Node() const { return NGBlockNode(box); }
-
-  void Trace(Visitor* visitor) const {
-    visitor->Trace(box);
-    visitor->Trace(inline_container);
-    visitor->Trace(containing_block);
-    visitor->Trace(fixedpos_containing_block);
-  }
 };
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGPhysicalOutOfFlowPositionedNode)
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGPhysicalOOFNodeForFragmentation)
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGLogicalOutOfFlowPositionedNode)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_OUT_OF_FLOW_POSITIONED_NODE_H_
diff --git a/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.cc
index bd9557e..fa7d6b8f 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.cc
@@ -19,14 +19,14 @@
     const NGLayoutAlgorithmParams& params)
     : NGLayoutAlgorithm(params) {}
 
-const NGLayoutResult* NGPageLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGPageLayoutAlgorithm::Layout() {
   LogicalSize page_size = ChildAvailableSize();
 
   NGConstraintSpace child_space = CreateConstraintSpaceForPages(page_size);
 
   WritingDirectionMode writing_direction =
       ConstraintSpace().GetWritingDirection();
-  const NGBlockBreakToken* break_token = BreakToken();
+  scoped_refptr<const NGBlockBreakToken> break_token = BreakToken();
   LayoutUnit intrinsic_block_size;
   LogicalOffset page_offset = BorderScrollbarPadding().StartOffset();
   // TODO(mstensho): Handle auto block size.
@@ -39,8 +39,8 @@
     NGFragmentGeometry fragment_geometry =
         CalculateInitialFragmentGeometry(child_space, Node());
     NGBlockLayoutAlgorithm child_algorithm(
-        {Node(), fragment_geometry, child_space, break_token});
-    const NGLayoutResult* result = child_algorithm.Layout();
+        {Node(), fragment_geometry, child_space, break_token.get()});
+    scoped_refptr<const NGLayoutResult> result = child_algorithm.Layout();
     const auto& page = result->PhysicalFragment();
 
     container_builder_.AddChild(page, page_offset);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h
index 6d0c797..699dfa06 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h
@@ -23,7 +23,7 @@
  public:
   NGPageLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
index 863cb52..23e611f 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -108,7 +108,7 @@
 }  // namespace
 
 // static
-const NGPhysicalBoxFragment* NGPhysicalBoxFragment::Create(
+scoped_refptr<const NGPhysicalBoxFragment> NGPhysicalBoxFragment::Create(
     NGBoxFragmentBuilder* builder,
     WritingMode block_or_line_writing_mode) {
   const auto writing_direction = builder->GetWritingDirection();
@@ -189,24 +189,26 @@
 
   wtf_size_t num_fragment_items =
       builder->ItemsBuilder() ? builder->ItemsBuilder()->Size() : 0;
-  size_t byte_size = AdditionalByteSize(
-      num_fragment_items, builder->children_.size(), has_layout_overflow,
-      has_borders, has_padding, inflow_bounds.has_value(), has_rare_data);
+  size_t byte_size = ByteSize(num_fragment_items, builder->children_.size(),
+                              has_layout_overflow, has_borders, has_padding,
+                              inflow_bounds.has_value(), has_rare_data);
 
   // We store the children list inline in the fragment as a flexible
   // array. Therefore, we need to make sure to allocate enough space for
   // that array here, which requires a manual allocation + placement new.
   // The initialization of the array is done by NGPhysicalFragment;
   // we pass the buffer as a constructor argument.
-  return MakeGarbageCollected<NGPhysicalBoxFragment>(
-      AdditionalBytes(byte_size), PassKey(), builder, has_layout_overflow,
-      layout_overflow, has_borders, borders, has_padding, padding,
-      inflow_bounds, has_fragment_items, has_rare_data,
-      block_or_line_writing_mode);
+  void* data = ::WTF::Partitions::FastMalloc(
+      byte_size, ::WTF::GetStringWithTypeName<NGPhysicalBoxFragment>());
+  new (data) NGPhysicalBoxFragment(
+      PassKey(), builder, has_layout_overflow, layout_overflow, has_borders,
+      borders, has_padding, padding, inflow_bounds, has_fragment_items,
+      has_rare_data, block_or_line_writing_mode);
+  return base::AdoptRef(static_cast<NGPhysicalBoxFragment*>(data));
 }
 
 // static
-const NGPhysicalBoxFragment*
+scoped_refptr<const NGPhysicalBoxFragment>
 NGPhysicalBoxFragment::CloneWithPostLayoutFragments(
     const NGPhysicalBoxFragment& other,
     const base::Optional<PhysicalRect> updated_layout_overflow) {
@@ -220,26 +222,29 @@
 
   // The size of the new fragment shouldn't differ from the old one.
   wtf_size_t num_fragment_items = other.Items() ? other.Items()->Size() : 0;
-  size_t byte_size = AdditionalByteSize(
-      num_fragment_items, other.const_num_children_, has_layout_overflow,
-      other.has_borders_, other.has_padding_, other.has_inflow_bounds_,
-      other.const_has_rare_data_);
+  size_t byte_size =
+      ByteSize(num_fragment_items, other.const_num_children_,
+               has_layout_overflow, other.has_borders_, other.has_padding_,
+               other.has_inflow_bounds_, other.const_has_rare_data_);
 
-  return MakeGarbageCollected<NGPhysicalBoxFragment>(
-      AdditionalBytes(byte_size), PassKey(), other, has_layout_overflow,
-      layout_overflow,
+  void* data = ::WTF::Partitions::FastMalloc(
+      byte_size, ::WTF::GetStringWithTypeName<NGPhysicalBoxFragment>());
+  new (data) NGPhysicalBoxFragment(
+      PassKey(), other, has_layout_overflow, layout_overflow,
       /* recalculate_layout_overflow */ updated_layout_overflow.has_value());
+  return base::AdoptRef(static_cast<NGPhysicalBoxFragment*>(data));
 }
 
 // static
-size_t NGPhysicalBoxFragment::AdditionalByteSize(wtf_size_t num_fragment_items,
-                                                 wtf_size_t num_children,
-                                                 bool has_layout_overflow,
-                                                 bool has_borders,
-                                                 bool has_padding,
-                                                 bool has_inflow_bounds,
-                                                 bool has_rare_data) {
-  return NGFragmentItems::ByteSizeFor(num_fragment_items) +
+size_t NGPhysicalBoxFragment::ByteSize(wtf_size_t num_fragment_items,
+                                       wtf_size_t num_children,
+                                       bool has_layout_overflow,
+                                       bool has_borders,
+                                       bool has_padding,
+                                       bool has_inflow_bounds,
+                                       bool has_rare_data) {
+  return sizeof(NGPhysicalBoxFragment) +
+         NGFragmentItems::ByteSizeFor(num_fragment_items) +
          sizeof(NGLink) * num_children +
          (has_layout_overflow ? sizeof(PhysicalRect) : 0) +
          (has_borders ? sizeof(NGPhysicalBoxStrut) : 0) +
@@ -279,8 +284,15 @@
   for (auto& child : builder->children_) {
     children_[i].offset =
         converter.ToPhysical(child.offset, child.fragment->Size());
-    // Fragments in |builder| are not used after |this| was constructed.
-    children_[i].fragment = std::move(child.fragment);
+    // Call the move constructor to move without |AddRef|. Fragments in
+    // |builder| are not used after |this| was constructed.
+    static_assert(
+        sizeof(children_[0].fragment) ==
+            sizeof(scoped_refptr<const NGPhysicalFragment>),
+        "scoped_refptr must be the size of a pointer for this to work");
+    new (&children_[i].fragment)
+        scoped_refptr<const NGPhysicalFragment>(std::move(child.fragment));
+    DCHECK(!child.fragment);  // Ensure it was moved.
     ++i;
   }
 
@@ -386,7 +398,8 @@
   // To ensure the fragment tree is consistent, use the post-layout fragment.
   for (wtf_size_t i = 0; i < const_num_children_; ++i) {
     children_[i].offset = other.children_[i].offset;
-    const NGPhysicalFragment* post_layout = other.children_[i]->PostLayout();
+    scoped_refptr<const NGPhysicalFragment> post_layout =
+        other.children_[i]->PostLayout();
     // While making the fragment tree consistent, we need to also clone any
     // fragmentainer fragments, as they don't necessarily have their result
     // stored on the layout-object tree.
@@ -400,10 +413,14 @@
                 box_fragment);
       }
 
-      post_layout = NGPhysicalBoxFragment::CloneWithPostLayoutFragments(
-          box_fragment, recalculated_layout_overflow);
+      // Call the move constructor to move without |AddRef|.
+      new (&children_[i].fragment) scoped_refptr<const NGPhysicalFragment>(
+          NGPhysicalBoxFragment::CloneWithPostLayoutFragments(
+              box_fragment, recalculated_layout_overflow));
+    } else {
+      new (&children_[i].fragment)
+          scoped_refptr<const NGPhysicalFragment>(post_layout);
     }
-    children_[i].fragment = post_layout;
   }
 
   ink_overflow_type_ = other.ink_overflow_type_;
@@ -456,18 +473,18 @@
     auto& value = multicol.value;
     multicols_with_pending_oofs.insert(
         multicol.key,
-        MakeGarbageCollected<NGMulticolWithPendingOOFs<PhysicalOffset>>(
-            value->multicol_offset.ConvertToPhysical(
+        NGMulticolWithPendingOOFs<PhysicalOffset>(
+            value.multicol_offset.ConvertToPhysical(
                 builder->Style().GetWritingDirection(), size, PhysicalSize()),
             PhysicalContainingBlock(builder, size,
-                                    value->fixedpos_containing_block)));
+                                    value.fixedpos_containing_block)));
   }
   if (builder->table_grid_rect_)
     table_grid_rect = *builder->table_grid_rect_;
   if (builder->table_column_geometries_)
     table_column_geometries = *builder->table_column_geometries_;
   if (builder->table_collapsed_borders_)
-    table_collapsed_borders = builder->table_collapsed_borders_;
+    table_collapsed_borders = std::move(builder->table_collapsed_borders_);
   if (builder->table_collapsed_borders_geometry_) {
     table_collapsed_borders_geometry =
         std::move(builder->table_collapsed_borders_geometry_);
@@ -493,7 +510,8 @@
               : nullptr),
       table_cell_column_index(other.table_cell_column_index) {}
 
-const NGLayoutResult* NGPhysicalBoxFragment::CloneAsHiddenForPaint() const {
+scoped_refptr<const NGLayoutResult>
+NGPhysicalBoxFragment::CloneAsHiddenForPaint() const {
   const ComputedStyle& style = Style();
   NGBoxFragmentBuilder builder(GetMutableLayoutObject(), &style,
                                style.GetWritingDirection());
@@ -1268,7 +1286,7 @@
     return layout_object_->CreatePositionWithAffinity(0);
   }
 
-  if (IsA<LayoutBlockFlow>(*layout_object_) &&
+  if (IsA<LayoutBlockFlow>(layout_object_) &&
       layout_object_->ChildrenInline()) {
     // Here |this| may have out-of-flow children without inline children, we
     // don't find closest child of |point| for out-of-flow children.
@@ -1629,27 +1647,4 @@
 }
 #endif
 
-void NGPhysicalBoxFragment::TraceAfterDispatch(Visitor* visitor) const {
-  // |children_| is traced in |NGPhysicalFragment|.
-  // These if branches are safe since |const_has_fragment_items_| and
-  // |const_has_rare_data_| are const and set in ctor.
-  if (const_has_fragment_items_)
-    visitor->Trace(*ComputeItemsAddress());
-  if (const_has_rare_data_)
-    visitor->Trace(*ComputeRareDataAddress());
-  // Accessing |const_num_children_| inside Trace() here is safe since it is
-  // const. Note we don't check children_valid_ since that is not threadsafe.
-  // Tracing the child links themselves is safe from a background thread.
-  for (const auto& child : base::make_span(children_, const_num_children_))
-    visitor->Trace(child);
-  NGPhysicalFragment::TraceAfterDispatch(visitor);
-}
-
-void NGPhysicalBoxFragment::RareData::Trace(Visitor* visitor) const {
-  visitor->Trace(oof_positioned_fragmentainer_descendants);
-  visitor->Trace(multicols_with_pending_oofs);
-  visitor->Trace(table_column_geometries);
-  visitor->Trace(table_collapsed_borders);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
index d51a416..52dbc03 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
@@ -25,19 +25,18 @@
 
 class CORE_EXPORT NGPhysicalBoxFragment final : public NGPhysicalFragment {
  public:
-  static const NGPhysicalBoxFragment* Create(
+  static scoped_refptr<const NGPhysicalBoxFragment> Create(
       NGBoxFragmentBuilder* builder,
       WritingMode block_or_line_writing_mode);
   // Creates a copy of |other| but uses the "post-layout" fragments to ensure
   // fragment-tree consistency.
-  static const NGPhysicalBoxFragment* CloneWithPostLayoutFragments(
-      const NGPhysicalBoxFragment& other,
-      const base::Optional<PhysicalRect> updated_layout_overflow =
-          base::nullopt);
+  static scoped_refptr<const NGPhysicalBoxFragment>
+  CloneWithPostLayoutFragments(const NGPhysicalBoxFragment& other,
+                               const base::Optional<PhysicalRect>
+                                   updated_layout_overflow = base::nullopt);
 
   using MulticolCollection =
-      HeapHashMap<Member<LayoutBox>,
-                  Member<NGMulticolWithPendingOOFs<PhysicalOffset>>>;
+      HashMap<LayoutBox*, NGMulticolWithPendingOOFs<PhysicalOffset>>;
   using PassKey = base::PassKey<NGPhysicalBoxFragment>;
   NGPhysicalBoxFragment(PassKey,
                         NGBoxFragmentBuilder* builder,
@@ -58,7 +57,7 @@
                         const PhysicalRect& layout_overflow,
                         bool recalculate_layout_overflow);
 
-  const NGLayoutResult* CloneAsHiddenForPaint() const;
+  scoped_refptr<const NGLayoutResult> CloneAsHiddenForPaint() const;
 
   ~NGPhysicalBoxFragment() {
     ink_overflow_.Reset(InkOverflowType());
@@ -66,10 +65,14 @@
       ComputeItemsAddress()->~NGFragmentItems();
     if (const_has_rare_data_)
       ComputeRareDataAddress()->~RareData();
+    if (ChildrenValid()) {
+      for (const NGLink& child : Children()) {
+        if (child.fragment)
+          child.fragment->Release();
+      }
+    }
   }
 
-  void TraceAfterDispatch(Visitor* visitor) const;
-
   const NGPhysicalBoxFragment* PostLayout() const;
 
   // Returns the children of |this|.
@@ -140,7 +143,7 @@
   }
 
   const NGTableBorders* TableCollapsedBorders() const {
-    return ComputeRareDataAddress()->table_collapsed_borders;
+    return ComputeRareDataAddress()->table_collapsed_borders.get();
   }
 
   const NGTableFragmentData::CollapsedBordersGeometry*
@@ -199,8 +202,8 @@
   OutOfFlowPositionedFragmentainerDescendants() const {
     if (!const_has_rare_data_)
       return base::span<NGPhysicalOOFNodeForFragmentation>();
-    HeapVector<NGPhysicalOOFNodeForFragmentation>& descendants =
-        const_cast<HeapVector<NGPhysicalOOFNodeForFragmentation>&>(
+    Vector<NGPhysicalOOFNodeForFragmentation>& descendants =
+        const_cast<Vector<NGPhysicalOOFNodeForFragmentation>&>(
             ComputeRareDataAddress()->oof_positioned_fragmentainer_descendants);
     return {descendants.data(), descendants.size()};
   }
@@ -426,23 +429,19 @@
 #endif
 
  private:
-  static size_t AdditionalByteSize(wtf_size_t num_fragment_items,
-                                   wtf_size_t num_children,
-                                   bool has_layout_overflow,
-                                   bool has_borders,
-                                   bool has_padding,
-                                   bool has_inflow_bounds,
-                                   bool has_rare_data);
+  static size_t ByteSize(wtf_size_t num_fragment_items,
+                         wtf_size_t num_children,
+                         bool has_layout_overflow,
+                         bool has_borders,
+                         bool has_padding,
+                         bool has_inflow_bounds,
+                         bool has_rare_data);
 
   struct RareData {
-    DISALLOW_NEW();
-
-   public:
     RareData(const RareData&);
     RareData(NGBoxFragmentBuilder*, PhysicalSize size);
-    void Trace(Visitor*) const;
 
-    HeapVector<NGPhysicalOOFNodeForFragmentation>
+    Vector<NGPhysicalOOFNodeForFragmentation>
         oof_positioned_fragmentainer_descendants;
     MulticolCollection multicols_with_pending_oofs;
     const std::unique_ptr<const NGMathMLPaintInfo> mathml_paint_info;
@@ -450,7 +449,7 @@
     // TablesNG rare data.
     PhysicalRect table_grid_rect;
     NGTableFragmentData::ColumnGeometries table_column_geometries;
-    Member<const NGTableBorders> table_collapsed_borders;
+    scoped_refptr<const NGTableBorders> table_collapsed_borders;
     std::unique_ptr<NGTableFragmentData::CollapsedBordersGeometry>
         table_collapsed_borders_geometry;
     wtf_size_t table_cell_column_index;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
index c0a19cf..020680f2 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
@@ -25,12 +25,14 @@
 namespace blink {
 namespace {
 
-struct SameSizeAsNGPhysicalFragment : GarbageCollected<NGPhysicalFragment> {
-  Member<void*> layout_object;
+struct SameSizeAsNGPhysicalFragment
+    : RefCounted<const NGPhysicalFragment, NGPhysicalFragmentTraits> {
+  void* layout_object;
   PhysicalSize size;
   unsigned flags;
-  Member<void*> break_token;
-  Member<Vector<NGPhysicalOutOfFlowPositionedNode>> oof_positioned_descendants_;
+  scoped_refptr<void*> break_token;
+  std::unique_ptr<Vector<NGPhysicalOutOfFlowPositionedNode>>
+      oof_positioned_descendants_;
 };
 
 ASSERT_SIZE(NGPhysicalFragment, SameSizeAsNGPhysicalFragment);
@@ -182,7 +184,7 @@
       if (!descendant->IsLayoutNGObject()) {
         if (const auto* block = DynamicTo<LayoutBlock>(descendant)) {
           if (const auto* positioned_descendants = block->PositionedObjects()) {
-            for (const auto& positioned_object : *positioned_descendants) {
+            for (const auto* positioned_object : *positioned_descendants) {
               if (positioned_object->IsLayoutNGObject())
                 AppendNGRootInLegacySubtree(*positioned_object, indent);
               else
@@ -310,8 +312,7 @@
       oof_positioned_descendants_(
           builder->oof_positioned_descendants_.IsEmpty()
               ? nullptr
-              : MakeGarbageCollected<
-                    HeapVector<NGPhysicalOutOfFlowPositionedNode>>()) {
+              : new Vector<NGPhysicalOutOfFlowPositionedNode>()) {
   CHECK(builder->layout_object_);
   has_floating_descendants_for_paint_ =
       builder->has_floating_descendants_for_paint_;
@@ -369,8 +370,7 @@
       break_token_(other.break_token_),
       oof_positioned_descendants_(
           other.oof_positioned_descendants_
-              ? MakeGarbageCollected<
-                    HeapVector<NGPhysicalOutOfFlowPositionedNode>>(
+              ? new Vector<NGPhysicalOutOfFlowPositionedNode>(
                     *other.oof_positioned_descendants_)
               : nullptr) {
   CHECK(layout_object_);
@@ -532,8 +532,8 @@
   }
 }
 
-const HeapVector<NGInlineItem>&
-NGPhysicalFragment::InlineItemsOfContainingBlock() const {
+const Vector<NGInlineItem>& NGPhysicalFragment::InlineItemsOfContainingBlock()
+    const {
   DCHECK(IsInline());
   DCHECK(GetLayoutObject());
   LayoutBlockFlow* block_flow = GetLayoutObject()->ContainingNGBlockFlow();
@@ -652,25 +652,6 @@
 }
 #endif
 
-void NGPhysicalFragment::Trace(Visitor* visitor) const {
-  switch (Type()) {
-    case kFragmentBox:
-      static_cast<const NGPhysicalBoxFragment*>(this)->TraceAfterDispatch(
-          visitor);
-      break;
-    case kFragmentLineBox:
-      static_cast<const NGPhysicalLineBoxFragment*>(this)->TraceAfterDispatch(
-          visitor);
-      break;
-  }
-}
-
-void NGPhysicalFragment::TraceAfterDispatch(Visitor* visitor) const {
-  visitor->Trace(layout_object_);
-  visitor->Trace(break_token_);
-  visitor->Trace(oof_positioned_descendants_);
-}
-
 // TODO(dlibby): remove `Children` and `PostLayoutChildren` and move the
 // casting and/or branching to the callers.
 base::span<const NGLink> NGPhysicalFragment::Children() const {
@@ -693,7 +674,7 @@
     return;
 
   for (const NGLink& child : Children()) {
-    const_cast<NGLink&>(child).fragment = nullptr;
+    const_cast<NGLink&>(child).fragment->Release();
   }
   children_valid_ = false;
 }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
index b826ca4..e8adb3b 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -9,8 +9,8 @@
 
 #include <iterator>
 
-#include "base/containers/span.h"
-#include "base/dcheck_is_on.h"
+#include "base/memory/scoped_refptr.h"
+
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/editing/forward.h"
 #include "third_party/blink/renderer/core/layout/geometry/physical_offset.h"
@@ -22,6 +22,7 @@
 #include "third_party/blink/renderer/core/layout/ng/ng_link.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_style_variant.h"
 #include "third_party/blink/renderer/platform/graphics/touch_action.h"
+#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
 
 namespace blink {
 
@@ -53,7 +54,7 @@
 // NGFragment wrapper classes which transforms information into the logical
 // coordinate system.
 class CORE_EXPORT NGPhysicalFragment
-    : public GarbageCollected<NGPhysicalFragment> {
+    : public RefCounted<const NGPhysicalFragment, NGPhysicalFragmentTraits> {
  public:
   enum NGFragmentType {
     kFragmentBox = 0,
@@ -287,13 +288,13 @@
   PaintLayer* Layer() const {
     if (!HasLayer())
       return nullptr;
-    return To<LayoutBoxModelObject>(layout_object_.Get())->Layer();
+    return To<LayoutBoxModelObject>(layout_object_)->Layer();
   }
 
   // Whether this object has a self-painting |Layer()|.
   bool HasSelfPaintingLayer() const {
-    return HasLayer() && To<LayoutBoxModelObject>(layout_object_.Get())
-                             ->HasSelfPaintingLayer();
+    return HasLayer() &&
+           To<LayoutBoxModelObject>(layout_object_)->HasSelfPaintingLayer();
   }
 
   // True if overflow != 'visible', except for certain boxes that do not allow
@@ -473,9 +474,6 @@
   static void ShowFragmentTree(const LayoutObject& root);
 #endif
 
-  void Trace(Visitor*) const;
-  void TraceAfterDispatch(Visitor*) const;
-
   // Same as |base::span<const NGLink>|, except that:
   // * Each |NGLink| has the latest generation of post-layout. See
   //   |NGPhysicalFragment::UpdatedFragment()| for more details.
@@ -549,7 +547,7 @@
     const NGLink* buffer_;
   };
 
-  const NGBreakToken* BreakToken() const { return break_token_; }
+  const NGBreakToken* BreakToken() const { return break_token_.get(); }
 
   base::span<const NGLink> Children() const;
 
@@ -579,7 +577,7 @@
   bool HasOutOfFlowPositionedDescendants() const {
     DCHECK(!oof_positioned_descendants_ ||
            !oof_positioned_descendants_->IsEmpty());
-    return oof_positioned_descendants_;
+    return oof_positioned_descendants_.get();
   }
 
   base::span<NGPhysicalOutOfFlowPositionedNode> OutOfFlowPositionedDescendants()
@@ -593,7 +591,7 @@
  protected:
   const ComputedStyle& SlowEffectiveStyle() const;
 
-  const HeapVector<NGInlineItem>& InlineItemsOfContainingBlock() const;
+  const Vector<NGInlineItem>& InlineItemsOfContainingBlock() const;
 
   void AddScrollableOverflowForInlineChild(
       const NGPhysicalBoxFragment& container,
@@ -628,7 +626,7 @@
 
   static bool DependsOnPercentageBlockSize(const NGContainerFragmentBuilder&);
 
-  Member<LayoutObject> layout_object_;
+  LayoutObject* layout_object_;
   const PhysicalSize size_;
 
   unsigned has_floating_descendants_for_paint_ : 1;
@@ -661,8 +659,8 @@
   unsigned has_baseline_ : 1;
   unsigned has_last_baseline_ : 1;
 
-  Member<const NGBreakToken> break_token_;
-  const Member<HeapVector<NGPhysicalOutOfFlowPositionedNode>>
+  scoped_refptr<const NGBreakToken> break_token_;
+  const std::unique_ptr<Vector<NGPhysicalOutOfFlowPositionedNode>>
       oof_positioned_descendants_;
 
  private:
@@ -674,10 +672,7 @@
 struct CORE_EXPORT NGPhysicalFragmentWithOffset {
   DISALLOW_NEW();
 
- public:
-  void Trace(Visitor* visitor) const { visitor->Trace(fragment); }
-
-  Member<const NGPhysicalFragment> fragment;
+  scoped_refptr<const NGPhysicalFragment> fragment;
   PhysicalOffset offset_to_container_box;
 
   PhysicalRect RectInContainerBox() const;
@@ -692,7 +687,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGPhysicalFragmentWithOffset)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_PHYSICAL_FRAGMENT_H_
diff --git a/third_party/blink/renderer/core/layout/ng/ng_positioned_float.cc b/third_party/blink/renderer/core/layout/ng/ng_positioned_float.cc
deleted file mode 100644
index 7b5a8ee..0000000
--- a/third_party/blink/renderer/core/layout/ng/ng_positioned_float.cc
+++ /dev/null
@@ -1,13 +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/core/layout/ng/ng_positioned_float.h"
-
-namespace blink {
-
-void NGPositionedFloat::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_result);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_positioned_float.h b/third_party/blink/renderer/core/layout/ng/ng_positioned_float.h
index 2bbd427..84473ec 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_positioned_float.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_positioned_float.h
@@ -15,10 +15,8 @@
 class NGLayoutResult;
 
 // Contains the information necessary for copying back data to a FloatingObject.
-struct CORE_EXPORT NGPositionedFloat
-    : public GarbageCollected<NGPositionedFloat> {
- public:
-  NGPositionedFloat(const NGLayoutResult* layout_result,
+struct CORE_EXPORT NGPositionedFloat {
+  NGPositionedFloat(scoped_refptr<const NGLayoutResult> layout_result,
                     const NGBfcOffset& bfc_offset,
                     bool need_break_before = false)
       : layout_result(layout_result),
@@ -29,15 +27,11 @@
   NGPositionedFloat& operator=(NGPositionedFloat&&) = default;
   NGPositionedFloat& operator=(const NGPositionedFloat&) = default;
 
-  void Trace(Visitor*) const;
-
-  Member<const NGLayoutResult> layout_result;
+  scoped_refptr<const NGLayoutResult> layout_result;
   NGBfcOffset bfc_offset;
   bool need_break_before = false;
 };
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::NGPositionedFloat)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_POSITIONED_FLOAT_H_
diff --git a/third_party/blink/renderer/core/layout/ng/ng_relative_utils_test.cc b/third_party/blink/renderer/core/layout/ng/ng_relative_utils_test.cc
index 80bd75ed..2d3ac9c 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_relative_utils_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_relative_utils_test.cc
@@ -39,7 +39,7 @@
                                   : Length::Fixed(left.ToInt()));
   }
 
-  Persistent<ComputedStyle> style_;
+  scoped_refptr<ComputedStyle> style_;
   LogicalSize container_size_;
 };
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_replaced_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_replaced_layout_algorithm.cc
index 03474d3..9fdd342 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_replaced_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_replaced_layout_algorithm.cc
@@ -13,7 +13,7 @@
     const NGLayoutAlgorithmParams& params)
     : NGLayoutAlgorithm(params) {}
 
-const NGLayoutResult* NGReplacedLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGReplacedLayoutAlgorithm::Layout() {
   DCHECK(!BreakToken() || BreakToken()->IsBreakBefore());
   // Set this as a legacy root so that legacy painters are used.
   container_builder_.SetIsLegacyLayoutRoot();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_replaced_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_replaced_layout_algorithm.h
index f6e8abb2..3a4cc98e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_replaced_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_replaced_layout_algorithm.h
@@ -23,7 +23,7 @@
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override;
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
index 0da8823..026e14a 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
@@ -122,7 +122,7 @@
 
     if (const auto* table_column_geometries =
             physical_fragment.TableColumnGeometries())
-      container_builder_.SetTableColumnGeometries(table_column_geometries);
+      container_builder_.SetTableColumnGeometries(*table_column_geometries);
 
     if (const auto* table_collapsed_borders =
             physical_fragment.TableCollapsedBorders())
@@ -170,7 +170,7 @@
   previous_physical_container_size_ = physical_fragment.Size();
 }
 
-const NGLayoutResult* NGSimplifiedLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGSimplifiedLayoutAlgorithm::Layout() {
   // Since simplified layout's |Layout()| function deals with laying out
   // children, we can early out if we are display-locked.
   if (Node().ChildLayoutBlockedByDisplayLock())
@@ -193,7 +193,7 @@
     }
 
     // Add the (potentially updated) layout result.
-    const NGLayoutResult* result =
+    scoped_refptr<const NGLayoutResult> result =
         NGBlockNode(To<LayoutBox>(child_fragment.GetMutableLayoutObject()))
             .SimplifiedLayout(child_fragment);
 
@@ -265,11 +265,11 @@
   return container_builder_.ToBoxFragment();
 }
 
-NOINLINE const NGLayoutResult*
+NOINLINE scoped_refptr<const NGLayoutResult>
 NGSimplifiedLayoutAlgorithm::LayoutWithItemsBuilder() {
   NGFragmentItemsBuilder items_builder(writing_direction_);
   container_builder_.SetItemsBuilder(&items_builder);
-  const NGLayoutResult* result = Layout();
+  scoped_refptr<const NGLayoutResult> result = Layout();
   // Ensure stack-allocated |NGFragmentItemsBuilder| is not used anymore.
   // TODO(kojii): Revisit when the storage of |NGFragmentItemsBuilder| is
   // finalized.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h
index 04fe694..e773381 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h
@@ -42,14 +42,14 @@
   NGSimplifiedLayoutAlgorithm(const NGLayoutAlgorithmParams&,
                               const NGLayoutResult&);
 
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override {
     NOTREACHED();
     return MinMaxSizesResult();
   }
 
-  NOINLINE const NGLayoutResult* LayoutWithItemsBuilder();
+  NOINLINE scoped_refptr<const NGLayoutResult> LayoutWithItemsBuilder();
 
  private:
   void AddChildFragment(const NGLink& old_fragment,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_simplified_oof_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_simplified_oof_layout_algorithm.cc
index 30ee1c3d..92b146b 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_simplified_oof_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_simplified_oof_layout_algorithm.cc
@@ -59,12 +59,12 @@
       previous_fragment.MayHaveDescendantAboveBlockStart());
 }
 
-const NGLayoutResult* NGSimplifiedOOFLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGSimplifiedOOFLayoutAlgorithm::Layout() {
   return container_builder_.ToBoxFragment();
 }
 
 void NGSimplifiedOOFLayoutAlgorithm::AppendOutOfFlowResult(
-    const NGLayoutResult* result) {
+    scoped_refptr<const NGLayoutResult> result) {
   container_builder_.AddResult(*result, result->OutOfFlowPositionedOffset(),
                                /* relative_offset */ base::nullopt,
                                /* propagate_oof_descendants */ false);
@@ -76,10 +76,9 @@
           incoming_break_token_->ChildBreakTokens().end()) {
     DCHECK_EQ(result->PhysicalFragment().GetLayoutObject(),
               (*break_token_iterator_)->InputNode().GetLayoutBox());
-    DCHECK(
-        !To<NGPhysicalBoxFragment>(result->PhysicalFragment())
-             .IsFirstForNode() ||
-        To<NGBlockBreakToken>(break_token_iterator_->Get())->IsBreakBefore());
+    DCHECK(!To<NGPhysicalBoxFragment>(result->PhysicalFragment())
+                .IsFirstForNode() ||
+           To<NGBlockBreakToken>(*break_token_iterator_)->IsBreakBefore());
     break_token_iterator_++;
     AdvanceChildIterator();
   }
@@ -110,11 +109,11 @@
         break_token_iterator_ !=
             incoming_break_token_->ChildBreakTokens().end()) {
       // Add the current child if it matches the incoming child break token.
-      const auto& break_token = *break_token_iterator_;
+      const auto* break_token = *break_token_iterator_;
       if (child_link.fragment->GetLayoutObject() ==
           break_token->InputNode().GetLayoutBox()) {
         DCHECK(!To<NGPhysicalBoxFragment>(child_link.get())->IsFirstForNode() ||
-               To<NGBlockBreakToken>(break_token.Get())->IsBreakBefore());
+               To<NGBlockBreakToken>(break_token)->IsBreakBefore());
         AddChildFragment(child_link);
         child_iterator_++;
         break_token_iterator_++;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_simplified_oof_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_simplified_oof_layout_algorithm.h
index 5e16c0d..7eabca6f 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_simplified_oof_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_simplified_oof_layout_algorithm.h
@@ -28,14 +28,14 @@
                                  const NGPhysicalBoxFragment&,
                                  bool is_new_fragment);
 
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override {
     NOTREACHED();
     return MinMaxSizesResult();
   }
 
-  void AppendOutOfFlowResult(const NGLayoutResult* child);
+  void AppendOutOfFlowResult(scoped_refptr<const NGLayoutResult> child);
 
  private:
   void AddChildFragment(const NGLink& old_fragment);
@@ -47,7 +47,7 @@
   base::span<const NGLink> children_;
   base::span<const NGLink>::iterator child_iterator_;
   const NGBlockBreakToken* incoming_break_token_;
-  base::span<const Member<const NGBreakToken>>::iterator break_token_iterator_;
+  base::span<const NGBreakToken* const>::iterator break_token_iterator_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h b/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h
index 265813c..93b5e15 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h
@@ -43,7 +43,7 @@
         parent_style(parent_style) {}
 
   NGBlockNode node;
-  const NGBlockBreakToken* token = nullptr;
+  scoped_refptr<const NGBlockBreakToken> token;
 
   const LogicalSize available_size;
   const LogicalSize percentage_size;
@@ -54,7 +54,7 @@
 
   // layout_result and margins are used as a cache when measuring the
   // inline_size of a float in an inline context.
-  const NGLayoutResult* layout_result = nullptr;
+  scoped_refptr<const NGLayoutResult> layout_result;
   NGBoxStrut margins;
 
   bool IsLineLeft(TextDirection cb_direction) const {
diff --git a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc
index c89a439..c1d0500 100644
--- a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.cc
@@ -279,11 +279,9 @@
 struct SVGTextLengthContext {
   DISALLOW_NEW();
   wtf_size_t start_index;
-  Member<const LayoutObject> layout_object;
+  const LayoutObject* layout_object;
   float text_length;
   SVGLengthAdjustType length_adjust;
-
-  void Trace(Visitor* visitor) const { visitor->Trace(layout_object); }
 };
 
 }  // namespace blink
@@ -310,7 +308,7 @@
     if (last_parent == layout_object->Parent())
       continue;
     last_parent = layout_object->Parent();
-    HeapVector<SVGTextLengthContext> text_length_ancestors =
+    auto text_length_ancestors =
         CollectTextLengthAncestors(items, index, layout_object);
 
     // Find a common part of context_stack and text_length_ancestors.
@@ -345,7 +343,7 @@
 // Collects ancestors with a valid textLength attribute up until the IFC.
 // The result is a list of pairs of scaled textLength value and LayoutObject
 // in the reversed order of distance from the specified |layout_object|.
-HeapVector<SVGTextLengthContext>
+Vector<SVGTextLengthContext>
 NGSVGTextLayoutAlgorithm::CollectTextLengthAncestors(
     const NGFragmentItemsBuilder::ItemWithOffsetList& items,
     wtf_size_t index,
diff --git a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.h
index 9a7044c..ea1605e 100644
--- a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_algorithm.h
@@ -31,7 +31,7 @@
       const NGFragmentItemsBuilder::ItemWithOffsetList& items);
   void ApplyTextLengthAttribute(
       const NGFragmentItemsBuilder::ItemWithOffsetList& items);
-  HeapVector<SVGTextLengthContext> CollectTextLengthAncestors(
+  Vector<SVGTextLengthContext> CollectTextLengthAncestors(
       const NGFragmentItemsBuilder::ItemWithOffsetList& items,
       wtf_size_t index,
       const LayoutObject* layout_object) const;
diff --git a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_attributes_builder.cc b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_attributes_builder.cc
index 151d596..2115b3b9 100644
--- a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_attributes_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_attributes_builder.cc
@@ -200,7 +200,7 @@
 // [1]: https://svgwg.org/svg2-draft/text.html#TextLayoutAlgorithm
 void NGSVGTextLayoutAttributesBuilder::Build(
     const String& ifc_text_content,
-    const HeapVector<NGInlineItem>& items) {
+    const Vector<NGInlineItem>& items) {
   LayoutAttributesStack attr_stack;
   unsigned addressable_index = 0;
   bool in_text_path = false;
@@ -319,8 +319,7 @@
   return std::move(resolved_);
 }
 
-HeapVector<SVGTextPathRange>
-NGSVGTextLayoutAttributesBuilder::TextPathRangeList() {
+Vector<SVGTextPathRange> NGSVGTextLayoutAttributesBuilder::TextPathRangeList() {
   return std::move(text_path_range_list_);
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_attributes_builder.h b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_attributes_builder.h
index f1814a2f..7c038c94 100644
--- a/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_attributes_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/svg/ng_svg_text_layout_attributes_builder.h
@@ -30,13 +30,12 @@
  public:
   explicit NGSVGTextLayoutAttributesBuilder(NGInlineNode ifc);
 
-  void Build(const String& ifc_text_content,
-             const HeapVector<NGInlineItem>& items);
+  void Build(const String& ifc_text_content, const Vector<NGInlineItem>& items);
 
   // This function can be called just once after Build().
   Vector<std::pair<unsigned, NGSVGCharacterData>> CharacterDataList();
   // This function can be called just once after Build().
-  HeapVector<SVGTextPathRange> TextPathRangeList();
+  Vector<SVGTextPathRange> TextPathRangeList();
 
  private:
   LayoutBlockFlow* block_flow_;
@@ -51,7 +50,7 @@
   // A list of a pair of start addressable character index and end
   // addressable character index (inclusive) for a <textPath>.
   // This is used in "8. Position on path".
-  HeapVector<SVGTextPathRange> text_path_range_list_;
+  Vector<SVGTextPathRange> text_path_range_list_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/svg/svg_inline_node_data.h b/third_party/blink/renderer/core/layout/ng/svg/svg_inline_node_data.h
index 11807ed..5ba58ff 100644
--- a/third_party/blink/renderer/core/layout/ng/svg/svg_inline_node_data.h
+++ b/third_party/blink/renderer/core/layout/ng/svg/svg_inline_node_data.h
@@ -15,11 +15,9 @@
 struct SVGTextPathRange {
   DISALLOW_NEW();
 
-  Member<const LayoutSVGTextPath> layout_svg_text_path;
+  const LayoutSVGTextPath* layout_svg_text_path;
   unsigned start_index;
   unsigned end_index;
-
-  void Trace(Visitor* visitor) const { visitor->Trace(layout_svg_text_path); }
 };
 
 }  // namespace blink
@@ -29,11 +27,9 @@
 namespace blink {
 
 // SVG-specific data stored in NGInlineNodeData.
-struct SVGInlineNodeData final : public GarbageCollected<SVGInlineNodeData> {
+struct SVGInlineNodeData final {
   Vector<std::pair<unsigned, NGSVGCharacterData>> character_data_list;
-  HeapVector<SVGTextPathRange> text_path_range_list;
-
-  void Trace(Visitor* visitor) const { visitor->Trace(text_path_range_list); }
+  Vector<SVGTextPathRange> text_path_range_list;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc
index 439558c2..b86bbc88 100644
--- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc
@@ -51,9 +51,10 @@
   return cached_table_borders_ && cached_table_borders_->IsCollapsed();
 }
 
-void LayoutNGTable::SetCachedTableBorders(const NGTableBorders* table_borders) {
+void LayoutNGTable::SetCachedTableBorders(
+    scoped_refptr<const NGTableBorders> table_borders) {
   NOT_DESTROYED();
-  cached_table_borders_ = table_borders;
+  cached_table_borders_ = std::move(table_borders);
 }
 
 void LayoutNGTable::InvalidateCachedTableBorders() {
@@ -61,7 +62,7 @@
   // TODO(layout-dev) When cached borders are invalidated, we could do a
   // special kind of relayout where fragments can replace only TableBorders,
   // keep the geometry, and repaint.
-  cached_table_borders_.Clear();
+  cached_table_borders_.reset();
 }
 
 const NGTableTypes::Columns* LayoutNGTable::GetCachedTableColumnConstraints() {
@@ -271,9 +272,9 @@
 
 LayoutUnit LayoutNGTable::BorderLeft() const {
   NOT_DESTROYED();
-  // DCHECK(cached_table_borders_)
+  // DCHECK(cached_table_borders_.get())
   // ScrollAnchoring fails this DCHECK.
-  if (ShouldCollapseBorders() && cached_table_borders_) {
+  if (ShouldCollapseBorders() && cached_table_borders_.get()) {
     return cached_table_borders_->TableBorder()
         .ConvertToPhysical(Style()->GetWritingDirection())
         .left;
@@ -283,9 +284,9 @@
 
 LayoutUnit LayoutNGTable::BorderRight() const {
   NOT_DESTROYED();
-  // DCHECK(cached_table_borders_)
+  // DCHECK(cached_table_borders_.get())
   // ScrollAnchoring fails this DCHECK.
-  if (ShouldCollapseBorders() && cached_table_borders_) {
+  if (ShouldCollapseBorders() && cached_table_borders_.get()) {
     return cached_table_borders_->TableBorder()
         .ConvertToPhysical(Style()->GetWritingDirection())
         .right;
@@ -295,9 +296,9 @@
 
 LayoutUnit LayoutNGTable::BorderTop() const {
   NOT_DESTROYED();
-  // DCHECK(cached_table_borders_)
+  // DCHECK(cached_table_borders_.get())
   // ScrollAnchoring fails this DCHECK.
-  if (ShouldCollapseBorders() && cached_table_borders_) {
+  if (ShouldCollapseBorders() && cached_table_borders_.get()) {
     return cached_table_borders_->TableBorder()
         .ConvertToPhysical(Style()->GetWritingDirection())
         .top;
@@ -307,9 +308,9 @@
 
 LayoutUnit LayoutNGTable::BorderBottom() const {
   NOT_DESTROYED();
-  // DCHECK(cached_table_borders_)
+  // DCHECK(cached_table_borders_.get())
   // ScrollAnchoring fails this DCHECK.
-  if (ShouldCollapseBorders() && cached_table_borders_) {
+  if (ShouldCollapseBorders() && cached_table_borders_.get()) {
     return cached_table_borders_->TableBorder()
         .ConvertToPhysical(Style()->GetWritingDirection())
         .bottom;
@@ -347,7 +348,7 @@
 
 LayoutRectOutsets LayoutNGTable::BorderBoxOutsets() const {
   NOT_DESTROYED();
-  // DCHECK(cached_table_borders_)
+  // DCHECK(cached_table_borders_.get())
   // ScrollAnchoring fails this DCHECK.
   if (PhysicalFragmentCount() > 0) {
     return GetPhysicalFragment(0)->Borders().ToLayoutRectOutsets();
@@ -437,9 +438,4 @@
   return nullptr;
 }
 
-void LayoutNGTable::Trace(Visitor* visitor) const {
-  visitor->Trace(cached_table_borders_);
-  LayoutNGMixin<LayoutBlock>::Trace(visitor);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h
index 4a98894..a6a8767 100644
--- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h
+++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h
@@ -50,10 +50,10 @@
 
   const NGTableBorders* GetCachedTableBorders() const {
     NOT_DESTROYED();
-    return cached_table_borders_;
+    return cached_table_borders_.get();
   }
 
-  void SetCachedTableBorders(const NGTableBorders*);
+  void SetCachedTableBorders(scoped_refptr<const NGTableBorders>);
 
   const NGTableTypes::Columns* GetCachedTableColumnConstraints();
 
@@ -140,8 +140,6 @@
     return false;
   }
 
-  void Trace(Visitor*) const override;
-
   // LayoutBlock methods end.
 
   // LayoutNGTableInterface methods start.
@@ -247,7 +245,7 @@
   void InvalidateCachedTableBorders();
 
   // Table borders are cached because computing collapsed borders is expensive.
-  Member<const NGTableBorders> cached_table_borders_;
+  scoped_refptr<const NGTableBorders> cached_table_borders_;
 
   // Table columns do not depend on any outside data (e.g. NGConstraintSpace).
   // They are cached because computing them is expensive.
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.cc
index be7ebb9..cee94d96 100644
--- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.cc
@@ -78,7 +78,7 @@
 
   DCHECK(!IsOutOfFlowPositioned()) << "Out of flow captions are blockified.";
 
-  const NGLayoutResult* result = UpdateInFlowBlockLayout();
+  scoped_refptr<const NGLayoutResult> result = UpdateInFlowBlockLayout();
   CalculateAndSetMargins(result->GetConstraintSpaceForCaching(),
                          result->PhysicalFragment());
 
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.cc
index e5c9b18..cec7ea0 100644
--- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.cc
@@ -16,11 +16,6 @@
   UpdateFromElement();
 }
 
-void LayoutNGTableColumn::Trace(Visitor* visitor) const {
-  visitor->Trace(children_);
-  LayoutBox::Trace(visitor);
-}
-
 void LayoutNGTableColumn::StyleDidChange(StyleDifference diff,
                                          const ComputedStyle* old_style) {
   NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.h
index 9e4b9c3..f0f56cc 100644
--- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.h
+++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.h
@@ -16,7 +16,6 @@
 class CORE_EXPORT LayoutNGTableColumn : public LayoutBox {
  public:
   explicit LayoutNGTableColumn(Element*);
-  void Trace(Visitor*) const override;
 
   LayoutNGTable* Table() const;
 
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column_visitor.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column_visitor.h
index 7cd1e191f..538d97b 100644
--- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column_visitor.h
+++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column_visitor.h
@@ -31,7 +31,7 @@
 //                      bool has_children);
 // }
 template <typename Visitor>
-void VisitLayoutNGTableColumn(const HeapVector<NGBlockNode>& columns,
+void VisitLayoutNGTableColumn(const Vector<NGBlockNode>& columns,
                               wtf_size_t table_column_count,
                               Visitor* visitor) {
   wtf_size_t current_column_index = 0;
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc
index fe702a3..dd2b367a 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc
@@ -30,12 +30,12 @@
     return true;
 
   EBorderStyle edge_border_style =
-      NGTableBorders::BorderStyle(edge.style, edge.edge_side);
+      NGTableBorders::BorderStyle(edge.style.get(), edge.edge_side);
   if (edge_border_style == EBorderStyle::kHidden)
     return false;
 
   LayoutUnit edge_width =
-      NGTableBorders::BorderWidth(edge.style, edge.edge_side);
+      NGTableBorders::BorderWidth(edge.style.get(), edge.edge_side);
   if (source_width < edge_width)
     return false;
   if (source_width > edge_width)
@@ -177,15 +177,15 @@
 
 }  // namespace
 
-const NGTableBorders* NGTableBorders::ComputeTableBorders(
+scoped_refptr<NGTableBorders> NGTableBorders::ComputeTableBorders(
     const NGBlockNode& table) {
   const ComputedStyle& table_style = table.Style();
   NGBoxStrut intrinsic_borders(LayoutUnit(table_style.BorderStartWidth()),
                                LayoutUnit(table_style.BorderEndWidth()),
                                LayoutUnit(table_style.BorderBeforeWidth()),
                                LayoutUnit(table_style.BorderAfterWidth()));
-  NGTableBorders* table_borders =
-      MakeGarbageCollected<NGTableBorders>(table_style, intrinsic_borders);
+  scoped_refptr<NGTableBorders> table_borders =
+      base::MakeRefCounted<NGTableBorders>(table_style, intrinsic_borders);
 
   if (table_style.BorderCollapse() != EBorderCollapse::kCollapse)
     return table_borders;
@@ -306,14 +306,16 @@
   // COL borders have precedence over COLGROUP borders.
   // We have to traverse COL first, then COLGROUP.
   ColBordersMarker col_borders_marker(table_row_count, ++box_order,
-                                      table_writing_direction, *table_borders);
+                                      table_writing_direction,
+                                      *table_borders.get());
   VisitLayoutNGTableColumn(
-      const_cast<HeapVector<NGBlockNode>&>(grouped_children.columns),
+      const_cast<Vector<NGBlockNode>&>(grouped_children.columns),
       table_column_count, &col_borders_marker);
-  ColgroupBordersMarker colgroup_borders_marker(
-      table_row_count, ++box_order, table_writing_direction, *table_borders);
+  ColgroupBordersMarker colgroup_borders_marker(table_row_count, ++box_order,
+                                                table_writing_direction,
+                                                *table_borders.get());
   VisitLayoutNGTableColumn(
-      const_cast<HeapVector<NGBlockNode>&>(grouped_children.columns),
+      const_cast<Vector<NGBlockNode>&>(grouped_children.columns),
       table_column_count, &colgroup_borders_marker);
 
   // Mark table borders.
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h
index 2e44929..8bb12b3 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h
@@ -56,16 +56,14 @@
 //   |   |   |    |
 //   |9  |11 |13  |15
 
-class NGTableBorders final : public GarbageCollected<NGTableBorders> {
+class NGTableBorders : public RefCounted<NGTableBorders> {
  public:
-  static const NGTableBorders* ComputeTableBorders(const NGBlockNode&);
+  static scoped_refptr<NGTableBorders> ComputeTableBorders(const NGBlockNode&);
 
   // |table_border_padding| as computed from css values.
   NGTableBorders(const ComputedStyle& table_style,
                  const NGBoxStrut& table_border);
 
-  void Trace(Visitor* visitor) const { visitor->Trace(edges_); }
-
 #if DCHECK_IS_ON()
   String DumpEdges();
   void ShowEdges();
@@ -83,8 +81,7 @@
   // style border defines the edge.
   struct Edge {
     DISALLOW_NEW();
-    void Trace(Visitor* visitor) const { visitor->Trace(style); }
-    Member<const ComputedStyle> style;
+    scoped_refptr<const ComputedStyle> style;
     EdgeSide edge_side;
     // Box order is used to compute edge painting precedence.
     // Lower box order has precedence.
@@ -169,22 +166,25 @@
   }
 
   LayoutUnit BorderWidth(wtf_size_t edge_index) const {
-    return BorderWidth(edges_[edge_index].style, edges_[edge_index].edge_side);
+    return BorderWidth(edges_[edge_index].style.get(),
+                       edges_[edge_index].edge_side);
   }
 
   EBorderStyle BorderStyle(wtf_size_t edge_index) const {
-    return BorderStyle(edges_[edge_index].style, edges_[edge_index].edge_side);
+    return BorderStyle(edges_[edge_index].style.get(),
+                       edges_[edge_index].edge_side);
   }
 
   Color BorderColor(wtf_size_t edge_index) const {
-    return BorderColor(edges_[edge_index].style, edges_[edge_index].edge_side);
+    return BorderColor(edges_[edge_index].style.get(),
+                       edges_[edge_index].edge_side);
   }
 
   wtf_size_t BoxOrder(wtf_size_t edge_index) const {
     return edges_[edge_index].box_order;
   }
 
-  using Edges = HeapVector<Edge>;
+  using Edges = Vector<Edge>;
 
   struct Section {
     wtf_size_t start_row;
@@ -342,22 +342,8 @@
 
 }  // namespace blink
 
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NGTableBorders::Edge)
 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
     blink::NGTableBorders::Section)
 
-namespace WTF {
-
-template <>
-struct VectorTraits<blink::NGTableBorders::Edge>
-    : VectorTraitsBase<blink::NGTableBorders::Edge> {
-  STATIC_ONLY(VectorTraits);
-  static constexpr bool kNeedsDestruction = false;
-  static constexpr bool kCanInitializeWithMemset = true;
-  static constexpr bool kCanClearUnusedSlotsWithMemset = true;
-  static constexpr bool kCanCopyWithMemcpy = true;
-  static constexpr bool kCanMoveWithMemcpy = true;
-};
-
-}  // namespace WTF
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_NG_TABLE_BORDERS_H_
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_fragment_data.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_fragment_data.h
index 0efa75f7..f89b5edb 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_fragment_data.h
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_fragment_data.h
@@ -31,7 +31,6 @@
           inline_offset(inline_offset),
           inline_size(inline_size),
           node(node) {}
-    void Trace(Visitor* visitor) const { visitor->Trace(node); }
     wtf_size_t start_column;
     wtf_size_t span;
     LayoutUnit inline_offset;
@@ -39,7 +38,7 @@
     NGLayoutInputNode node;
   };
 
-  using ColumnGeometries = HeapVector<ColumnGeometry>;
+  using ColumnGeometries = Vector<ColumnGeometry>;
 
   // Column/row location is used for collapsed border painting.
   // Only present if borders are collapsed.
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
index 05040cd2f..75c3cb46 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
@@ -58,7 +58,7 @@
     const ComputedStyle& table_style,
     const NGTableGroupedChildren& grouped_children,
     const LayoutUnit table_inline_size,
-    HeapVector<NGTableLayoutAlgorithm::CaptionResult>& captions,
+    Vector<NGTableLayoutAlgorithm::CaptionResult>& captions,
     LayoutUnit& captions_block_size) {
   const LogicalSize available_size = {table_inline_size, kIndefiniteSize};
   for (NGBlockNode caption : grouped_children.captions) {
@@ -73,7 +73,8 @@
     builder.SetStretchInlineSizeIfAuto(true);
     NGConstraintSpace caption_constraint_space = builder.ToConstraintSpace();
 
-    auto* caption_result = caption.Layout(caption_constraint_space);
+    scoped_refptr<const NGLayoutResult> caption_result =
+        caption.Layout(caption_constraint_space);
     NGFragment fragment(table_constraint_space.GetWritingDirection(),
                         caption_result->PhysicalFragment());
     NGBoxStrut margins = ComputeMarginsFor(
@@ -288,7 +289,6 @@
 // back to LayoutObject.
 class ColumnGeometriesBuilder {
   STACK_ALLOCATED();
-
  public:
   void VisitCol(const NGLayoutInputNode& col,
                 wtf_size_t start_column_index,
@@ -300,11 +300,10 @@
                                     column_locations[start_column_index].offset;
     col.GetLayoutBox()->SetLogicalWidth(column_inline_size);
     col.GetLayoutBox()->SetLogicalHeight(table_grid_block_size);
-    column_geometries->emplace_back(
-        start_column_index, span,
-        column_locations[start_column_index].offset -
-            border_spacing.inline_size,
-        column_inline_size, col);
+    column_geometries.emplace_back(start_column_index, span,
+                                   column_locations[start_column_index].offset -
+                                       border_spacing.inline_size,
+                                   column_inline_size, col);
   }
 
   void EnterColgroup(const NGLayoutInputNode& colgroup,
@@ -322,18 +321,17 @@
                                column_locations[start_column_index].offset;
     colgroup.GetLayoutBox()->SetLogicalWidth(colgroup_size);
     colgroup.GetLayoutBox()->SetLogicalHeight(table_grid_block_size);
-    column_geometries->emplace_back(
-        start_column_index, span,
-        column_locations[start_column_index].offset -
-            border_spacing.inline_size,
-        colgroup_size, colgroup);
+    column_geometries.emplace_back(start_column_index, span,
+                                   column_locations[start_column_index].offset -
+                                       border_spacing.inline_size,
+                                   colgroup_size, colgroup);
   }
 
   void Sort() {
     // Geometries need to be sorted because this must be true:
     // - parent COLGROUP must come before child COLs.
     // - child COLs are in ascending order.
-    std::sort(column_geometries->begin(), column_geometries->end(),
+    std::sort(column_geometries.begin(), column_geometries.end(),
               [](const NGTableFragmentData::ColumnGeometry& a,
                  const NGTableFragmentData::ColumnGeometry& b) {
                 if (a.node.IsTableCol() && b.node.IsTableCol()) {
@@ -364,8 +362,7 @@
       : column_locations(column_locations),
         table_grid_block_size(table_grid_block_size),
         border_spacing(border_spacing) {}
-  NGTableFragmentData::ColumnGeometries* column_geometries =
-      MakeGarbageCollected<NGTableFragmentData::ColumnGeometries>();
+  NGTableFragmentData::ColumnGeometries column_geometries;
   const NGTableTypes::ColumnLocations& column_locations;
   const LayoutUnit table_grid_block_size;
   const LogicalSize& border_spacing;
@@ -393,7 +390,7 @@
 
   const LogicalSize border_spacing = table.Style().TableBorderSpacing();
   NGTableGroupedChildren grouped_children(table);
-  const NGTableBorders* table_borders = table.GetTableBorders();
+  scoped_refptr<const NGTableBorders> table_borders = table.GetTableBorders();
 
   // Compute min/max inline constraints.
   const scoped_refptr<const NGTableTypes::Columns> column_constraints =
@@ -438,7 +435,7 @@
     const NGTableNode& node,
     const NGConstraintSpace& space,
     const LayoutUnit table_inline_size) {
-  HeapVector<NGTableLayoutAlgorithm::CaptionResult> captions;
+  Vector<NGTableLayoutAlgorithm::CaptionResult> captions;
   NGTableGroupedChildren grouped_children(node);
   LayoutUnit captions_block_size;
 
@@ -447,14 +444,15 @@
   return captions_block_size;
 }
 
-const NGLayoutResult* NGTableLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGTableLayoutAlgorithm::Layout() {
   DCHECK(!BreakToken());
 
   const bool is_fixed_layout = Style().IsFixedTableLayout();
   const LogicalSize border_spacing = Style().TableBorderSpacing();
   NGTableGroupedChildren grouped_children(Node());
-  const NGTableBorders* table_borders = Node().GetTableBorders();
-  DCHECK(table_borders);
+  const scoped_refptr<const NGTableBorders> table_borders =
+      Node().GetTableBorders();
+  DCHECK(table_borders.get());
   const NGBoxStrut border_padding = container_builder_.BorderPadding();
 
   // Algorithm:
@@ -507,7 +505,7 @@
   //
   // The block-size taken by the captions, *subtracts* from the available
   // block-size given to the table-grid.
-  HeapVector<CaptionResult> captions;
+  Vector<CaptionResult> captions;
   LayoutUnit captions_block_size;
   ComputeCaptionFragments(ConstraintSpace(), Style(), grouped_children,
                           container_builder_.InlineSize(), captions,
@@ -572,7 +570,8 @@
 
   const LogicalSize border_spacing = Style().TableBorderSpacing();
   NGTableGroupedChildren grouped_children(Node());
-  Node().GetTableBorders();
+  const scoped_refptr<const NGTableBorders> table_borders =
+      Node().GetTableBorders();
   const NGBoxStrut border_padding = container_builder_.BorderPadding();
 
   const scoped_refptr<const NGTableTypes::Columns> column_constraints =
@@ -744,7 +743,7 @@
 // |     table border/padding       |
 // |     bottom caption fragments   |
 // +--------------------------------+
-const NGLayoutResult* NGTableLayoutAlgorithm::GenerateFragment(
+scoped_refptr<const NGLayoutResult> NGTableLayoutAlgorithm::GenerateFragment(
     const LayoutUnit table_inline_size,
     const LayoutUnit minimal_table_grid_block_size,
     const NGTableGroupedChildren& grouped_children,
@@ -752,7 +751,7 @@
     const NGTableTypes::Rows& rows,
     const NGTableTypes::CellBlockConstraints& cell_block_constraints,
     const NGTableTypes::Sections& sections,
-    const HeapVector<CaptionResult>& captions,
+    const Vector<CaptionResult>& captions,
     const NGTableBorders& table_borders,
     const LogicalSize& border_spacing) {
   const auto table_writing_direction = Style().GetWritingDirection();
@@ -821,7 +820,7 @@
   wtf_size_t section_index = 0;
   bool needs_end_border_spacing = false;
   for (NGBlockNode section : grouped_children) {
-    const NGLayoutResult* section_result =
+    scoped_refptr<const NGLayoutResult> section_result =
         section.Layout(CreateSectionConstraintSpace(section_index++));
     const NGPhysicalBoxFragment& physical_fragment =
         To<NGPhysicalBoxFragment>(section_result->PhysicalFragment());
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.h
index 09c434c..ca66167 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.h
@@ -23,7 +23,7 @@
  public:
   explicit NGTableLayoutAlgorithm(const NGLayoutAlgorithmParams& params)
       : NGLayoutAlgorithm(params) {}
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override;
@@ -43,16 +43,8 @@
   // table-grid, we need to layout all the captions ahead of time. This struct
   // stores the necessary information to add them to the fragment later.
   struct CaptionResult {
-    DISALLOW_NEW();
-
-   public:
-    void Trace(Visitor* visitor) const {
-      visitor->Trace(node);
-      visitor->Trace(layout_result);
-    }
-
     NGBlockNode node;
-    Member<const NGLayoutResult> layout_result;
+    scoped_refptr<const NGLayoutResult> layout_result;
     const NGBoxStrut margins;
   };
 
@@ -79,7 +71,7 @@
       const LogicalSize& border_spacing,
       LayoutUnit table_grid_block_size);
 
-  const NGLayoutResult* GenerateFragment(
+  scoped_refptr<const NGLayoutResult> GenerateFragment(
       LayoutUnit table_inline_size,
       LayoutUnit minimal_table_grid_block_size,
       const NGTableGroupedChildren& grouped_children,
@@ -87,14 +79,11 @@
       const NGTableTypes::Rows& rows,
       const NGTableTypes::CellBlockConstraints& cell_block_constraints,
       const NGTableTypes::Sections& sections,
-      const HeapVector<CaptionResult>& captions,
+      const Vector<CaptionResult>& captions,
       const NGTableBorders& table_borders,
       const LogicalSize& border_spacing);
 };
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::NGTableLayoutAlgorithm::CaptionResult)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_NG_TABLE_LAYOUT_ALGORITHM_H_
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc
index d0e0d20e..35981c6 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc
@@ -355,14 +355,6 @@
   }
 }
 
-void NGTableGroupedChildren::Trace(Visitor* visitor) const {
-  visitor->Trace(captions);
-  visitor->Trace(columns);
-  visitor->Trace(header);
-  visitor->Trace(bodies);
-  visitor->Trace(footer);
-}
-
 NGTableGroupedChildrenIterator NGTableGroupedChildren::begin() const {
   return NGTableGroupedChildrenIterator(*this);
 }
@@ -390,8 +382,8 @@
       AdvanceToNonEmptySection();
       break;
     case kBody:
-      ++position_;
-      if (body_vector_->begin() + position_ == grouped_children_.bodies.end())
+      ++body_iterator_;
+      if (body_iterator_ == grouped_children_.bodies.end())
         AdvanceToNonEmptySection();
       break;
     case kEnd:
@@ -410,7 +402,7 @@
     case kFoot:
       return grouped_children_.footer;
     case kBody:
-      return body_vector_->at(position_);
+      return *body_iterator_;
     case kEnd:
     case kNone:
       NOTREACHED();
@@ -423,7 +415,7 @@
   if (current_section_ != rhs.current_section_)
     return false;
   if (current_section_ == kBody)
-    return rhs.body_vector_ == body_vector_ && rhs.position_ == position_;
+    return rhs.body_iterator_ == body_iterator_;
   return true;
 }
 
@@ -441,9 +433,8 @@
       break;
     case kHead:
       current_section_ = kBody;
-      body_vector_ = &grouped_children_.bodies;
-      position_ = 0;
-      if (body_vector_->size() == 0)
+      body_iterator_ = grouped_children_.bodies.begin();
+      if (body_iterator_ == grouped_children_.bodies.end())
         AdvanceToNonEmptySection();
       break;
     case kBody:
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h
index b678589c..871e877f 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h
@@ -12,7 +12,6 @@
 #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
 #include "third_party/blink/renderer/core/style/computed_style_constants.h"
 #include "third_party/blink/renderer/platform/geometry/length.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
@@ -269,17 +268,12 @@
 
  public:
   explicit NGTableGroupedChildren(const NGBlockNode& table);
-  void Trace(Visitor*) const;
 
-  HeapVector<NGBlockNode> captions;  // CAPTION
-  HeapVector<NGBlockNode> columns;   // COLGROUP, COL
+  Vector<NGBlockNode> captions;  // CAPTION
+  Vector<NGBlockNode> columns;   // COLGROUP, COL
 
   NGBlockNode header;          // first THEAD
-
-  // These cannot be modified except in ctor to ensure
-  // NGTableGroupedChildrenIterator works correctly.
-  HeapVector<NGBlockNode> bodies;  // TBODY/multiple THEAD/TFOOT
-
+  Vector<NGBlockNode> bodies;  // TBODY/multiple THEAD/TFOOT
   NGBlockNode footer;          // first TFOOT
 
   // Default iterators iterate over tbody-like (THEAD/TBODY/TFOOT) elements.
@@ -291,7 +285,6 @@
 // thead, tbody, tfoot
 class NGTableGroupedChildrenIterator {
   STACK_ALLOCATED();
-
   enum CurrentSection { kNone, kHead, kBody, kFoot, kEnd };
 
  public:
@@ -309,12 +302,8 @@
  private:
   void AdvanceToNonEmptySection();
   const NGTableGroupedChildren& grouped_children_;
+  Vector<NGBlockNode>::const_iterator body_iterator_;
   CurrentSection current_section_{kNone};
-
-  // |body_vector_| can be modified only in ctor and
-  // |AdvanceToNonEmptySection()|.
-  const HeapVector<NGBlockNode>* body_vector_ = nullptr;
-  wtf_size_t position_ = 0;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc
index 7942050e..33e2846 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc
@@ -226,7 +226,8 @@
         table_writing_direction);
     const NGConstraintSpace cell_constraint_space = CreateCellConstraintSpace(
         cell, colspan_cell_tabulator->CurrentColumn(), cell_borders);
-    const NGLayoutResult* layout_result = cell.Layout(cell_constraint_space);
+    scoped_refptr<const NGLayoutResult> layout_result =
+        cell.Layout(cell_constraint_space);
     const NGBoxFragment fragment(
         table_writing_direction,
         To<NGPhysicalBoxFragment>(layout_result->PhysicalFragment()));
@@ -375,7 +376,7 @@
 
 // Computes constraints specified on column elements.
 void ComputeColumnElementConstraints(
-    const HeapVector<NGBlockNode>& columns,
+    const Vector<NGBlockNode>& columns,
     bool is_fixed_layout,
     NGTableTypes::Columns* column_constraints) {
   ColumnConstraintsBuilder constraints_builder(column_constraints,
@@ -507,7 +508,7 @@
 
 // Computes maximum possible number of non-mergeable columns.
 wtf_size_t NGTableAlgorithmUtils::ComputeMaximumNonMergeableColumnCount(
-    const HeapVector<NGBlockNode>& columns,
+    const Vector<NGBlockNode>& columns,
     bool is_fixed_layout) {
   // Build column constraints.
   scoped_refptr<NGTableTypes::Columns> column_constraints =
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.h
index a7023a0..e7bcbc1 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.h
@@ -48,7 +48,7 @@
       NGCacheSlot);
 
   static wtf_size_t ComputeMaximumNonMergeableColumnCount(
-      const HeapVector<NGBlockNode>& columns,
+      const Vector<NGBlockNode>& columns,
       bool is_fixed_layout);
 
   static scoped_refptr<NGTableTypes::Columns> ComputeColumnConstraints(
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc
index d0d6b556..3327050 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc
@@ -10,16 +10,17 @@
 
 namespace blink {
 
-const NGTableBorders* NGTableNode::GetTableBorders() const {
-  LayoutNGTable* layout_table = To<LayoutNGTable>(box_.Get());
-  const NGTableBorders* table_borders = layout_table->GetCachedTableBorders();
+scoped_refptr<const NGTableBorders> NGTableNode::GetTableBorders() const {
+  LayoutNGTable* layout_table = To<LayoutNGTable>(box_);
+  scoped_refptr<const NGTableBorders> table_borders =
+      layout_table->GetCachedTableBorders();
   if (!table_borders) {
     table_borders = NGTableBorders::ComputeTableBorders(*this);
-    layout_table->SetCachedTableBorders(table_borders);
+    layout_table->SetCachedTableBorders(table_borders.get());
   } else {
 #if DCHECK_IS_ON()
     // TODO(crbug.com/1191742) remove these DCHECKs as soon as bug is found.
-    auto* duplicate_table_borders = NGTableBorders::ComputeTableBorders(*this);
+    auto duplicate_table_borders = NGTableBorders::ComputeTableBorders(*this);
     DCHECK(*duplicate_table_borders == *table_borders);
 #endif
   }
@@ -33,12 +34,12 @@
 scoped_refptr<const NGTableTypes::Columns> NGTableNode::GetColumnConstraints(
     const NGTableGroupedChildren& grouped_children,
     const NGBoxStrut& border_padding) const {
-  LayoutNGTable* layout_table = To<LayoutNGTable>(box_.Get());
+  LayoutNGTable* layout_table = To<LayoutNGTable>(box_);
   scoped_refptr<const NGTableTypes::Columns> column_constraints =
       layout_table->GetCachedTableColumnConstraints();
   if (!column_constraints) {
     column_constraints = NGTableAlgorithmUtils::ComputeColumnConstraints(
-        *this, grouped_children, *GetTableBorders(), border_padding);
+        *this, grouped_children, *GetTableBorders().get(), border_padding);
     layout_table->SetCachedTableColumnConstraints(column_constraints.get());
   }
   return column_constraints;
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h
index d3f9154..bcf5a2bb 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.h
@@ -19,7 +19,7 @@
 
   const NGBoxStrut& GetTableBordersStrut() const;
 
-  const NGTableBorders* GetTableBorders() const;
+  scoped_refptr<const NGTableBorders> GetTableBorders() const;
 
   LayoutUnit ComputeCaptionBlockSize(const NGConstraintSpace& space) const;
 
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.cc
index 7aeb7d8b..78710c3 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.cc
@@ -18,7 +18,7 @@
     const NGLayoutAlgorithmParams& params)
     : NGLayoutAlgorithm(params) {}
 
-const NGLayoutResult* NGTableRowLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGTableRowLayoutAlgorithm::Layout() {
   const NGTableConstraintSpaceData& table_data = *ConstraintSpace().TableData();
   wtf_size_t row_index = ConstraintSpace().TableRowIndex();
 
@@ -94,7 +94,8 @@
       NGConstraintSpace cell_constraint_space = CreateCellConstraintSpace(
           cell, cell_index, base::nullopt, row.is_collapsed,
           &cell_location_start_column);
-      const NGLayoutResult* layout_result = cell.Layout(cell_constraint_space);
+      scoped_refptr<const NGLayoutResult> layout_result =
+          cell.Layout(cell_constraint_space);
       NGBoxFragment fragment(
           table_data.table_writing_direction,
           To<NGPhysicalBoxFragment>(layout_result->PhysicalFragment()));
@@ -116,7 +117,8 @@
     NGConstraintSpace cell_constraint_space = CreateCellConstraintSpace(
         cell, cell_index, row_baseline, row.is_collapsed,
         &cell_location_start_column);
-    const NGLayoutResult* cell_result = cell.Layout(cell_constraint_space);
+    scoped_refptr<const NGLayoutResult> cell_result =
+        cell.Layout(cell_constraint_space);
     LogicalOffset cell_offset(
         table_data.column_locations[cell_location_start_column].offset -
             table_data.table_border_spacing.inline_size,
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.h
index 7e6b3201..842ca512 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.h
@@ -21,7 +21,7 @@
  public:
   explicit NGTableRowLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override {
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc
index 81a6982..11e273b 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc
@@ -27,7 +27,7 @@
 // |  +--------------------+  |
 // |       vspacing           |
 // +--------------------------+
-const NGLayoutResult* NGTableSectionLayoutAlgorithm::Layout() {
+scoped_refptr<const NGLayoutResult> NGTableSectionLayoutAlgorithm::Layout() {
   const NGTableConstraintSpaceData& table_data = *ConstraintSpace().TableData();
   wtf_size_t section_index = ConstraintSpace().TableSectionIndex();
 
@@ -52,7 +52,7 @@
         {container_builder_.InlineSize(), kIndefiniteSize});
     row_space_builder.SetTableRowData(&table_data, row_index);
     NGConstraintSpace row_space = row_space_builder.ToConstraintSpace();
-    const NGLayoutResult* row_result = row.Layout(row_space);
+    scoped_refptr<const NGLayoutResult> row_result = row.Layout(row_space);
     if (is_first_row) {
       const NGPhysicalBoxFragment& physical_fragment =
           To<NGPhysicalBoxFragment>(row_result->PhysicalFragment());
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.h
index fb338e6..6b3edaf0 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.h
@@ -21,7 +21,7 @@
  public:
   explicit NGTableSectionLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
 
-  const NGLayoutResult* Layout() override;
+  scoped_refptr<const NGLayoutResult> Layout() override;
 
   MinMaxSizesResult ComputeMinMaxSizes(
       const MinMaxSizesFloatInput&) const override {
diff --git a/third_party/blink/renderer/core/layout/order_iterator.h b/third_party/blink/renderer/core/layout/order_iterator.h
index 3dab631..a80bec2 100644
--- a/third_party/blink/renderer/core/layout/order_iterator.h
+++ b/third_party/blink/renderer/core/layout/order_iterator.h
@@ -31,7 +31,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_ORDER_ITERATOR_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_ORDER_ITERATOR_H_
 
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 #include <set>
@@ -67,9 +66,9 @@
   // Returns the order to use for |child|.
   int ResolvedOrder(const LayoutBox& child) const;
 
-  UntracedMember<const LayoutBox> container_box_;
+  const LayoutBox* container_box_;
 
-  UntracedMember<LayoutBox> current_child_;
+  LayoutBox* current_child_ = nullptr;
 
   using OrderValues = std::set<int>;
   OrderValues order_values_;
diff --git a/third_party/blink/renderer/core/layout/scroll_anchor.cc b/third_party/blink/renderer/core/layout/scroll_anchor.cc
index 2b6980c..0494502f 100644
--- a/third_party/blink/renderer/core/layout/scroll_anchor.cc
+++ b/third_party/blink/renderer/core/layout/scroll_anchor.cc
@@ -43,11 +43,6 @@
 
 ScrollAnchor::~ScrollAnchor() = default;
 
-void ScrollAnchor::Trace(Visitor* visitor) const {
-  visitor->Trace(scroller_);
-  visitor->Trace(anchor_object_);
-}
-
 void ScrollAnchor::SetScroller(ScrollableArea* scroller) {
   DCHECK_NE(scroller_, scroller);
   DCHECK(scroller);
diff --git a/third_party/blink/renderer/core/layout/scroll_anchor.h b/third_party/blink/renderer/core/layout/scroll_anchor.h
index 7873217..7fdc92e 100644
--- a/third_party/blink/renderer/core/layout/scroll_anchor.h
+++ b/third_party/blink/renderer/core/layout/scroll_anchor.h
@@ -44,7 +44,6 @@
   ScrollAnchor();
   explicit ScrollAnchor(ScrollableArea*);
   ~ScrollAnchor();
-  void Trace(Visitor* visitor) const;
 
   // The scroller that is scrolled to componsate for layout movements. Note
   // that the scroller can only be initialized once.
@@ -100,6 +99,8 @@
   // Notifies us that an object will be removed from the layout tree.
   void NotifyRemoved(LayoutObject*);
 
+  void Trace(Visitor* visitor) const { visitor->Trace(scroller_); }
+
  private:
   void FindAnchor();
   // Returns true if searching should stop. Stores result in m_anchorObject.
@@ -142,7 +143,7 @@
   Member<ScrollableArea> scroller_;
 
   // The LayoutObject we should anchor to.
-  Member<LayoutObject> anchor_object_;
+  LayoutObject* anchor_object_;
 
   // Which corner of m_anchorObject's bounding box to anchor to.
   Corner corner_;
diff --git a/third_party/blink/renderer/core/layout/scrollbars_test.cc b/third_party/blink/renderer/core/layout/scrollbars_test.cc
index 550b3b5..50b5f6e 100644
--- a/third_party/blink/renderer/core/layout/scrollbars_test.cc
+++ b/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -2933,8 +2933,8 @@
     ASSERT_TRUE(vertical_track_);
   }
 
-  Persistent<LayoutCustomScrollbarPart> horizontal_track_;
-  Persistent<LayoutCustomScrollbarPart> vertical_track_;
+  LayoutCustomScrollbarPart* horizontal_track_ = nullptr;
+  LayoutCustomScrollbarPart* vertical_track_ = nullptr;
 };
 
 TEST_F(ScrollbarTrackMarginsTest,
diff --git a/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc b/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc
index d4d4d946..1f8a3f2 100644
--- a/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc
+++ b/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc
@@ -201,11 +201,10 @@
 
   const LayoutRect& margin_rect =
       GetShapeImageMarginRect(*layout_box_, reference_box_logical_size_);
-  const LayoutRect& image_rect = (layout_box_->IsLayoutImage())
-                                     ? To<LayoutImage>(layout_box_.Get())
-                                           ->ReplacedContentRect()
-                                           .ToLayoutRect()
-                                     : LayoutRect(LayoutPoint(), image_size);
+  const LayoutRect& image_rect =
+      (layout_box_->IsLayoutImage())
+          ? To<LayoutImage>(layout_box_)->ReplacedContentRect().ToLayoutRect()
+          : LayoutRect(LayoutPoint(), image_size);
 
   scoped_refptr<Image> image =
       style_image->GetImage(*layout_box_, layout_box_->GetDocument(),
@@ -494,11 +493,4 @@
   return result;
 }
 
-// static
-ShapeOutsideInfo::InfoMap& ShapeOutsideInfo::GetInfoMap() {
-  DEFINE_STATIC_LOCAL(Persistent<InfoMap>, static_info_map,
-                      (MakeGarbageCollected<InfoMap>()));
-  return *static_info_map;
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/shapes/shape_outside_info.h b/third_party/blink/renderer/core/layout/shapes/shape_outside_info.h
index aecaa65..9beabe70 100644
--- a/third_party/blink/renderer/core/layout/shapes/shape_outside_info.h
+++ b/third_party/blink/renderer/core/layout/shapes/shape_outside_info.h
@@ -147,11 +147,13 @@
   LayoutUnit LogicalTopOffset() const;
   LayoutUnit LogicalLeftOffset() const;
 
-  using InfoMap = HeapHashMap<WeakMember<const LayoutBox>,
-                              std::unique_ptr<ShapeOutsideInfo>>;
-  static InfoMap& GetInfoMap();
+  typedef HashMap<const LayoutBox*, std::unique_ptr<ShapeOutsideInfo>> InfoMap;
+  static InfoMap& GetInfoMap() {
+    DEFINE_STATIC_LOCAL(InfoMap, static_info_map, ());
+    return static_info_map;
+  }
 
-  const UntracedMember<const LayoutBox> layout_box_;
+  const LayoutBox* const layout_box_;
   mutable std::unique_ptr<Shape> shape_;
   LayoutSize reference_box_logical_size_;
   LayoutUnit percentage_resolution_inline_size_;
diff --git a/third_party/blink/renderer/core/layout/style_retain_scope.h b/third_party/blink/renderer/core/layout/style_retain_scope.h
index 24a8afcd..cbb9357 100644
--- a/third_party/blink/renderer/core/layout/style_retain_scope.h
+++ b/third_party/blink/renderer/core/layout/style_retain_scope.h
@@ -6,7 +6,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_STYLE_RETAIN_SCOPE_H_
 
 #include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
@@ -30,7 +29,7 @@
   }
 
  private:
-  HeapVector<Member<const ComputedStyle>> styles_retained_during_layout_;
+  Vector<scoped_refptr<const ComputedStyle>> styles_retained_during_layout_;
   StyleRetainScope* parent_;
 };
 
diff --git a/third_party/blink/renderer/core/layout/style_retain_scope_test.cc b/third_party/blink/renderer/core/layout/style_retain_scope_test.cc
index eda34ea..3a3e1f7 100644
--- a/third_party/blink/renderer/core/layout/style_retain_scope_test.cc
+++ b/third_party/blink/renderer/core/layout/style_retain_scope_test.cc
@@ -24,4 +24,18 @@
   EXPECT_EQ(StyleRetainScope::Current(), nullptr);
 }
 
+TEST(StyleRetainScopeTest, Retain) {
+  scoped_refptr<const ComputedStyle> style =
+      ComputedStyle::CreateInitialStyleSingleton();
+  EXPECT_TRUE(style->HasOneRef());
+  {
+    StyleRetainScope scope;
+    scope.Retain(*style);
+
+    EXPECT_FALSE(style->HasOneRef());
+    EXPECT_TRUE(style->HasAtLeastOneRef());
+  }
+  EXPECT_TRUE(style->HasOneRef());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/subtree_layout_scope.cc b/third_party/blink/renderer/core/layout/subtree_layout_scope.cc
index d7a1fb1..fafe6b6f 100644
--- a/third_party/blink/renderer/core/layout/subtree_layout_scope.cc
+++ b/third_party/blink/renderer/core/layout/subtree_layout_scope.cc
@@ -45,7 +45,7 @@
   CHECK(!root_.NeedsLayout() || root_.ChildLayoutBlockedByDisplayLock());
 
 #if DCHECK_IS_ON()
-  for (const auto& layout_object : layout_objects_to_layout_) {
+  for (const auto* layout_object : layout_objects_to_layout_) {
     // There are situations where the object to layout was never laid out, such
     // as if there was a display-locked descendant of the root and ancestor of
     // the object which prevented layout. This can happen in quirks mode, where
diff --git a/third_party/blink/renderer/core/layout/subtree_layout_scope.h b/third_party/blink/renderer/core/layout/subtree_layout_scope.h
index 2eaa806b9..daf4562 100644
--- a/third_party/blink/renderer/core/layout/subtree_layout_scope.h
+++ b/third_party/blink/renderer/core/layout/subtree_layout_scope.h
@@ -67,7 +67,7 @@
   LayoutObject& root_;
 
 #if DCHECK_IS_ON()
-  HeapHashSet<Member<LayoutObject>> layout_objects_to_layout_;
+  HashSet<LayoutObject*> layout_objects_to_layout_;
 #endif
 };
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_container.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_container.cc
index 52380c8..a006624 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_container.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_container.cc
@@ -43,11 +43,6 @@
 
 LayoutSVGContainer::~LayoutSVGContainer() = default;
 
-void LayoutSVGContainer::Trace(Visitor* visitor) const {
-  visitor->Trace(content_);
-  LayoutSVGModelObject::Trace(visitor);
-}
-
 void LayoutSVGContainer::UpdateLayout() {
   NOT_DESTROYED();
   DCHECK(NeedsLayout());
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_container.h b/third_party/blink/renderer/core/layout/svg/layout_svg_container.h
index 068fcfb..cecb654 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_container.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_container.h
@@ -36,7 +36,6 @@
  public:
   explicit LayoutSVGContainer(SVGElement*);
   ~LayoutSVGContainer() override;
-  void Trace(Visitor*) const override;
 
   // If you have a LayoutSVGContainer, use firstChild or lastChild instead.
   void SlowFirstChild() const = delete;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc
index 139b457d..d6bb5f6 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc
@@ -57,11 +57,6 @@
 
 LayoutSVGImage::~LayoutSVGImage() = default;
 
-void LayoutSVGImage::Trace(Visitor* visitor) const {
-  visitor->Trace(image_resource_);
-  LayoutSVGModelObject::Trace(visitor);
-}
-
 void LayoutSVGImage::StyleDidChange(StyleDifference diff,
                                     const ComputedStyle* old_style) {
   NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_image.h b/third_party/blink/renderer/core/layout/svg/layout_svg_image.h
index 31340e23..94a2df3 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_image.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_image.h
@@ -35,7 +35,6 @@
  public:
   explicit LayoutSVGImage(SVGImageElement*);
   ~LayoutSVGImage() override;
-  void Trace(Visitor*) const override;
 
   void SetNeedsBoundariesUpdate() override { NOT_DESTROYED(); }
   void SetNeedsTransformUpdate() override {
@@ -106,7 +105,7 @@
   bool transform_uses_reference_box_ : 1;
   AffineTransform local_transform_;
   FloatRect object_bounding_box_;
-  Member<LayoutImageResource> image_resource_;
+  Persistent<LayoutImageResource> image_resource_;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
index d89c4ed..5b61f954 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
@@ -59,8 +59,7 @@
 
 InlineFlowBox* LayoutSVGInline::CreateInlineFlowBox() {
   NOT_DESTROYED();
-  InlineFlowBox* box =
-      MakeGarbageCollected<SVGInlineFlowBox>(LineLayoutItem(this));
+  InlineFlowBox* box = new SVGInlineFlowBox(LineLayoutItem(this));
   box->SetHasVirtualLogicalHeight();
   return box;
 }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc
index 2405446..2d31566 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc
@@ -115,8 +115,8 @@
 
 InlineTextBox* LayoutSVGInlineText::CreateTextBox(int start, uint16_t length) {
   NOT_DESTROYED();
-  InlineTextBox* box = MakeGarbageCollected<SVGInlineTextBox>(
-      LineLayoutItem(this), start, length);
+  InlineTextBox* box =
+      new SVGInlineTextBox(LineLayoutItem(this), start, length);
   box->SetHasVirtualLogicalHeight();
   return box;
 }
@@ -400,7 +400,7 @@
     // If BiDi override is in effect, use the specified direction.
     if (bidi_override && !StyleRef().IsLeftToRightDirection())
       direction = WTF::unicode::kRightToLeft;
-    bidi_runs.AddRun(MakeGarbageCollected<BidiCharacterRun>(
+    bidi_runs.AddRun(new BidiCharacterRun(
         status.context->Override(), status.context->Level(), 0,
         run.CharactersLength(), direction, status.context->Dir()));
   } else {
@@ -422,7 +422,7 @@
     AddMetricsFromRun(sub_run, last_character_was_white_space);
   }
 
-  bidi_resolver.Runs().ClearRuns();
+  bidi_resolver.Runs().DeleteRuns();
 }
 
 void LayoutSVGInlineText::UpdateScaledFont() {
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.cc
index 72f35c6c..5876f8c3 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.cc
@@ -42,11 +42,6 @@
       should_collect_gradient_attributes_(true),
       gradient_map_(MakeGarbageCollected<GradientMap>()) {}
 
-void LayoutSVGResourceGradient::Trace(Visitor* visitor) const {
-  visitor->Trace(gradient_map_);
-  LayoutSVGResourcePaintServer::Trace(visitor);
-}
-
 void LayoutSVGResourceGradient::RemoveAllClientsFromCache() {
   NOT_DESTROYED();
   gradient_map_->clear();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.h b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.h
index d2a0c2c6e..548aea6 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.h
@@ -35,7 +35,6 @@
 class LayoutSVGResourceGradient : public LayoutSVGResourcePaintServer {
  public:
   explicit LayoutSVGResourceGradient(SVGGradientElement*);
-  void Trace(Visitor*) const override;
 
   void RemoveAllClientsFromCache() final;
   bool RemoveClientFromCache(SVGResourceClient&) final;
@@ -63,7 +62,7 @@
   bool should_collect_gradient_attributes_ : 1;
   using GradientMap = HeapHashMap<Member<const SVGResourceClient>,
                                   std::unique_ptr<GradientData>>;
-  Member<GradientMap> gradient_map_;
+  Persistent<GradientMap> gradient_map_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.cc
index 72010e0..930019b2 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.cc
@@ -33,11 +33,6 @@
 
 LayoutSVGResourceLinearGradient::~LayoutSVGResourceLinearGradient() = default;
 
-void LayoutSVGResourceLinearGradient::Trace(Visitor* visitor) const {
-  visitor->Trace(attributes_wrapper_);
-  LayoutSVGResourceGradient::Trace(visitor);
-}
-
 void LayoutSVGResourceLinearGradient::CollectGradientAttributes() {
   NOT_DESTROYED();
   DCHECK(GetElement());
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.h b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.h
index afb461f..5c17082 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.h
@@ -32,7 +32,6 @@
  public:
   explicit LayoutSVGResourceLinearGradient(SVGLinearGradientElement*);
   ~LayoutSVGResourceLinearGradient() override;
-  void Trace(Visitor*) const override;
 
   const char* GetName() const override {
     NOT_DESTROYED();
@@ -61,7 +60,7 @@
   FloatPoint EndPoint(const LinearGradientAttributes&) const;
 
  private:
-  Member<LinearGradientAttributesWrapper> attributes_wrapper_;
+  Persistent<LinearGradientAttributesWrapper> attributes_wrapper_;
 
   LinearGradientAttributes& MutableAttributes() {
     NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
index 84d933ad..1edd62a 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
@@ -52,12 +52,6 @@
       attributes_wrapper_(MakeGarbageCollected<PatternAttributesWrapper>()),
       pattern_map_(MakeGarbageCollected<PatternMap>()) {}
 
-void LayoutSVGResourcePattern::Trace(Visitor* visitor) const {
-  visitor->Trace(attributes_wrapper_);
-  visitor->Trace(pattern_map_);
-  LayoutSVGResourcePaintServer::Trace(visitor);
-}
-
 void LayoutSVGResourcePattern::RemoveAllClientsFromCache() {
   NOT_DESTROYED();
   pattern_map_->clear();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.h b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.h
index 50cf1d60..723d6d6a 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.h
@@ -38,7 +38,6 @@
 class LayoutSVGResourcePattern final : public LayoutSVGResourcePaintServer {
  public:
   explicit LayoutSVGResourcePattern(SVGPatternElement*);
-  void Trace(Visitor*) const override;
 
   const char* GetName() const override {
     NOT_DESTROYED();
@@ -70,7 +69,7 @@
                                    const AffineTransform&) const;
 
   mutable bool should_collect_pattern_attributes_ : 1;
-  Member<PatternAttributesWrapper> attributes_wrapper_;
+  Persistent<PatternAttributesWrapper> attributes_wrapper_;
 
   const PatternAttributes& Attributes() const {
     NOT_DESTROYED();
@@ -87,7 +86,7 @@
   // would avoid re-recording when multiple clients share the same pattern.
   using PatternMap = HeapHashMap<Member<const SVGResourceClient>,
                                  std::unique_ptr<PatternData>>;
-  Member<PatternMap> pattern_map_;
+  Persistent<PatternMap> pattern_map_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.cc
index 44cd0a10..a03e902b 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.cc
@@ -34,11 +34,6 @@
 
 LayoutSVGResourceRadialGradient::~LayoutSVGResourceRadialGradient() = default;
 
-void LayoutSVGResourceRadialGradient::Trace(Visitor* visitor) const {
-  visitor->Trace(attributes_wrapper_);
-  LayoutSVGResourceGradient::Trace(visitor);
-}
-
 void LayoutSVGResourceRadialGradient::CollectGradientAttributes() {
   NOT_DESTROYED();
   DCHECK(GetElement());
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.h b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.h
index 529ec70..a7a4aea2 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.h
@@ -32,7 +32,6 @@
  public:
   explicit LayoutSVGResourceRadialGradient(SVGRadialGradientElement*);
   ~LayoutSVGResourceRadialGradient() override;
-  void Trace(Visitor*) const override;
 
   const char* GetName() const override {
     NOT_DESTROYED();
@@ -63,7 +62,7 @@
   float FocalRadius(const RadialGradientAttributes&) const;
 
  private:
-  Member<RadialGradientAttributesWrapper> attributes_wrapper_;
+  Persistent<RadialGradientAttributesWrapper> attributes_wrapper_;
 
   RadialGradientAttributes& MutableAttributes() {
     NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
index deb4c45..b3b6ede 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
@@ -67,11 +67,6 @@
 
 LayoutSVGRoot::~LayoutSVGRoot() = default;
 
-void LayoutSVGRoot::Trace(Visitor* visitor) const {
-  visitor->Trace(content_);
-  LayoutReplaced::Trace(visitor);
-}
-
 void LayoutSVGRoot::UnscaledIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
   NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_root.h b/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
index ffdd140..ddd5850 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
@@ -35,7 +35,6 @@
  public:
   explicit LayoutSVGRoot(SVGElement*);
   ~LayoutSVGRoot() override;
-  void Trace(Visitor*) const override;
 
   bool IsEmbeddedThroughSVGImage() const;
   bool IsEmbeddedThroughFrameContainingSVGDocument() const;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
index fece9c3..041872f 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc
@@ -79,11 +79,6 @@
   DCHECK(descendant_text_nodes_.IsEmpty());
 }
 
-void LayoutSVGText::Trace(Visitor* visitor) const {
-  visitor->Trace(descendant_text_nodes_);
-  LayoutSVGBlock::Trace(visitor);
-}
-
 void LayoutSVGText::StyleDidChange(StyleDifference diff,
                                    const ComputedStyle* old_style) {
   NOT_DESTROYED();
@@ -117,7 +112,7 @@
 
 static inline void CollectDescendantTextNodes(
     LayoutSVGText& text_root,
-    HeapVector<Member<LayoutSVGInlineText>>& descendant_text_nodes) {
+    Vector<LayoutSVGInlineText*>& descendant_text_nodes) {
   for (LayoutObject* descendant = text_root.FirstChild(); descendant;
        descendant = descendant->NextInPreOrder(&text_root)) {
     if (descendant->IsSVGInlineText())
@@ -173,9 +168,9 @@
 
 static inline void CheckDescendantTextNodeConsistency(
     LayoutSVGText& text,
-    HeapVector<Member<LayoutSVGInlineText>>& expected_descendant_text_nodes) {
+    Vector<LayoutSVGInlineText*>& expected_descendant_text_nodes) {
 #if DCHECK_IS_ON()
-  HeapVector<Member<LayoutSVGInlineText>> new_descendant_text_nodes;
+  Vector<LayoutSVGInlineText*> new_descendant_text_nodes;
   CollectDescendantTextNodes(text, new_descendant_text_nodes);
   DCHECK(new_descendant_text_nodes == expected_descendant_text_nodes);
 #endif
@@ -327,8 +322,7 @@
 
 RootInlineBox* LayoutSVGText::CreateRootInlineBox() {
   NOT_DESTROYED();
-  RootInlineBox* box =
-      MakeGarbageCollected<SVGRootInlineBox>(LineLayoutItem(this));
+  RootInlineBox* box = new SVGRootInlineBox(LineLayoutItem(this));
   box->SetHasVirtualLogicalHeight();
   return box;
 }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_text.h b/third_party/blink/renderer/core/layout/svg/layout_svg_text.h
index 29c0e7af..923cad2 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_text.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_text.h
@@ -32,7 +32,6 @@
  public:
   explicit LayoutSVGText(Element*);
   ~LayoutSVGText() override;
-  void Trace(Visitor*) const override;
 
   bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
 
@@ -64,7 +63,7 @@
     NOT_DESTROYED();
     return needs_reordering_;
   }
-  const HeapVector<Member<LayoutSVGInlineText>>& DescendantTextNodes() const {
+  const Vector<LayoutSVGInlineText*>& DescendantTextNodes() const {
     NOT_DESTROYED();
     return descendant_text_nodes_;
   }
@@ -114,7 +113,7 @@
   bool needs_reordering_ : 1;
   bool needs_positioning_values_update_ : 1;
   bool needs_text_metrics_update_ : 1;
-  HeapVector<Member<LayoutSVGInlineText>> descendant_text_nodes_;
+  Vector<LayoutSVGInlineText*> descendant_text_nodes_;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.cc b/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.cc
index 2196fb7..01ccabfb 100644
--- a/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.cc
+++ b/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.cc
@@ -51,7 +51,7 @@
   auto& text_root =
       To<LayoutSVGText>(*LineLayoutAPIShim::LayoutObjectFrom(Block()));
 
-  const HeapVector<Member<LayoutSVGInlineText>>& descendant_text_nodes =
+  const Vector<LayoutSVGInlineText*>& descendant_text_nodes =
       text_root.DescendantTextNodes();
   if (descendant_text_nodes.IsEmpty())
     return;
@@ -161,8 +161,8 @@
 }
 
 static inline void ReverseInlineBoxRangeAndValueListsIfNeeded(
-    HeapVector<Member<InlineBox>>::iterator first,
-    HeapVector<Member<InlineBox>>::iterator last) {
+    Vector<InlineBox*>::iterator first,
+    Vector<InlineBox*>::iterator last) {
   // This is a copy of std::reverse(first, last). It additionally assures
   // that the metrics map within the layoutObjects belonging to the
   // InlineBoxes are reordered as well.
@@ -170,8 +170,8 @@
     if (first == last || first == --last)
       return;
 
-    auto* first_text_box = DynamicTo<SVGInlineTextBox>(first->Get());
-    auto* last_text_box = DynamicTo<SVGInlineTextBox>(last->Get());
+    auto* first_text_box = DynamicTo<SVGInlineTextBox>(*first);
+    auto* last_text_box = DynamicTo<SVGInlineTextBox>(*last);
     if (last_text_box && first_text_box) {
       // Reordering is only necessary for BiDi text that is _absolutely_
       // positioned.
@@ -188,7 +188,7 @@
 }
 
 void SVGRootInlineBox::ReorderValueLists() {
-  HeapVector<Member<InlineBox>> leaf_boxes_in_logical_order;
+  Vector<InlineBox*> leaf_boxes_in_logical_order;
   CollectLeafBoxesInLogicalOrder(leaf_boxes_in_logical_order,
                                  ReverseInlineBoxRangeAndValueListsIfNeeded);
 }
diff --git a/third_party/blink/renderer/core/layout/svg/svg_content_container.h b/third_party/blink/renderer/core/layout/svg/svg_content_container.h
index d29b745d..6cb7fc6 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_content_container.h
+++ b/third_party/blink/renderer/core/layout/svg/svg_content_container.h
@@ -39,8 +39,6 @@
   LayoutObjectChildList& Children() { return children_; }
   const LayoutObjectChildList& Children() const { return children_; }
 
-  void Trace(Visitor* visitor) const { visitor->Trace(children_); }
-
  private:
   LayoutObjectChildList children_;
 
diff --git a/third_party/blink/renderer/core/layout/svg/svg_hit_test_perftest.cc b/third_party/blink/renderer/core/layout/svg/svg_hit_test_perftest.cc
index 45de177a..837043f 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_hit_test_perftest.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_hit_test_perftest.cc
@@ -125,7 +125,7 @@
             SVGLayoutSupport::IntersectsClipPath(
                 *container, container_bounding_box, *local_location);
           },
-          WrapPersistent(container), std::ref(object_bounding_box),
+          WTF::Unretained(container), std::ref(object_bounding_box),
           std::ref(local_location)));
 }
 
diff --git a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
index 3b74d59..b3153f2 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
@@ -47,7 +47,7 @@
       : layout_object(nullptr), distance(std::numeric_limits<float>::max()) {}
   SearchCandidate(LayoutObject* layout_object, float distance)
       : layout_object(layout_object), distance(distance) {}
-  UntracedMember<LayoutObject> layout_object;
+  LayoutObject* layout_object;
   float distance;
 };
 
diff --git a/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc b/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc
index 6da25717..56e7fcd 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc
@@ -64,8 +64,7 @@
   ChunkLengthAccumulator(bool is_vertical)
       : num_characters_(0), length_(0), is_vertical_(is_vertical) {}
 
-  typedef HeapVector<Member<SVGInlineTextBox>>::const_iterator
-      BoxListConstIterator;
+  typedef Vector<SVGInlineTextBox*>::const_iterator BoxListConstIterator;
 
   void ProcessRange(BoxListConstIterator box_start,
                     BoxListConstIterator box_end);
@@ -86,7 +85,7 @@
 void ChunkLengthAccumulator::ProcessRange(BoxListConstIterator box_start,
                                           BoxListConstIterator box_end) {
   SVGTextFragment* last_fragment = nullptr;
-  for (auto* box_iter = box_start; box_iter != box_end; ++box_iter) {
+  for (auto* const* box_iter = box_start; box_iter != box_end; ++box_iter) {
     for (SVGTextFragment& fragment : (*box_iter)->TextFragments()) {
       num_characters_ += fragment.length;
 
@@ -116,14 +115,14 @@
 SVGTextChunkBuilder::SVGTextChunkBuilder() = default;
 
 void SVGTextChunkBuilder::ProcessTextChunks(
-    const HeapVector<Member<SVGInlineTextBox>>& line_layout_boxes) {
+    const Vector<SVGInlineTextBox*>& line_layout_boxes) {
   if (line_layout_boxes.IsEmpty())
     return;
 
   bool found_start = false;
-  auto const* box_iter = line_layout_boxes.begin();
-  auto const* end_box = line_layout_boxes.end();
-  auto const* chunk_start_box = box_iter;
+  auto* const* box_iter = line_layout_boxes.begin();
+  auto* const* end_box = line_layout_boxes.end();
+  auto* const* chunk_start_box = box_iter;
   for (; box_iter != end_box; ++box_iter) {
     if (!(*box_iter)->StartsNewTextChunk())
       continue;
@@ -210,7 +209,7 @@
         text_length_shift /= length_accumulator.NumCharacters() - 1;
       }
       unsigned at_character = 0;
-      for (auto* box_iter = box_start; box_iter != box_end; ++box_iter) {
+      for (auto* const* box_iter = box_start; box_iter != box_end; ++box_iter) {
         Vector<SVGTextFragment>& fragments = (*box_iter)->TextFragments();
         if (fragments.IsEmpty())
           continue;
@@ -230,7 +229,7 @@
       float text_length_bias = 0;
 
       bool found_first_fragment = false;
-      for (auto* box_iter = box_start; box_iter != box_end; ++box_iter) {
+      for (auto* const* box_iter = box_start; box_iter != box_end; ++box_iter) {
         SVGInlineTextBox* text_box = *box_iter;
         Vector<SVGTextFragment>& fragments = text_box->TextFragments();
         if (fragments.IsEmpty())
@@ -253,7 +252,7 @@
 
   float text_anchor_shift =
       CalculateTextAnchorShift(style, length_accumulator.length());
-  for (auto* box_iter = box_start; box_iter != box_end; ++box_iter) {
+  for (auto* const* box_iter = box_start; box_iter != box_end; ++box_iter) {
     Vector<SVGTextFragment>& fragments = (*box_iter)->TextFragments();
     if (fragments.IsEmpty())
       continue;
diff --git a/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.h b/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.h
index bff56d8b..b2e59d9 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.h
+++ b/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.h
@@ -20,8 +20,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_SVG_TEXT_CHUNK_BUILDER_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_SVG_TEXT_CHUNK_BUILDER_H_
 
-#include "base/macros.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
@@ -49,11 +47,10 @@
   SVGTextChunkBuilder(const SVGTextChunkBuilder&) = delete;
   SVGTextChunkBuilder& operator=(const SVGTextChunkBuilder&) = delete;
 
-  void ProcessTextChunks(const HeapVector<Member<SVGInlineTextBox>>&);
+  void ProcessTextChunks(const Vector<SVGInlineTextBox*>&);
 
  protected:
-  typedef HeapVector<Member<SVGInlineTextBox>>::const_iterator
-      BoxListConstIterator;
+  typedef Vector<SVGInlineTextBox*>::const_iterator BoxListConstIterator;
 
   virtual void HandleTextChunk(BoxListConstIterator box_start,
                                BoxListConstIterator box_end);
diff --git a/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.cc b/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.cc
index 08bb3cc..9219680 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.cc
@@ -36,7 +36,7 @@
 namespace blink {
 
 SVGTextLayoutEngine::SVGTextLayoutEngine(
-    const HeapVector<Member<LayoutSVGInlineText>>& descendant_text_nodes)
+    const Vector<LayoutSVGInlineText*>& descendant_text_nodes)
     : descendant_text_nodes_(descendant_text_nodes),
       current_logical_text_node_index_(0),
       logical_character_offset_(0),
diff --git a/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.h b/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.h
index 5718138..0a84048 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.h
+++ b/third_party/blink/renderer/core/layout/svg/svg_text_layout_engine.h
@@ -49,7 +49,7 @@
   STACK_ALLOCATED();
 
  public:
-  explicit SVGTextLayoutEngine(const HeapVector<Member<LayoutSVGInlineText>>&);
+  SVGTextLayoutEngine(const Vector<LayoutSVGInlineText*>&);
   SVGTextLayoutEngine(const SVGTextLayoutEngine&) = delete;
   SVGTextLayoutEngine& operator=(const SVGTextLayoutEngine&) = delete;
   ~SVGTextLayoutEngine();
@@ -78,12 +78,12 @@
   void AdvanceToNextLogicalCharacter(const SVGTextMetrics&);
 
   // Logical iteration state.
-  const HeapVector<Member<LayoutSVGInlineText>>& descendant_text_nodes_;
+  const Vector<LayoutSVGInlineText*>& descendant_text_nodes_;
   unsigned current_logical_text_node_index_;
   unsigned logical_character_offset_;
   unsigned logical_metrics_list_offset_;
 
-  HeapVector<Member<SVGInlineTextBox>> line_layout_boxes_;
+  Vector<SVGInlineTextBox*> line_layout_boxes_;
 
   SVGTextFragment current_text_fragment_;
   SVGInlineTextMetricsIterator visual_metrics_iterator_;
diff --git a/third_party/blink/renderer/core/layout/svg/svg_text_query.cc b/third_party/blink/renderer/core/layout/svg/svg_text_query.cc
index a77870a..ba2633497 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_text_query.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_text_query.cc
@@ -80,9 +80,8 @@
   return nullptr;
 }
 
-static void CollectTextBoxesInFlowBox(
-    InlineFlowBox* flow_box,
-    HeapVector<Member<SVGInlineTextBox>>& text_boxes) {
+static void CollectTextBoxesInFlowBox(InlineFlowBox* flow_box,
+                                      Vector<SVGInlineTextBox*>& text_boxes) {
   if (!flow_box)
     return;
 
@@ -127,7 +126,7 @@
 static void SpatialQuery(LayoutObject* query_root,
                          QueryData* query_data,
                          ProcessTextFragmentCallback fragment_callback) {
-  HeapVector<Member<SVGInlineTextBox>> text_boxes;
+  Vector<SVGInlineTextBox*> text_boxes;
   CollectTextBoxesInFlowBox(FlowBoxForLayoutObject(query_root), text_boxes);
 
   // Loop over all text boxes
@@ -139,7 +138,7 @@
 
 static void CollectTextBoxesInLogicalOrder(
     LineLayoutSVGInlineText text_line_layout,
-    HeapVector<Member<SVGInlineTextBox>>& text_boxes) {
+    Vector<SVGInlineTextBox*>& text_boxes) {
   text_boxes.Shrink(0);
   for (InlineTextBox* text_box = text_line_layout.FirstTextBox(); text_box;
        text_box = text_box->NextForSameLayoutObject())
@@ -158,7 +157,7 @@
 
   // Walk the layout tree in pre-order, starting at the specified root, and
   // run the query for each text node.
-  HeapVector<Member<SVGInlineTextBox>> text_boxes;
+  Vector<SVGInlineTextBox*> text_boxes;
   for (LayoutObject* layout_object = query_root->SlowFirstChild();
        layout_object;
        layout_object = layout_object->NextInPreOrder(query_root)) {
@@ -556,7 +555,7 @@
     LineLayoutSVGInlineText text_line_layout,
     const SVGInlineTextBox* start_text_box,
     unsigned fragment_offset) {
-  HeapVector<Member<SVGInlineTextBox>> text_boxes;
+  Vector<SVGInlineTextBox*> text_boxes;
   CollectTextBoxesInLogicalOrder(text_line_layout, text_boxes);
 
   DCHECK(start_text_box);
diff --git a/third_party/blink/renderer/core/layout/table_grid_cell.cc b/third_party/blink/renderer/core/layout/table_grid_cell.cc
index 0c55702..6d2b1cc 100644
--- a/third_party/blink/renderer/core/layout/table_grid_cell.cc
+++ b/third_party/blink/renderer/core/layout/table_grid_cell.cc
@@ -12,8 +12,4 @@
 
 TableGridCell::~TableGridCell() = default;
 
-void TableGridCell::Trace(Visitor* visitor) const {
-  visitor->Trace(cells_);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/table_grid_cell.h b/third_party/blink/renderer/core/layout/table_grid_cell.h
index 75169ac..13e88e1 100644
--- a/third_party/blink/renderer/core/layout/table_grid_cell.h
+++ b/third_party/blink/renderer/core/layout/table_grid_cell.h
@@ -5,7 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_TABLE_GRID_CELL_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_TABLE_GRID_CELL_H_
 
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
@@ -32,7 +31,6 @@
   // from this file due to circular includes.
   TableGridCell();
   ~TableGridCell();
-  void Trace(Visitor*) const;
 
   // This is the LayoutTableCell covering this TableGridCell that is on top of
   // the others (aka the last LayoutTableCell in DOM order for this
@@ -52,8 +50,8 @@
 
   bool HasCells() const { return cells_.size() > 0; }
 
-  HeapVector<Member<LayoutTableCell>, 1>& Cells() { return cells_; }
-  const HeapVector<Member<LayoutTableCell>, 1>& Cells() const { return cells_; }
+  Vector<LayoutTableCell*, 1>& Cells() { return cells_; }
+  const Vector<LayoutTableCell*, 1>& Cells() const { return cells_; }
 
   bool InColSpan() const { return in_col_span_; }
   void SetInColSpan(bool in_col_span) { in_col_span_ = in_col_span; }
@@ -63,7 +61,7 @@
   // Due to colspan / rowpsan, it is possible to have overlapping cells
   // (see class comment about an example).
   // This Vector is sorted in DOM order.
-  HeapVector<Member<LayoutTableCell>, 1> cells_;
+  Vector<LayoutTableCell*, 1> cells_;
 
   // True for columns after the first in a colspan.
   bool in_col_span_ = false;
@@ -71,15 +69,4 @@
 
 }  // namespace blink
 
-namespace WTF {
-
-template <>
-struct VectorTraits<blink::TableGridCell>
-    : VectorTraitsBase<blink::TableGridCell> {
-  STATIC_ONLY(VectorTraits);
-  static constexpr bool kCanClearUnusedSlotsWithMemset = true;
-};
-
-}  // namespace WTF
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_TABLE_GRID_CELL_H_
diff --git a/third_party/blink/renderer/core/layout/table_layout_algorithm.h b/third_party/blink/renderer/core/layout/table_layout_algorithm.h
index c0f4106..86ef949d 100644
--- a/third_party/blink/renderer/core/layout/table_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/table_layout_algorithm.h
@@ -22,7 +22,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_TABLE_LAYOUT_ALGORITHM_H_
 
 #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 namespace blink {
@@ -54,7 +53,7 @@
   // overflow in some tests, so we just pick a large number.
   const static int kTableMaxWidth = 1000000;
 
-  UntracedMember<LayoutTable> table_;
+  LayoutTable* table_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc b/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc
index 5793fe9e3..8557f27 100644
--- a/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc
+++ b/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc
@@ -178,7 +178,7 @@
   unsigned n_eff_cols = table_->NumEffectiveColumns();
   layout_struct_.resize(n_eff_cols);
   layout_struct_.Fill(Layout());
-  span_cells_.Fill(nullptr);
+  span_cells_.Fill(0);
 
   Length group_logical_width;
   unsigned current_column = 0;
diff --git a/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.h b/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.h
index 6a69d78..a27d5c3 100644
--- a/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.h
+++ b/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.h
@@ -90,7 +90,7 @@
   };
 
   Vector<Layout, 4> layout_struct_;
-  Vector<UntracedMember<LayoutTableCell>, 4> span_cells_;
+  Vector<LayoutTableCell*, 4> span_cells_;
   bool has_percent_ : 1;
   mutable bool effective_logical_width_dirty_ : 1;
   LayoutUnit scaled_width_from_percent_columns_;
diff --git a/third_party/blink/renderer/core/layout/text_autosizer.cc b/third_party/blink/renderer/core/layout/text_autosizer.cc
index 0f27e030..c37fd886 100644
--- a/third_party/blink/renderer/core/layout/text_autosizer.cc
+++ b/third_party/blink/renderer/core/layout/text_autosizer.cc
@@ -963,7 +963,7 @@
   if (supercluster->has_enough_text_to_autosize_ != kUnknownAmountOfText)
     return supercluster->has_enough_text_to_autosize_ == kHasEnoughText;
 
-  for (const auto& root : *supercluster->roots_) {
+  for (auto* root : *supercluster->roots_) {
     if (skip_layouted_nodes && !root->NormalChildNeedsLayout())
       continue;
     if (ClusterWouldHaveEnoughTextToAutosize(root, width_provider)) {
@@ -1010,7 +1010,7 @@
     max_width = WidthFromBlock(result);
 
   const BlockSet* roots = supercluster->roots_;
-  for (const auto& root : *roots) {
+  for (const auto* root : *roots) {
     const LayoutBlock* width_provider = ClusterWidthProvider(root);
     if (width_provider->NeedsLayout())
       continue;
@@ -1229,7 +1229,7 @@
   if (current_style.TextAutosizingMultiplier() == multiplier)
     return;
 
-  ComputedStyle* style = ComputedStyle::Clone(current_style);
+  scoped_refptr<ComputedStyle> style = ComputedStyle::Clone(current_style);
   style->SetTextAutosizingMultiplier(multiplier);
 
   if (multiplier > 1 && !did_check_cross_site_use_count_) {
@@ -1539,7 +1539,7 @@
 
     if (SuperclusterHasEnoughTextToAutosize(supercluster, width_provider,
                                             true) == kHasEnoughText) {
-      for (const auto& root : *supercluster->roots_) {
+      for (auto* root : *supercluster->roots_) {
         if (!root->EverHadLayout())
           continue;
 
@@ -1555,12 +1555,6 @@
 
 void TextAutosizer::Trace(Visitor* visitor) const {
   visitor->Trace(document_);
-  visitor->Trace(first_block_to_begin_layout_);
-  visitor->Trace(fingerprint_mapper_);
-}
-
-void TextAutosizer::FingerprintMapper::Trace(Visitor* visitor) const {
-  visitor->Trace(fingerprints_);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/text_autosizer.h b/third_party/blink/renderer/core/layout/text_autosizer.h
index 2f48439..685a960 100644
--- a/third_party/blink/renderer/core/layout/text_autosizer.h
+++ b/third_party/blink/renderer/core/layout/text_autosizer.h
@@ -141,8 +141,8 @@
   };
 
  private:
-  typedef HashSet<UntracedMember<LayoutBlock>> BlockSet;
-  typedef HashSet<UntracedMember<const LayoutBlock>> ConstBlockSet;
+  typedef HashSet<LayoutBlock*> BlockSet;
+  typedef HashSet<const LayoutBlock*> ConstBlockSet;
 
   enum HasEnoughTextToAutosize {
     kUnknownAmountOfText,
@@ -211,12 +211,12 @@
                      Cluster* parent,
                      Supercluster* = nullptr);
 
-    UntracedMember<const LayoutBlock> const root_;
+    const LayoutBlock* const root_;
     BlockFlags flags_;
     // The deepest block containing all text is computed lazily (see:
     // deepestBlockContainingAllText). A value of 0 indicates the value has not
     // been computed yet.
-    UntracedMember<const LayoutBlock> deepest_block_containing_all_text_;
+    const LayoutBlock* deepest_block_containing_all_text_;
     Cluster* parent_;
     // The multiplier is computed lazily (see: clusterMultiplier) because it
     // must be calculated after the lowest block containing all text has entered
@@ -275,10 +275,9 @@
     HashSet<Supercluster*>& GetPotentiallyInconsistentSuperclusters() {
       return potentially_inconsistent_superclusters_;
     }
-    void Trace(Visitor* visitor) const;
 
    private:
-    typedef HeapHashMap<Member<const LayoutObject>, Fingerprint> FingerprintMap;
+    typedef HashMap<const LayoutObject*, Fingerprint> FingerprintMap;
     typedef HashMap<Fingerprint, std::unique_ptr<BlockSet>>
         ReverseFingerprintMap;
     typedef HashMap<Fingerprint, std::unique_ptr<Supercluster>> SuperclusterMap;
@@ -371,7 +370,7 @@
   void ReportIfCrossSiteFrame();
 
   Member<const Document> document_;
-  Member<const LayoutBlock> first_block_to_begin_layout_;
+  const LayoutBlock* first_block_to_begin_layout_;
 #if DCHECK_IS_ON()
   // Used to ensure we don't compute properties of a block before beginLayout()
   // is called on it.
diff --git a/third_party/blink/renderer/core/layout/view_fragmentation_context.h b/third_party/blink/renderer/core/layout/view_fragmentation_context.h
index 5263217e..a2effb4 100644
--- a/third_party/blink/renderer/core/layout/view_fragmentation_context.h
+++ b/third_party/blink/renderer/core/layout/view_fragmentation_context.h
@@ -6,7 +6,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_VIEW_FRAGMENTATION_CONTEXT_H_
 
 #include "third_party/blink/renderer/core/layout/fragmentation_context.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 
 namespace blink {
 
@@ -20,7 +19,7 @@
   LayoutUnit RemainingLogicalHeightAt(LayoutUnit block_offset) final;
 
  private:
-  UntracedMember<LayoutView> view_;
+  LayoutView* const view_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index 4ff7af20..4574b686 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -43,7 +43,6 @@
 #include "third_party/blink/public/common/widget/screen_infos.h"
 #include "third_party/blink/public/mojom/frame/viewport_intersection_state.mojom-blink.h"
 #include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
-#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_spell_check_panel_host_client.h"
 #include "third_party/blink/public/platform/web_url_loader.h"
 #include "third_party/blink/renderer/core/core_export.h"
diff --git a/third_party/blink/renderer/core/mathml/mathml_padded_element.cc b/third_party/blink/renderer/core/mathml/mathml_padded_element.cc
index e34dcc2..6f54654d 100644
--- a/third_party/blink/renderer/core/mathml/mathml_padded_element.cc
+++ b/third_party/blink/renderer/core/mathml/mathml_padded_element.cc
@@ -89,7 +89,7 @@
   if (!RuntimeEnabledFeatures::MathMLCoreEnabled() ||
       !style.IsDisplayMathType())
     return MathMLElement::CreateLayoutObject(style, legacy);
-  return MakeGarbageCollected<LayoutNGMathMLBlockWithAnonymousMrow>(this);
+  return new LayoutNGMathMLBlockWithAnonymousMrow(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/mathml/mathml_radical_element.cc b/third_party/blink/renderer/core/mathml/mathml_radical_element.cc
index 27b013d..5409492b 100644
--- a/third_party/blink/renderer/core/mathml/mathml_radical_element.cc
+++ b/third_party/blink/renderer/core/mathml/mathml_radical_element.cc
@@ -24,8 +24,8 @@
       !style.IsDisplayMathType())
     return MathMLElement::CreateLayoutObject(style, legacy);
   if (HasTagName(mathml_names::kMsqrtTag))
-    return MakeGarbageCollected<LayoutNGMathMLBlockWithAnonymousMrow>(this);
-  return MakeGarbageCollected<LayoutNGMathMLBlock>(this);
+    return new LayoutNGMathMLBlockWithAnonymousMrow(this);
+  return new LayoutNGMathMLBlock(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/mathml/mathml_row_element.cc b/third_party/blink/renderer/core/mathml/mathml_row_element.cc
index b5f921d..3a35f12f 100644
--- a/third_party/blink/renderer/core/mathml/mathml_row_element.cc
+++ b/third_party/blink/renderer/core/mathml/mathml_row_element.cc
@@ -20,7 +20,7 @@
   if (!RuntimeEnabledFeatures::MathMLCoreEnabled() ||
       !style.IsDisplayMathType())
     return MathMLElement::CreateLayoutObject(style, legacy);
-  return MakeGarbageCollected<LayoutNGMathMLBlock>(this);
+  return new LayoutNGMathMLBlock(this);
 }
 
 void MathMLRowElement::ChildrenChanged(const ChildrenChange& change) {
diff --git a/third_party/blink/renderer/core/mojo/mojo_handle.cc b/third_party/blink/renderer/core/mojo/mojo_handle.cc
index a6bb303..1e57caf 100644
--- a/third_party/blink/renderer/core/mojo/mojo_handle.cc
+++ b/third_party/blink/renderer/core/mojo/mojo_handle.cc
@@ -19,6 +19,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_mojo_read_message_result.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_mojo_write_data_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_mojo_write_data_result.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/mojo/mojo_watcher.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
@@ -51,7 +52,11 @@
 }
 
 MojoResult MojoHandle::writeMessage(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BufferSource* buffer,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ArrayBufferOrArrayBufferView& buffer,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const HeapVector<Member<MojoHandle>>& handles) {
   Vector<mojo::ScopedHandle, kHandleVectorInlineCapacity> scoped_handles;
   scoped_handles.ReserveCapacity(handles.size());
@@ -67,6 +72,22 @@
 
   const void* bytes = nullptr;
   size_t num_bytes = 0;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (buffer->GetContentType()) {
+    case V8BufferSource::ContentType::kArrayBuffer: {
+      DOMArrayBuffer* array = buffer->GetAsArrayBuffer();
+      bytes = array->Data();
+      num_bytes = array->ByteLength();
+      break;
+    }
+    case V8BufferSource::ContentType::kArrayBufferView: {
+      const auto& view = buffer->GetAsArrayBufferView();
+      bytes = view->BaseAddress();
+      num_bytes = view->byteLength();
+      break;
+    }
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (buffer.IsArrayBuffer()) {
     DOMArrayBuffer* array = buffer.GetAsArrayBuffer();
     bytes = array->Data();
@@ -76,6 +97,7 @@
     bytes = view->BaseAddress();
     num_bytes = view->byteLength();
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   auto message = mojo::Message(
       base::make_span(static_cast<const uint8_t*>(bytes), num_bytes),
@@ -141,7 +163,11 @@
 }
 
 MojoWriteDataResult* MojoHandle::writeData(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BufferSource* buffer,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const ArrayBufferOrArrayBufferView& buffer,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const MojoWriteDataOptions* options_dict) {
   MojoWriteDataResult* result_dict = MojoWriteDataResult::Create();
 
@@ -151,6 +177,22 @@
 
   const void* elements = nullptr;
   base::CheckedNumeric<uint32_t> checked_num_bytes;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (buffer->GetContentType()) {
+    case V8BufferSource::ContentType::kArrayBuffer: {
+      DOMArrayBuffer* array = buffer->GetAsArrayBuffer();
+      elements = array->Data();
+      checked_num_bytes = array->ByteLength();
+      break;
+    }
+    case V8BufferSource::ContentType::kArrayBufferView: {
+      const auto& view = buffer->GetAsArrayBufferView();
+      elements = view->BaseAddress();
+      checked_num_bytes = view->byteLength();
+      break;
+    }
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (buffer.IsArrayBuffer()) {
     DOMArrayBuffer* array = buffer.GetAsArrayBuffer();
     elements = array->Data();
@@ -160,6 +202,7 @@
     elements = view->BaseAddress();
     checked_num_bytes = view->byteLength();
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   ::MojoWriteDataOptions options;
   options.struct_size = sizeof(options);
@@ -206,7 +249,11 @@
 }
 
 MojoReadDataResult* MojoHandle::readData(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BufferSource* buffer,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ArrayBufferOrArrayBufferView& buffer,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const MojoReadDataOptions* options_dict) const {
   MojoReadDataResult* result_dict = MojoReadDataResult::Create();
   MojoReadDataFlags flags = MOJO_READ_DATA_FLAG_NONE;
@@ -217,6 +264,22 @@
 
   void* elements = nullptr;
   base::CheckedNumeric<uint32_t> checked_num_bytes;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (buffer->GetContentType()) {
+    case V8BufferSource::ContentType::kArrayBuffer: {
+      DOMArrayBuffer* array = buffer->GetAsArrayBuffer();
+      elements = array->Data();
+      checked_num_bytes = array->ByteLength();
+      break;
+    }
+    case V8BufferSource::ContentType::kArrayBufferView: {
+      const auto& view = buffer->GetAsArrayBufferView();
+      elements = view->BaseAddress();
+      checked_num_bytes = view->byteLength();
+      break;
+    }
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (buffer.IsArrayBuffer()) {
     DOMArrayBuffer* array = buffer.GetAsArrayBuffer();
     elements = array->Data();
@@ -226,6 +289,7 @@
     elements = view->BaseAddress();
     checked_num_bytes = view->byteLength();
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   ::MojoReadDataOptions options;
   options.struct_size = sizeof(options);
diff --git a/third_party/blink/renderer/core/mojo/mojo_handle.h b/third_party/blink/renderer/core/mojo/mojo_handle.h
index 3c22fb08..8dd063c 100644
--- a/third_party/blink/renderer/core/mojo/mojo_handle.h
+++ b/third_party/blink/renderer/core/mojo/mojo_handle.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_MOJO_MOJO_HANDLE_H_
 
 #include "mojo/public/cpp/system/core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 
@@ -41,18 +42,33 @@
                      V8MojoWatchCallback*);
 
   // MessagePipe handle.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  MojoResult writeMessage(const V8BufferSource* buffer,
+                          const HeapVector<Member<MojoHandle>>& handles);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   MojoResult writeMessage(ArrayBufferOrArrayBufferView&,
                           const HeapVector<Member<MojoHandle>>&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   MojoReadMessageResult* readMessage(const MojoReadMessageFlags*);
 
   // DataPipe handle.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  MojoWriteDataResult* writeData(const V8BufferSource* buffer,
+                                 const MojoWriteDataOptions* options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   MojoWriteDataResult* writeData(const ArrayBufferOrArrayBufferView&,
                                  const MojoWriteDataOptions*);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   MojoReadDataResult* queryData() const;
   MojoReadDataResult* discardData(unsigned num_bytes,
                                   const MojoDiscardDataOptions*);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  MojoReadDataResult* readData(const V8BufferSource* buffer,
+                               const MojoReadDataOptions* options) const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   MojoReadDataResult* readData(ArrayBufferOrArrayBufferView&,
                                const MojoReadDataOptions*) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // SharedBuffer handle.
   MojoMapBufferResult* mapBuffer(unsigned offset, unsigned num_bytes);
diff --git a/third_party/blink/renderer/core/page/autoscroll_controller.cc b/third_party/blink/renderer/core/page/autoscroll_controller.cc
index ebef6eb..cc558625 100644
--- a/third_party/blink/renderer/core/page/autoscroll_controller.cc
+++ b/third_party/blink/renderer/core/page/autoscroll_controller.cc
@@ -96,10 +96,6 @@
 
 void AutoscrollController::Trace(Visitor* visitor) const {
   visitor->Trace(page_);
-  visitor->Trace(autoscroll_layout_object_);
-  visitor->Trace(pressed_layout_object_);
-  visitor->Trace(horizontal_autoscroll_layout_box_);
-  visitor->Trace(vertical_autoscroll_layout_box_);
 }
 
 bool AutoscrollController::SelectionAutoscrollInProgress() const {
diff --git a/third_party/blink/renderer/core/page/autoscroll_controller.h b/third_party/blink/renderer/core/page/autoscroll_controller.h
index 33d4ded..0b0a711 100644
--- a/third_party/blink/renderer/core/page/autoscroll_controller.h
+++ b/third_party/blink/renderer/core/page/autoscroll_controller.h
@@ -105,15 +105,14 @@
 
   // Selection and drag-and-drop autoscroll.
   void ScheduleMainThreadAnimation();
-  Member<LayoutBox> autoscroll_layout_object_ = nullptr;
-  Member<LayoutBox> pressed_layout_object_ = nullptr;
-
+  LayoutBox* autoscroll_layout_object_ = nullptr;
+  LayoutBox* pressed_layout_object_ = nullptr;
   PhysicalOffset drag_and_drop_autoscroll_reference_position_;
   base::TimeTicks drag_and_drop_autoscroll_start_time_;
 
   // Middle-click autoscroll.
-  Member<LayoutBox> horizontal_autoscroll_layout_box_ = nullptr;
-  Member<LayoutBox> vertical_autoscroll_layout_box_ = nullptr;
+  LayoutBox* horizontal_autoscroll_layout_box_ = nullptr;
+  LayoutBox* vertical_autoscroll_layout_box_ = nullptr;
   FloatPoint middle_click_autoscroll_start_pos_global_;
   gfx::Vector2dF last_velocity_;
   MiddleClickMode middle_click_mode_ = kMiddleClickInitial;
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc
index be36779..55741cfd 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.cc
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -41,6 +41,7 @@
 #include "cc/layers/picture_layer.h"
 #include "third_party/blink/public/common/page/page_zoom.h"
 #include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
+#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "third_party/blink/public/web/blink.h"
 #include "third_party/blink/public/web/web_autofill_client.h"
diff --git a/third_party/blink/renderer/core/page/print_context.cc b/third_party/blink/renderer/core/page/print_context.cc
index fe43ee1d..c8c66eeef 100644
--- a/third_party/blink/renderer/core/page/print_context.cc
+++ b/third_party/blink/renderer/core/page/print_context.cc
@@ -258,7 +258,8 @@
   // want to collect @page rules and figure out what declarations apply on a
   // given page (that may or may not exist).
   print_context->BeginPrintMode(800, 1000);
-  const ComputedStyle* style = document->StyleForPage(page_number);
+  scoped_refptr<const ComputedStyle> style =
+      document->StyleForPage(page_number);
 
   // Implement formatters for properties we care about.
   if (!strcmp(property_name, "margin-left")) {
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
index e7cf485..b9b2d60 100644
--- a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/public/web/web_script_source.h"
 #include "third_party/blink/public/web/web_settings.h"
 #include "third_party/blink/renderer/bindings/core/v8/node_or_string_or_trusted_script.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_node_string_trustedscript.h"
 #include "third_party/blink/renderer/core/frame/browser_controls.h"
 #include "third_party/blink/renderer/core/frame/dom_visual_viewport.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
@@ -217,8 +218,14 @@
 
   // Replace the documentElement with the iframe. The effectiveRootScroller
   // should remain the same.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>> nodes;
+  nodes.push_back(
+      MakeGarbageCollected<V8UnionNodeOrStringOrTrustedScript>(iframe));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<NodeOrStringOrTrustedScript> nodes;
   nodes.push_back(NodeOrStringOrTrustedScript::FromNode(iframe));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   document->documentElement()->ReplaceWith(nodes, ASSERT_NO_EXCEPTION);
 
   UpdateAllLifecyclePhases(MainFrameView());
diff --git a/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc b/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
index 5b0c3dc..a7815a52 100644
--- a/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/scroll_into_view_options_or_boolean.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_to_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_boolean_scrollintoviewoptions.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/frame/find_in_page.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -42,11 +43,16 @@
   Compositor().BeginFrame();
   ASSERT_EQ(Window().scrollY(), 0);
   Element* content = GetDocument().getElementById("content");
-  ScrollIntoViewOptionsOrBoolean arg;
   ScrollIntoViewOptions* options = ScrollIntoViewOptions::Create();
   options->setBlock("start");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  content->scrollIntoView(
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScrollIntoViewOptionsOrBoolean arg;
   arg.SetScrollIntoViewOptions(options);
   content->scrollIntoView(arg);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   ASSERT_EQ(Window().scrollY(), content->OffsetTop());
 }
@@ -162,11 +168,16 @@
       "<div id='content' style='height: 1000px'></div>");
 
   Element* content = GetDocument().getElementById("content");
-  ScrollIntoViewOptionsOrBoolean arg;
   ScrollIntoViewOptions* options = ScrollIntoViewOptions::Create();
   options->setBlock("start");
   options->setBehavior("smooth");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScrollIntoViewOptionsOrBoolean arg;
   arg.SetScrollIntoViewOptions(options);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Compositor().BeginFrame();
   ASSERT_EQ(Window().scrollY(), 0);
 
@@ -201,11 +212,16 @@
 
   Element* container = GetDocument().getElementById("container");
   Element* content = GetDocument().getElementById("content");
-  ScrollIntoViewOptionsOrBoolean arg;
   ScrollIntoViewOptions* options = ScrollIntoViewOptions::Create();
   options->setBlock("start");
   options->setBehavior("smooth");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScrollIntoViewOptionsOrBoolean arg;
   arg.SetScrollIntoViewOptions(options);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Compositor().BeginFrame();
   ASSERT_EQ(Window().scrollY(), 0);
   ASSERT_EQ(container->scrollTop(), 0);
@@ -262,11 +278,16 @@
   Element* container2 = GetDocument().getElementById("container2");
   Element* content1 = GetDocument().getElementById("content1");
   Element* content2 = GetDocument().getElementById("content2");
-  ScrollIntoViewOptionsOrBoolean arg;
   ScrollIntoViewOptions* options = ScrollIntoViewOptions::Create();
   options->setBlock("start");
   options->setBehavior("smooth");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScrollIntoViewOptionsOrBoolean arg;
   arg.SetScrollIntoViewOptions(options);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   Compositor().BeginFrame();
   ASSERT_EQ(Window().scrollY(), 0);
@@ -334,11 +355,16 @@
 
   Element* container = GetDocument().getElementById("container");
   Element* content = GetDocument().getElementById("content");
-  ScrollIntoViewOptionsOrBoolean arg;
   ScrollIntoViewOptions* options = ScrollIntoViewOptions::Create();
   options->setBlock("start");
   options->setBehavior("smooth");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScrollIntoViewOptionsOrBoolean arg;
   arg.SetScrollIntoViewOptions(options);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Compositor().BeginFrame();
   ASSERT_EQ(Window().scrollY(), 0);
   ASSERT_EQ(container->scrollTop(), 0);
@@ -392,13 +418,20 @@
   int window_width = 800;
 
   Element* content = GetDocument().getElementById("content");
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScrollIntoViewOptionsOrBoolean arg1, arg2, arg3, arg4;
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScrollIntoViewOptions* options = ScrollIntoViewOptions::Create();
   ASSERT_EQ(Window().scrollY(), 0);
 
   options->setBlock("nearest");
   options->setInlinePosition("nearest");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg1 =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   arg1.SetScrollIntoViewOptions(options);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   content->scrollIntoView(arg1);
   ASSERT_EQ(Window().scrollX(),
             content->OffsetLeft() + content_width - window_width);
@@ -407,14 +440,24 @@
 
   options->setBlock("start");
   options->setInlinePosition("start");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg2 =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   arg2.SetScrollIntoViewOptions(options);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   content->scrollIntoView(arg2);
   ASSERT_EQ(Window().scrollX(), content->OffsetLeft());
   ASSERT_EQ(Window().scrollY(), content->OffsetTop());
 
   options->setBlock("center");
   options->setInlinePosition("center");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg3 =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   arg3.SetScrollIntoViewOptions(options);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   content->scrollIntoView(arg3);
   ASSERT_EQ(Window().scrollX(),
             content->OffsetLeft() + (content_width - window_width) / 2);
@@ -423,7 +466,12 @@
 
   options->setBlock("end");
   options->setInlinePosition("end");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg4 =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   arg4.SetScrollIntoViewOptions(options);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   content->scrollIntoView(arg4);
   ASSERT_EQ(Window().scrollX(),
             content->OffsetLeft() + content_width - window_width);
@@ -451,10 +499,15 @@
   Element* container = GetDocument().getElementById("container");
   Element* inner_container = GetDocument().getElementById("inner_container");
   Element* content = GetDocument().getElementById("content");
-  ScrollIntoViewOptionsOrBoolean arg;
   ScrollIntoViewOptions* options = ScrollIntoViewOptions::Create();
   options->setBlock("start");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScrollIntoViewOptionsOrBoolean arg;
   arg.SetScrollIntoViewOptions(options);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Compositor().BeginFrame();
   ASSERT_EQ(Window().scrollY(), 0);
   ASSERT_EQ(container->scrollTop(), 0);
@@ -553,10 +606,15 @@
       "<div id='content' style='height: 1000px'></div></html>");
 
   Element* content = GetDocument().getElementById("content");
-  ScrollIntoViewOptionsOrBoolean arg;
   ScrollIntoViewOptions* options = ScrollIntoViewOptions::Create();
   options->setBlock("start");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScrollIntoViewOptionsOrBoolean arg;
   arg.SetScrollIntoViewOptions(options);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Compositor().BeginFrame();
   ASSERT_EQ(Window().scrollY(), 0);
 
@@ -768,11 +826,16 @@
   ASSERT_EQ(Window().scrollY(), 0);
 
   Element* target = GetDocument().getElementById("target");
-  ScrollIntoViewOptionsOrBoolean arg;
   ScrollIntoViewOptions* options = ScrollIntoViewOptions::Create();
   options->setBlock("start");
   options->setBehavior("smooth");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* arg =
+      MakeGarbageCollected<V8UnionBooleanOrScrollIntoViewOptions>(options);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScrollIntoViewOptionsOrBoolean arg;
   arg.SetScrollIntoViewOptions(options);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   target->scrollIntoView(arg);
 
   // Scrolling the window
diff --git a/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
index eecde9e4..e18fbe6 100644
--- a/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
+++ b/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
@@ -39,10 +39,6 @@
 
 SnapCoordinator::~SnapCoordinator() = default;
 
-void SnapCoordinator::Trace(Visitor* visitor) const {
-  visitor->Trace(snap_containers_);
-}
-
 // Returns the layout box's next ancestor that can be a snap container.
 // The origin may be either a snap area or a snap container.
 LayoutBox* FindSnapContainer(const LayoutBox& origin_box) {
@@ -113,12 +109,12 @@
   SnapAreaSet* snap_areas = ancestor_snap_container->SnapAreas();
   if (!snap_areas)
     return;
-  HeapVector<Member<LayoutBox>> snap_areas_to_reassign;
-  for (const auto& snap_area : *snap_areas) {
+  Vector<LayoutBox*> snap_areas_to_reassign;
+  for (auto* snap_area : *snap_areas) {
     if (FindSnapContainer(*snap_area) == &snap_container)
       snap_areas_to_reassign.push_back(snap_area);
   }
-  for (const auto& snap_area : snap_areas_to_reassign)
+  for (auto* snap_area : snap_areas_to_reassign)
     snap_area->SetSnapContainer(&snap_container);
 
   // The new snap container will not have attached its ScrollableArea yet, so we
@@ -210,7 +206,7 @@
 }
 
 void SnapCoordinator::ResnapAllContainersIfNeeded() {
-  for (const auto& container : snap_containers_) {
+  for (const auto* container : snap_containers_) {
     if (!container->GetScrollableArea()->NeedsResnap())
       continue;
 
@@ -235,7 +231,7 @@
 }
 
 void SnapCoordinator::UpdateAllSnapContainerDataIfNeeded() {
-  for (const auto& container : snap_containers_) {
+  for (auto* container : snap_containers_) {
     if (container->GetScrollableArea()->SnapContainerDataNeedsUpdate())
       UpdateSnapContainerData(*container);
   }
@@ -433,14 +429,14 @@
 #ifndef NDEBUG
 
 void SnapCoordinator::ShowSnapAreaMap() {
-  for (const auto& container : snap_containers_)
+  for (auto* const container : snap_containers_)
     ShowSnapAreasFor(container);
 }
 
 void SnapCoordinator::ShowSnapAreasFor(const LayoutBox* container) {
   LOG(INFO) << *container->GetNode();
   if (SnapAreaSet* snap_areas = container->SnapAreas()) {
-    for (const auto& snap_area : *snap_areas) {
+    for (auto* const snap_area : *snap_areas) {
       LOG(INFO) << "    " << *snap_area->GetNode();
     }
   }
diff --git a/third_party/blink/renderer/core/page/scrolling/snap_coordinator.h b/third_party/blink/renderer/core/page/scrolling/snap_coordinator.h
index 3c0fbbc..98f72b3 100644
--- a/third_party/blink/renderer/core/page/scrolling/snap_coordinator.h
+++ b/third_party/blink/renderer/core/page/scrolling/snap_coordinator.h
@@ -36,7 +36,7 @@
  public:
   explicit SnapCoordinator();
   ~SnapCoordinator();
-  void Trace(Visitor* visitor) const;
+  void Trace(Visitor* visitor) const {}
 
   void AddSnapContainer(LayoutBox& snap_container);
   void RemoveSnapContainer(LayoutBox& snap_container);
@@ -76,7 +76,7 @@
  private:
   friend class SnapCoordinatorTest;
 
-  HeapHashSet<Member<LayoutBox>> snap_containers_;
+  HashSet<LayoutBox*> snap_containers_;
   bool any_snap_container_data_needs_update_ = true;
 
   // Used for reporting to UMA when snapping on the initial layout affects the
diff --git a/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.cc b/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.cc
index 0bb3c1ed..9326db5 100644
--- a/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.cc
+++ b/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.cc
@@ -122,18 +122,13 @@
          AncestorStickyBoxOffset(constraints_map);
 }
 
-void StickyPositionScrollingConstraints::Trace(Visitor* visitor) const {
-  visitor->Trace(nearest_sticky_layer_shifting_sticky_box);
-  visitor->Trace(nearest_sticky_layer_shifting_containing_block);
-}
-
 PhysicalOffset StickyPositionScrollingConstraints::AncestorStickyBoxOffset(
     const StickyConstraintsMap& constraints_map) const {
   if (!nearest_sticky_layer_shifting_sticky_box)
     return PhysicalOffset();
   DCHECK(constraints_map.Contains(nearest_sticky_layer_shifting_sticky_box));
   return constraints_map.at(nearest_sticky_layer_shifting_sticky_box)
-      ->total_sticky_box_sticky_offset;
+      .total_sticky_box_sticky_offset;
 }
 
 PhysicalOffset
@@ -145,7 +140,7 @@
   DCHECK(
       constraints_map.Contains(nearest_sticky_layer_shifting_containing_block));
   return constraints_map.at(nearest_sticky_layer_shifting_containing_block)
-      ->total_containing_block_sticky_offset;
+      .total_containing_block_sticky_offset;
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h b/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h
index f99e03b0..a9a04127 100644
--- a/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h
+++ b/third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h
@@ -7,7 +7,6 @@
 
 #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
 #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 
 namespace blink {
@@ -15,8 +14,7 @@
 class PaintLayer;
 struct StickyPositionScrollingConstraints;
 
-typedef HeapHashMap<Member<PaintLayer>,
-                    Member<StickyPositionScrollingConstraints>>
+typedef WTF::HashMap<PaintLayer*, StickyPositionScrollingConstraints>
     StickyConstraintsMap;
 
 // Encapsulates the constraint information for a position: sticky element and
@@ -73,14 +71,15 @@
 // already being shifted by its ancestor. To correctly handle such situations we
 // apply more complicated logic which is explained in the implementation of
 // |ComputeStickyOffset|.
-struct CORE_EXPORT StickyPositionScrollingConstraints final
-    : public GarbageCollected<StickyPositionScrollingConstraints> {
+struct StickyPositionScrollingConstraints final {
  public:
   StickyPositionScrollingConstraints()
       : is_anchored_left(false),
         is_anchored_right(false),
         is_anchored_top(false),
         is_anchored_bottom(false) {}
+  StickyPositionScrollingConstraints(
+      const StickyPositionScrollingConstraints& other) = default;
 
   // Computes the sticky offset for a given overflow clip rect.
   //
@@ -97,8 +96,6 @@
   // element. (Or after prepaint for CompositeAfterPaint).
   PhysicalOffset GetOffsetForStickyPosition(const StickyConstraintsMap&) const;
 
-  void Trace(Visitor* visitor) const;
-
   bool is_anchored_left : 1;
   bool is_anchored_right : 1;
   bool is_anchored_top : 1;
@@ -138,8 +135,8 @@
   //
   // See the implementation of |ComputeStickyOffset| for documentation on how
   // these ancestors are used to correct the offset calculation.
-  Member<PaintLayer> nearest_sticky_layer_shifting_sticky_box = nullptr;
-  Member<PaintLayer> nearest_sticky_layer_shifting_containing_block = nullptr;
+  PaintLayer* nearest_sticky_layer_shifting_sticky_box = nullptr;
+  PaintLayer* nearest_sticky_layer_shifting_containing_block = nullptr;
 
  private:
   // For performance we cache our accumulated sticky offset to allow descendant
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
index d9a20396..1e2e1922 100644
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/string_or_array_buffer_or_array_buffer_view.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_font_face_descriptors.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_mouse_event_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview_string.h"
 #include "third_party/blink/renderer/core/css/font_face_set_document.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/range.h"
@@ -104,9 +105,15 @@
   void LoadAhem() {
     scoped_refptr<SharedBuffer> shared_buffer =
         test::ReadFromFile(test::CoreTestDataPath("Ahem.ttf"));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* buffer =
+        MakeGarbageCollected<V8UnionArrayBufferOrArrayBufferViewOrString>(
+            DOMArrayBuffer::Create(shared_buffer));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     StringOrArrayBufferOrArrayBufferView buffer =
         StringOrArrayBufferOrArrayBufferView::FromArrayBuffer(
             DOMArrayBuffer::Create(shared_buffer));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     FontFace* ahem =
         FontFace::Create(GetDocument().GetFrame()->DomWindow(), "Ahem", buffer,
                          FontFaceDescriptors::Create());
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.h b/third_party/blink/renderer/core/paint/background_image_geometry.h
index 5c798b5..dc6c463 100644
--- a/third_party/blink/renderer/core/paint/background_image_geometry.h
+++ b/third_party/blink/renderer/core/paint/background_image_geometry.h
@@ -8,7 +8,6 @@
 #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
 #include "third_party/blink/renderer/core/paint/paint_phase.h"
 #include "third_party/blink/renderer/platform/graphics/graphics_types.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 namespace blink {
diff --git a/third_party/blink/renderer/core/paint/box_paint_invalidator.cc b/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
index 72e3e3e..9319573 100644
--- a/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
+++ b/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
@@ -235,7 +235,7 @@
   bool background_size_changed =
       new_background_rect.size != old_background_rect.size;
   if (background_location_changed || background_size_changed) {
-    for (const auto& object :
+    for (auto* object :
          layout_view.GetFrameView()->BackgroundAttachmentFixedObjects())
       object->SetBackgroundNeedsFullPaintInvalidation();
   }
diff --git a/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc b/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
index 0f21923..b2c2480 100644
--- a/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
+++ b/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
@@ -31,8 +31,8 @@
       const PhysicalOffset& old_paint_offset) {
     PaintInvalidatorContext context;
     context.old_paint_offset = old_paint_offset;
-    fragment_data_->SetPaintOffset(box.FirstFragment().PaintOffset());
-    context.fragment_data = fragment_data_;
+    fragment_data_.SetPaintOffset(box.FirstFragment().PaintOffset());
+    context.fragment_data = &fragment_data_;
     return BoxPaintInvalidator(box, context).ComputePaintInvalidationReason();
   }
 
@@ -94,8 +94,7 @@
   }
 
  private:
-  Persistent<FragmentData> fragment_data_ =
-      MakeGarbageCollected<FragmentData>();
+  FragmentData fragment_data_;
 };
 
 INSTANTIATE_PAINT_TEST_SUITE_P(BoxPaintInvalidatorTest);
diff --git a/third_party/blink/renderer/core/paint/build.gni b/third_party/blink/renderer/core/paint/build.gni
index 4a52d73e..bc9e44b5 100644
--- a/third_party/blink/renderer/core/paint/build.gni
+++ b/third_party/blink/renderer/core/paint/build.gni
@@ -161,7 +161,6 @@
   "paint_layer_clipper.cc",
   "paint_layer_clipper.h",
   "paint_layer_fragment.h",
-  "paint_layer_fragment.cc",
   "paint_layer_paint_order_iterator.cc",
   "paint_layer_paint_order_iterator.h",
   "paint_layer_painter.cc",
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
index aac445a..b85179e4 100644
--- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
+++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -107,8 +107,8 @@
          layer.AncestorScrollContainerLayer()->NeedsCompositedScrolling();
 }
 
-// Returns the sticky position offset that should be removed from a given
-// layer for use in CompositedLayerMapping.
+// Returns the sticky position offset that should be removed from a given layer
+// for use in CompositedLayerMapping.
 //
 // If the layer is not using composited sticky position, this will return
 // FloatPoint().
@@ -120,10 +120,10 @@
       layer.AncestorScrollContainerLayer()
           ->GetScrollableArea()
           ->GetStickyConstraintsMap();
-  const StickyPositionScrollingConstraints* constraints =
+  const StickyPositionScrollingConstraints& constraints =
       constraints_map.at(&layer);
 
-  return FloatPoint(constraints->GetOffsetForStickyPosition(constraints_map));
+  return FloatPoint(constraints.GetOffsetForStickyPosition(constraints_map));
 }
 
 static bool NeedsDecorationOutlineLayer(const PaintLayer& paint_layer,
@@ -139,8 +139,8 @@
       layout_object.IsCanvas() || IsA<LayoutVideo>(layout_object);
 
   // Unlike normal outlines (whole width is outside of the offset), focus
-  // rings can be drawn with the center of the path aligned with the offset,
-  // so only 2/3 of the width is outside of the offset.
+  // rings can be drawn with the center of the path aligned with the offset, so
+  // only 2/3 of the width is outside of the offset.
   const int outline_drawn_inside =
       style.OutlineStyleIsAuto()
           ? std::ceil(style.GetOutlineStrokeWidthForFocusRing() / 3.f) + 1
@@ -152,7 +152,7 @@
 }
 
 CompositedLayerMapping::CompositedLayerMapping(PaintLayer& layer)
-    : owning_layer_(&layer), pending_update_scope_(kGraphicsLayerUpdateNone) {
+    : owning_layer_(layer), pending_update_scope_(kGraphicsLayerUpdateNone) {
   CreatePrimaryGraphicsLayer();
 }
 
@@ -189,7 +189,7 @@
 
   graphics_layer->SetCompositingReasons(reasons);
   graphics_layer->SetSquashingDisallowedReasons(squashing_disallowed_reasons);
-  if (Node* owning_node = owning_layer_->GetLayoutObject().GetNode()) {
+  if (Node* owning_node = owning_layer_.GetLayoutObject().GetNode()) {
     graphics_layer->SetOwnerNodeId(
         static_cast<int>(DOMNodeIds::IdForNode(owning_node)));
   }
@@ -199,8 +199,8 @@
 
 void CompositedLayerMapping::CreatePrimaryGraphicsLayer() {
   graphics_layer_ =
-      CreateGraphicsLayer(owning_layer_->GetCompositingReasons(),
-                          owning_layer_->GetSquashingDisallowedReasons());
+      CreateGraphicsLayer(owning_layer_.GetCompositingReasons(),
+                          owning_layer_.GetSquashingDisallowedReasons());
 
   graphics_layer_->SetHitTestable(true);
 }
@@ -208,7 +208,7 @@
 void CompositedLayerMapping::UpdateGraphicsLayerContentsOpaque(
     bool should_check_children) {
   if (BackgroundPaintsOntoGraphicsLayer()) {
-    bool contents_opaque = owning_layer_->BackgroundIsKnownToBeOpaqueInRect(
+    bool contents_opaque = owning_layer_.BackgroundIsKnownToBeOpaqueInRect(
         CompositedBounds(), should_check_children);
     graphics_layer_->CcLayer().SetContentsOpaque(contents_opaque);
     if (!contents_opaque) {
@@ -235,7 +235,7 @@
     // TODO(flackr): This should actually check the entire overflow rect
     // within the scrolling contents layer but since we currently only trigger
     // this for solid color backgrounds the answer will be the same.
-    bool contents_opaque = owning_layer_->BackgroundIsKnownToBeOpaqueInRect(
+    bool contents_opaque = owning_layer_.BackgroundIsKnownToBeOpaqueInRect(
         To<LayoutBox>(GetLayoutObject()).PhysicalPaddingBoxRect(),
         should_check_children);
     scrolling_contents_layer_->CcLayer().SetContentsOpaque(contents_opaque);
@@ -269,25 +269,24 @@
 }
 
 void CompositedLayerMapping::UpdateCompositedBounds() {
-  DCHECK_EQ(owning_layer_->Compositor()->Lifecycle().GetState(),
+  DCHECK_EQ(owning_layer_.Compositor()->Lifecycle().GetState(),
             DocumentLifecycle::kInCompositingAssignmentsUpdate);
   // FIXME: if this is really needed for performance, it would be better to
   // store it on Layer.
-  composited_bounds_ = owning_layer_->BoundingBoxForCompositing();
+  composited_bounds_ = owning_layer_.BoundingBoxForCompositing();
 }
 
 void CompositedLayerMapping::UpdateCompositingReasons() {
   // All other layers owned by this mapping will have the same compositing
   // reason for their lifetime, so they are initialized only when created.
-  graphics_layer_->SetCompositingReasons(
-      owning_layer_->GetCompositingReasons());
+  graphics_layer_->SetCompositingReasons(owning_layer_.GetCompositingReasons());
   graphics_layer_->SetSquashingDisallowedReasons(
-      owning_layer_->GetSquashingDisallowedReasons());
+      owning_layer_.GetSquashingDisallowedReasons());
 }
 
 bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
     const PaintLayer* compositing_container) {
-  DCHECK_EQ(owning_layer_->Compositor()->Lifecycle().GetState(),
+  DCHECK_EQ(owning_layer_.Compositor()->Lifecycle().GetState(),
             DocumentLifecycle::kInCompositingAssignmentsUpdate);
 
   // Note carefully: here we assume that the compositing state of all
@@ -302,17 +301,17 @@
   bool layer_config_changed = false;
 
   if (UpdateForegroundLayer(
-          compositor->NeedsContentsCompositingLayer(owning_layer_)))
+          compositor->NeedsContentsCompositingLayer(&owning_layer_)))
     layer_config_changed = true;
 
-  if (UpdateScrollingContentsLayer(owning_layer_->NeedsCompositedScrolling()))
+  if (UpdateScrollingContentsLayer(owning_layer_.NeedsCompositedScrolling()))
     layer_config_changed = true;
 
   // If the outline needs to draw over the composited scrolling contents layer
   // or scrollbar layers (or video or webgl) it needs to be drawn into a
   // separate layer.
   bool needs_decoration_outline_layer =
-      NeedsDecorationOutlineLayer(*owning_layer_, layout_object);
+      NeedsDecorationOutlineLayer(owning_layer_, layout_object);
 
   if (UpdateDecorationOutlineLayer(needs_decoration_outline_layer))
     layer_config_changed = true;
@@ -355,16 +354,15 @@
   }
 
   if (layer_config_changed) {
-    // Changes to either the internal hierarchy or the mask layer have an
-    // impact on painting phases, so we need to update when either are
-    // updated.
+    // Changes to either the internal hierarchy or the mask layer have an impact
+    // on painting phases, so we need to update when either are updated.
     UpdatePaintingPhases();
   }
 
   UpdateElementId();
 
   if (style.Preserves3D() && style.HasOpacity() &&
-      owning_layer_->Has3DTransformedDescendant()) {
+      owning_layer_.Has3DTransformedDescendant()) {
     UseCounter::Count(layout_object.GetDocument(),
                       WebFeature::kOpacityWithPreserve3DQuirk);
   }
@@ -380,9 +378,8 @@
   // Add in the offset of the composited bounds from the coordinate space of
   // the PaintLayer, since visualOffsetFromAncestor() requires the pre-offset
   // input to be in the space of the PaintLayer. We also need to add in this
-  // offset before computation of visualOffsetFromAncestor(), because it
-  // affects fragmentation offset if compositedAncestor crosses a pagination
-  // boundary.
+  // offset before computation of visualOffsetFromAncestor(), because it affects
+  // fragmentation offset if compositedAncestor crosses a pagination boundary.
   //
   // Currently, visual fragmentation for composited layers is not implemented.
   // For fragmented contents, we paint in the logical coordinates of the flow
@@ -442,42 +439,40 @@
     IntPoint& snapped_offset_from_composited_ancestor) {
   // HACK(chrishtr): adjust for position of inlines.
   PhysicalOffset local_representative_point_for_fragmentation;
-  if (owning_layer_->GetLayoutObject().IsLayoutInline()) {
+  if (owning_layer_.GetLayoutObject().IsLayoutInline()) {
     local_representative_point_for_fragmentation =
-        To<LayoutInline>(owning_layer_->GetLayoutObject())
-            .FirstLineBoxTopLeft();
+        To<LayoutInline>(owning_layer_.GetLayoutObject()).FirstLineBoxTopLeft();
   }
-  // Blink will already have applied any necessary offset for sticky
-  // positioned elements. If the compositor is handling sticky offsets for
-  // this layer, we need to remove the Blink-side offset to avoid
-  // double-counting.
+  // Blink will already have applied any necessary offset for sticky positioned
+  // elements. If the compositor is handling sticky offsets for this layer, we
+  // need to remove the Blink-side offset to avoid double-counting.
   FloatPoint offset_for_sticky_position =
-      StickyPositionOffsetForLayer(*owning_layer_);
+      StickyPositionOffsetForLayer(owning_layer_);
   PhysicalOffset offset_from_composited_ancestor =
       ComputeOffsetFromCompositedAncestor(
-          owning_layer_, composited_ancestor,
+          &owning_layer_, composited_ancestor,
           local_representative_point_for_fragmentation,
           offset_for_sticky_position);
   PhysicalOffset subpixel_accumulation = ComputeSubpixelAccumulation(
-      offset_from_composited_ancestor, *owning_layer_,
+      offset_from_composited_ancestor, owning_layer_,
       snapped_offset_from_composited_ancestor);
 
   // Invalidate the whole layer when subpixel accumulation changes, since
   // the previous subpixel accumulation is baked into the display list.
   // However, don't do so for directly composited layers, to avoid impacting
   // performance.
-  if (subpixel_accumulation != owning_layer_->SubpixelAccumulation()) {
+  if (subpixel_accumulation != owning_layer_.SubpixelAccumulation()) {
     // Always invalidate if under-invalidation checking is on, to avoid
     // false positives.
     if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
-        !(owning_layer_->GetCompositingReasons() &
+        !(owning_layer_.GetCompositingReasons() &
           CompositingReason::kComboAllDirectReasons))
       GetLayoutObject().SetShouldCheckForPaintInvalidation();
   }
 
   // Otherwise discard the sub-pixel remainder because paint offset can't be
   // transformed by a non-translation transform.
-  owning_layer_->SetSubpixelAccumulation(subpixel_accumulation);
+  owning_layer_.SetSubpixelAccumulation(subpixel_accumulation);
 
   base::Optional<IntRect> mask_bounding_box =
       CSSMaskPainter::MaskBoundingBox(GetLayoutObject(), subpixel_accumulation);
@@ -508,7 +503,7 @@
     const PaintLayer* compositing_container,
     const IntPoint& snapped_offset_from_composited_ancestor,
     Vector<GraphicsLayerPaintInfo>& layers,
-    HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) {
+    Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   if (!non_scrolling_squashing_layer_)
     return;
 
@@ -530,7 +525,7 @@
     common_transform_ancestor =
         &compositing_container->TransformAncestorOrRoot();
   } else {
-    common_transform_ancestor = owning_layer_->Root();
+    common_transform_ancestor = owning_layer_.Root();
   }
 
   // FIXME: Cache these offsets.
@@ -579,11 +574,11 @@
   //
   // The painting offset we want to compute for each squashed PaintLayer is
   // essentially the position of the squashed PaintLayer described w.r.t.
-  // compositingContainer's origin.  So we just need to convert that point
-  // from compositingContainer space to the squashing layer's space. This is
-  // done by subtracting squashLayerOriginInCompositingContainerSpace, but
-  // then the offset overall needs to be negated because that's the direction
-  // that the painting code expects the offset to be.
+  // compositingContainer's origin.  So we just need to convert that point from
+  // compositingContainer space to the squashing layer's space. This is done by
+  // subtracting squashLayerOriginInCompositingContainerSpace, but then the
+  // offset overall needs to be negated because that's the direction that the
+  // painting code expects the offset to be.
   for (auto& layer : layers) {
     const PhysicalOffset squashed_layer_offset_from_transformed_ancestor =
         layer.paint_layer->ComputeOffsetFromAncestor(
@@ -620,17 +615,17 @@
     non_scrolling_squashing_layer_offset_from_layout_object_ = new_offset;
     // Need to update squashing LayerState according to the new offset.
     // GraphicsLayerUpdater does this.
-    layers_needing_paint_invalidation.push_back(owning_layer_);
+    layers_needing_paint_invalidation.push_back(&owning_layer_);
   }
 
   for (auto& layer : layers)
-    UpdateLocalClipRectForSquashedLayer(*owning_layer_, layers, layer);
+    UpdateLocalClipRectForSquashedLayer(owning_layer_, layers, layer);
 }
 
 void CompositedLayerMapping::UpdateGraphicsLayerGeometry(
     const PaintLayer* compositing_container,
-    HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) {
-  DCHECK_EQ(owning_layer_->Compositor()->Lifecycle().GetState(),
+    Vector<PaintLayer*>& layers_needing_paint_invalidation) {
+  DCHECK_EQ(owning_layer_.Compositor()->Lifecycle().GetState(),
             DocumentLifecycle::kInCompositingAssignmentsUpdate);
 
   IntRect local_compositing_bounds;
@@ -648,9 +643,9 @@
   UpdateScrollingContentsLayerGeometry(layers_needing_paint_invalidation);
   UpdateForegroundLayerGeometry();
 
-  if (owning_layer_->GetScrollableArea() &&
-      owning_layer_->GetScrollableArea()->ScrollsOverflow())
-    owning_layer_->GetScrollableArea()->PositionOverflowControls();
+  if (owning_layer_.GetScrollableArea() &&
+      owning_layer_.GetScrollableArea()->ScrollsOverflow())
+    owning_layer_.GetScrollableArea()->PositionOverflowControls();
 
   UpdateContentsRect();
   UpdateDrawsContentAndPaintsHitTest();
@@ -665,17 +660,17 @@
       ToIntSize(local_compositing_bounds.Location()));
   graphics_layer_->SetSize(gfx::Size(local_compositing_bounds.Size()));
 
-  // m_graphicsLayer is the corresponding GraphicsLayer for this PaintLayer
-  // and its non-compositing descendants. So, the visibility flag for
+  // m_graphicsLayer is the corresponding GraphicsLayer for this PaintLayer and
+  // its non-compositing descendants. So, the visibility flag for
   // m_graphicsLayer should be true if there are any non-compositing visible
   // layers.
-  bool contents_visible = owning_layer_->HasVisibleContent() ||
-                          HasVisibleNonCompositingDescendant(owning_layer_);
-  // TODO(sunxd): Investigate and possibly implement computing hit test
-  // regions in PaintTouchActionRects code path, so that cc has correct
-  // pointer-events information. For now, there is no need to set
-  // graphics_layer_'s hit testable bit here, because it is always hit
-  // testable from cc's perspective.
+  bool contents_visible = owning_layer_.HasVisibleContent() ||
+                          HasVisibleNonCompositingDescendant(&owning_layer_);
+  // TODO(sunxd): Investigate and possibly implement computing hit test regions
+  // in PaintTouchActionRects code path, so that cc has correct pointer-events
+  // information.
+  // For now, there is no need to set graphics_layer_'s hit testable bit here,
+  // because it is always hit testable from cc's perspective.
   graphics_layer_->SetContentsVisible(contents_visible);
 }
 
@@ -716,7 +711,7 @@
 }
 
 void CompositedLayerMapping::UpdateScrollingContentsLayerGeometry(
-    HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) {
+    Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   if (!scrolling_contents_layer_) {
     DCHECK(squashed_layers_in_scrolling_contents_.IsEmpty());
     return;
@@ -725,22 +720,21 @@
   DCHECK(scrolling_contents_layer_);
   auto& layout_box = To<LayoutBox>(GetLayoutObject());
   IntRect overflow_clip_rect = PixelSnappedIntRect(
-      layout_box.OverflowClipRect(owning_layer_->SubpixelAccumulation()));
+      layout_box.OverflowClipRect(owning_layer_.SubpixelAccumulation()));
 
   bool scroll_container_size_changed =
       previous_scroll_container_size_ != overflow_clip_rect.Size();
   if (scroll_container_size_changed)
     previous_scroll_container_size_ = overflow_clip_rect.Size();
 
-  PaintLayerScrollableArea* scrollable_area =
-      owning_layer_->GetScrollableArea();
+  PaintLayerScrollableArea* scrollable_area = owning_layer_.GetScrollableArea();
   IntSize scroll_size = scrollable_area->PixelSnappedContentsSize(
-      owning_layer_->SubpixelAccumulation());
+      owning_layer_.SubpixelAccumulation());
 
   // Ensure scrolling contents are at least as large as the scroll clip
   scroll_size = scroll_size.ExpandedTo(overflow_clip_rect.Size());
 
-  auto* scrolling_coordinator = owning_layer_->GetScrollingCoordinator();
+  auto* scrolling_coordinator = owning_layer_.GetScrollingCoordinator();
   scrolling_coordinator->UpdateCompositorScrollOffset(*layout_box.GetFrame(),
                                                       *scrollable_area);
 
@@ -757,8 +751,8 @@
   for (auto& layer : squashed_layers_in_scrolling_contents_) {
     layer.composited_bounds = layer.paint_layer->BoundingBoxForCompositing();
     PhysicalOffset offset_from_scrolling_contents_layer =
-        layer.paint_layer->ComputeOffsetFromAncestor(*owning_layer_) +
-        owning_layer_->SubpixelAccumulation() -
+        layer.paint_layer->ComputeOffsetFromAncestor(owning_layer_) +
+        owning_layer_.SubpixelAccumulation() -
         PhysicalOffset(scrolling_contents_layer_->OffsetFromLayoutObject());
     IntSize new_offset_from_layout_object =
         -ToIntSize(RoundedIntPoint(offset_from_scrolling_contents_layer));
@@ -776,23 +770,23 @@
   }
   for (auto& layer : squashed_layers_in_scrolling_contents_) {
     UpdateLocalClipRectForSquashedLayer(
-        *owning_layer_, squashed_layers_in_scrolling_contents_, layer);
+        owning_layer_, squashed_layers_in_scrolling_contents_, layer);
   }
 }
 
 bool CompositedLayerMapping::RequiresHorizontalScrollbarLayer() const {
-  return owning_layer_->GetScrollableArea() &&
-         owning_layer_->GetScrollableArea()->HorizontalScrollbar();
+  return owning_layer_.GetScrollableArea() &&
+         owning_layer_.GetScrollableArea()->HorizontalScrollbar();
 }
 
 bool CompositedLayerMapping::RequiresVerticalScrollbarLayer() const {
-  return owning_layer_->GetScrollableArea() &&
-         owning_layer_->GetScrollableArea()->VerticalScrollbar();
+  return owning_layer_.GetScrollableArea() &&
+         owning_layer_.GetScrollableArea()->VerticalScrollbar();
 }
 
 bool CompositedLayerMapping::RequiresScrollCornerLayer() const {
-  return owning_layer_->GetScrollableArea() &&
-         !owning_layer_->GetScrollableArea()
+  return owning_layer_.GetScrollableArea() &&
+         !owning_layer_.GetScrollableArea()
               ->ScrollCornerAndResizerRect()
               .IsEmpty();
 }
@@ -834,9 +828,9 @@
   graphics_layer_->RemoveFromParent();
 
   bool overflow_controls_after_scrolling_contents =
-      owning_layer_->IsRootLayer() ||
-      (owning_layer_->GetScrollableArea() &&
-       owning_layer_->GetScrollableArea()->HasOverlayOverflowControls());
+      owning_layer_.IsRootLayer() ||
+      (owning_layer_.GetScrollableArea() &&
+       owning_layer_.GetScrollableArea()->HasOverlayOverflowControls());
   if (overflow_controls_after_scrolling_contents && scrolling_contents_layer_)
     graphics_layer_->AddChild(scrolling_contents_layer_.get());
 
@@ -902,8 +896,8 @@
                          GetLayoutObject().HasEffectiveAllowedTouchAction() ||
                          GetLayoutObject().InsideBlockingWheelEventHandler();
   bool paints_scroll_hit_test =
-      ((owning_layer_->GetScrollableArea() &&
-        owning_layer_->GetScrollableArea()->ScrollsOverflow()) ||
+      ((owning_layer_.GetScrollableArea() &&
+        owning_layer_.GetScrollableArea()->ScrollsOverflow()) ||
        (GetPluginContainer(GetLayoutObject()) &&
         GetPluginContainer(GetLayoutObject())->WantsWheelEvents()));
   graphics_layer_->SetPaintsHitTest(paints_hit_test || paints_scroll_hit_test);
@@ -913,7 +907,7 @@
     // contents need to paint.
     bool has_painted_scrolling_contents =
         !squashed_layers_in_scrolling_contents_.IsEmpty() ||
-        (owning_layer_->HasVisibleContent() &&
+        (owning_layer_.HasVisibleContent() &&
          (GetLayoutObject().StyleRef().HasBackground() ||
           GetLayoutObject().HasNonInitialBackdropFilter() || PaintsChildren()));
     scrolling_contents_layer_->SetDrawsContent(has_painted_scrolling_contents);
@@ -949,9 +943,9 @@
   layer = needs_layer ? CreateGraphicsLayer(reason) : nullptr;
 
   if (PaintLayerScrollableArea* scrollable_area =
-          owning_layer_->GetScrollableArea()) {
+          owning_layer_.GetScrollableArea()) {
     if (ScrollingCoordinator* scrolling_coordinator =
-            owning_layer_->GetScrollingCoordinator()) {
+            owning_layer_.GetScrollingCoordinator()) {
       if (reason == CompositingReason::kLayerForHorizontalScrollbar) {
         scrolling_coordinator->ScrollableAreaScrollbarLayerDidChange(
             scrollable_area, kHorizontalScrollbar);
@@ -969,7 +963,7 @@
     bool needs_vertical_scrollbar_layer,
     bool needs_scroll_corner_layer) {
   if (PaintLayerScrollableArea* scrollable_area =
-          owning_layer_->GetScrollableArea()) {
+          owning_layer_.GetScrollableArea()) {
     // If the scrollable area is marked as needing a new scrollbar layer,
     // destroy the layer now so that it will be created again below.
     if (layer_for_horizontal_scrollbar_ && needs_horizontal_scrollbar_layer &&
@@ -1000,7 +994,7 @@
   // and therefore visible content status may be invalid.
   if (needs_horizontal_scrollbar_layer || needs_vertical_scrollbar_layer ||
       needs_scroll_corner_layer) {
-    bool invisible = owning_layer_->SubtreeIsInvisible();
+    bool invisible = owning_layer_.SubtreeIsInvisible();
     needs_horizontal_scrollbar_layer &= !invisible;
     needs_vertical_scrollbar_layer &= !invisible;
     needs_scroll_corner_layer &= !invisible;
@@ -1022,8 +1016,7 @@
 
 void CompositedLayerMapping::PositionOverflowControlsLayers() {
   if (GraphicsLayer* layer = LayerForHorizontalScrollbar()) {
-    Scrollbar* h_bar =
-        owning_layer_->GetScrollableArea()->HorizontalScrollbar();
+    Scrollbar* h_bar = owning_layer_.GetScrollableArea()->HorizontalScrollbar();
     if (h_bar) {
       IntRect frame_rect = h_bar->FrameRect();
       layer->SetOffsetFromLayoutObject(ToIntSize(frame_rect.Location()));
@@ -1037,7 +1030,7 @@
   }
 
   if (GraphicsLayer* layer = LayerForVerticalScrollbar()) {
-    Scrollbar* v_bar = owning_layer_->GetScrollableArea()->VerticalScrollbar();
+    Scrollbar* v_bar = owning_layer_.GetScrollableArea()->VerticalScrollbar();
     if (v_bar) {
       IntRect frame_rect = v_bar->FrameRect();
       layer->SetOffsetFromLayoutObject(ToIntSize(frame_rect.Location()));
@@ -1052,7 +1045,7 @@
 
   if (GraphicsLayer* layer = LayerForScrollCorner()) {
     const IntRect& scroll_corner_and_resizer =
-        owning_layer_->GetScrollableArea()->ScrollCornerAndResizerRect();
+        owning_layer_.GetScrollableArea()->ScrollCornerAndResizerRect();
     layer->SetOffsetFromLayoutObject(
         ToIntSize(scroll_corner_and_resizer.Location()));
     layer->SetSize(gfx::Size(scroll_corner_and_resizer.Size()));
@@ -1080,15 +1073,15 @@
   null_checking_function(mapping->LayerForScrollCorner());
 }
 
-// You receive an element id if you have an animation, or you're a scroller
-// (and might impl animate).
+// You receive an element id if you have an animation, or you're a scroller (and
+// might impl animate).
 //
 // The element id for the scroll layers is assigned when they're constructed,
 // since this is unconditional. However, the element id for the primary layer
 // may change according to the rules above so we update those values here.
 void CompositedLayerMapping::UpdateElementId() {
   CompositorElementId element_id = CompositorElementIdFromUniqueObjectId(
-      owning_layer_->GetLayoutObject().UniqueId(),
+      owning_layer_.GetLayoutObject().UniqueId(),
       CompositorElementIdNamespace::kPrimary);
 
   graphics_layer_->SetElementId(element_id);
@@ -1158,9 +1151,9 @@
 bool CompositedLayerMapping::UpdateScrollingContentsLayer(
     bool needs_scrolling_contents_layer) {
   ScrollingCoordinator* scrolling_coordinator =
-      owning_layer_->GetScrollingCoordinator();
+      owning_layer_.GetScrollingCoordinator();
 
-  auto* scrollable_area = owning_layer_->GetScrollableArea();
+  auto* scrollable_area = owning_layer_.GetScrollableArea();
   if (scrollable_area)
     scrollable_area->SetUsesCompositedScrolling(needs_scrolling_contents_layer);
 
@@ -1238,11 +1231,11 @@
 }
 
 bool CompositedLayerMapping::PaintsChildren() const {
-  if (owning_layer_->HasVisibleContent() &&
-      owning_layer_->HasNonEmptyChildLayoutObjects())
+  if (owning_layer_.HasVisibleContent() &&
+      owning_layer_.HasNonEmptyChildLayoutObjects())
     return true;
 
-  if (HasVisibleNonCompositingDescendant(owning_layer_))
+  if (HasVisibleNonCompositingDescendant(&owning_layer_))
     return true;
 
   return false;
@@ -1258,7 +1251,7 @@
   if (!parent->HasVisibleDescendant())
     return false;
 
-  PaintLayerPaintOrderIterator iterator(parent, kAllChildren);
+  PaintLayerPaintOrderIterator iterator(*parent, kAllChildren);
   while (PaintLayer* child_layer = iterator.Next()) {
     if (child_layer->HasCompositedLayerMapping())
       continue;
@@ -1275,15 +1268,15 @@
     return false;
 
   LayoutObject& layout_object = GetLayoutObject();
-  // FIXME: we could optimize cases where the image, video or canvas is known
-  // to fill the border box entirely, and set background color on the layer in
-  // that case, instead of allocating backing store and painting.
+  // FIXME: we could optimize cases where the image, video or canvas is known to
+  // fill the border box entirely, and set background color on the layer in that
+  // case, instead of allocating backing store and painting.
   auto* layout_video = DynamicTo<LayoutVideo>(layout_object);
   if (layout_video && layout_video->GetDisplayMode() == LayoutVideo::kVideo)
-    return owning_layer_->HasBoxDecorationsOrBackground();
+    return owning_layer_.HasBoxDecorationsOrBackground();
 
   if (layout_object.GetNode() && layout_object.GetNode()->IsDocumentNode()) {
-    if (owning_layer_->NeedsCompositedScrolling())
+    if (owning_layer_.NeedsCompositedScrolling())
       return BackgroundPaintsOntoGraphicsLayer();
 
     // Look to see if the root object has a non-simple background
@@ -1305,7 +1298,7 @@
       return true;
   }
 
-  if (owning_layer_->HasVisibleBoxDecorations())
+  if (owning_layer_.HasVisibleBoxDecorations())
     return true;
 
   if (layout_object.HasMask())  // masks require special treatment
@@ -1324,7 +1317,7 @@
 // Return the offset from the top-left of this compositing layer at which the
 // LayoutObject's contents are painted.
 PhysicalOffset CompositedLayerMapping::ContentOffsetInCompositingLayer() const {
-  return owning_layer_->SubpixelAccumulation() -
+  return owning_layer_.SubpixelAccumulation() -
          PhysicalOffset(graphics_layer_->OffsetFromLayoutObject());
 }
 
@@ -1335,7 +1328,7 @@
 }
 
 bool CompositedLayerMapping::NeedsToReparentOverflowControls() const {
-  return owning_layer_->NeedsReorderOverlayOverflowControls();
+  return owning_layer_.NeedsReorderOverlayOverflowControls();
 }
 
 wtf_size_t CompositedLayerMapping::MoveOverflowControlLayersInto(
@@ -1456,7 +1449,7 @@
     paint_info.local_clip_rect_for_squashed_layer =
         ClipRect(PhysicalRect(LayoutRect::InfiniteIntRect()));
     paint_info.offset_from_clip_rect_root = PhysicalOffset();
-    paint_info.local_clip_rect_root = paint_info.paint_layer.Get();
+    paint_info.local_clip_rect_root = paint_info.paint_layer;
     return;
   }
 
@@ -1486,7 +1479,7 @@
   paint_info.local_clip_rect_for_squashed_layer = parent_clip_rect;
   paint_info.offset_from_clip_rect_root =
       PhysicalOffset(ancestor_to_local_offset);
-  paint_info.local_clip_rect_root = ancestor_paint_info->paint_layer.Get();
+  paint_info.local_clip_rect_root = ancestor_paint_info->paint_layer;
 }
 
 void CompositedLayerMapping::DoPaintTask(
@@ -1580,7 +1573,7 @@
 
   auto source_state = graphics_layer->GetPropertyTreeState();
 
-  LayoutView* root_view = owning_layer_->GetLayoutObject().View();
+  LayoutView* root_view = owning_layer_.GetLayoutObject().View();
   while (root_view->GetFrame()->OwnerLayoutObject())
     root_view = root_view->GetFrame()->OwnerLayoutObject()->View();
 
@@ -1595,8 +1588,8 @@
   FloatRect visible_content_rect(EnclosingIntRect(mapping_rect.Rect()));
 
   FloatRect local_interest_rect;
-  // If the visible content rect is empty, then it makes no sense to map it
-  // back since there is nothing to map.
+  // If the visible content rect is empty, then it makes no sense to map it back
+  // since there is nothing to map.
   if (!visible_content_rect.IsEmpty()) {
     local_interest_rect = visible_content_rect;
     // 3. Map the visible content rect from root view space to local graphics
@@ -1611,9 +1604,9 @@
     // and return whether the mapping failed.  In some cases,
     // absoluteToLocalQuad can fail to map back to the local space, due to
     // passing through non-invertible transforms or floating-point accuracy
-    // issues. Examples include rotation near 90 degrees or perspective. In
-    // such cases, fall back to painting the first kPixelDistanceToRecord
-    // pixels in each direction.
+    // issues. Examples include rotation near 90 degrees or perspective. In such
+    // cases, fall back to painting the first kPixelDistanceToRecord pixels in
+    // each direction.
 
     // Note that since the interest rect mapping above can produce extremely
     // large numbers in cases of perspective, try our best to "normalize" the
@@ -1622,8 +1615,8 @@
     const float reasonable_pixel_limit = std::numeric_limits<int>::max() / 2.f;
     auto unpadded_intersection = local_interest_rect;
 
-    // Note that by clamping X and Y, we are effectively moving the rect right
-    // / down. However, this will at most make us paint more content, which is
+    // Note that by clamping X and Y, we are effectively moving the rect right /
+    // down. However, this will at most make us paint more content, which is
     // better than erroneously deciding that the rect produced here is far
     // offscreen.
     if (unpadded_intersection.X() < -reasonable_pixel_limit)
@@ -1640,10 +1633,9 @@
     }
 
     unpadded_intersection.Intersect(FloatRect(graphics_layer_bounds));
-    // If our unpadded intersection is not empty, then use that before
-    // padding, since it can produce more stable results, and it would not
-    // produce any smaller area than if we used the original local interest
-    // rect.
+    // If our unpadded intersection is not empty, then use that before padding,
+    // since it can produce more stable results, and it would not produce any
+    // smaller area than if we used the original local interest rect.
     if (!unpadded_intersection.IsEmpty())
       local_interest_rect = unpadded_intersection;
 
@@ -1685,8 +1677,8 @@
   if (previous_interest_rect.IsEmpty() && new_interest_rect.IsEmpty())
     return false;
 
-  // Repaint when going from empty to not-empty, to cover cases where the
-  // layer is painted for the first time, or otherwise becomes visible.
+  // Repaint when going from empty to not-empty, to cover cases where the layer
+  // is painted for the first time, or otherwise becomes visible.
   if (previous_interest_rect.IsEmpty())
     return true;
 
@@ -1698,10 +1690,10 @@
     return true;
 
   // Even if the new interest rect doesn't include enough new area to satisfy
-  // the condition above, repaint anyway if it touches a layer edge not
-  // touched by the existing interest rect.  Because it's impossible to expose
-  // more area in the direction, repainting cannot be deferred until the
-  // exposed new area satisfies the condition above.
+  // the condition above, repaint anyway if it touches a layer edge not touched
+  // by the existing interest rect.  Because it's impossible to expose more area
+  // in the direction, repainting cannot be deferred until the exposed new area
+  // satisfies the condition above.
   if (new_interest_rect.X() == 0 && previous_interest_rect.X() != 0)
     return true;
   if (new_interest_rect.Y() == 0 && previous_interest_rect.Y() != 0)
@@ -1760,13 +1752,13 @@
 }
 
 LayoutSize CompositedLayerMapping::SubpixelAccumulation() const {
-  return owning_layer_->SubpixelAccumulation().ToLayoutSize();
+  return owning_layer_.SubpixelAccumulation().ToLayoutSize();
 }
 
 bool CompositedLayerMapping::NeedsRepaint(
     const GraphicsLayer& graphics_layer) const {
   return IsScrollableAreaLayerWhichNeedsRepaint(&graphics_layer) ||
-         owning_layer_->SelfOrDescendantNeedsRepaint();
+         owning_layer_.SelfOrDescendantNeedsRepaint();
 }
 
 bool CompositedLayerMapping::AdjustForCompositedScrolling(
@@ -1775,10 +1767,10 @@
   if (graphics_layer == scrolling_contents_layer_.get() ||
       graphics_layer == foreground_layer_.get()) {
     if (PaintLayerScrollableArea* scrollable_area =
-            owning_layer_->GetScrollableArea()) {
+            owning_layer_.GetScrollableArea()) {
       if (scrollable_area->UsesCompositedScrolling()) {
-        // Note: this is the offset from the beginning of flow of the block,
-        // not the offset from the top/left of the overflow rect.
+        // Note: this is the offset from the beginning of flow of the block, not
+        // the offset from the top/left of the overflow rect.
         // offsetFromLayoutObject adds the origin offset from top/left to the
         // beginning of flow.
         ScrollOffset scroll_offset = scrollable_area->GetScrollOffset();
@@ -1835,13 +1827,13 @@
     page->SetIsPainting(true);
 #endif
 
-  DCHECK(owning_layer_->GetLayoutObject()
+  DCHECK(owning_layer_.GetLayoutObject()
              .GetFrameView()
              ->LocalFrameTreeAllowsThrottling());
 
   DEVTOOLS_TIMELINE_TRACE_EVENT_WITH_CATEGORIES(
       "devtools.timeline,rail", "Paint", inspector_paint_event::Data,
-      &owning_layer_->GetLayoutObject(), PhysicalRect(interest_rect),
+      &owning_layer_.GetLayoutObject(), PhysicalRect(interest_rect),
       graphics_layer);
 
   PaintLayerFlags paint_layer_flags =
@@ -1861,15 +1853,15 @@
     }
 
     GraphicsLayerPaintInfo paint_info;
-    paint_info.paint_layer = owning_layer_;
+    paint_info.paint_layer = &owning_layer_;
     paint_info.composited_bounds = CompositedBounds();
     paint_info.offset_from_layout_object =
         graphics_layer->OffsetFromLayoutObject();
     AdjustForCompositedScrolling(graphics_layer,
                                  paint_info.offset_from_layout_object);
 
-    // We have to use the same root as for hit testing, because both methods
-    // can compute and cache clipRects.
+    // We have to use the same root as for hit testing, because both methods can
+    // compute and cache clipRects.
     DoPaintTask(paint_info, *graphics_layer, paint_layer_flags, context,
                 interest_rect);
 
@@ -1911,8 +1903,7 @@
   // Scrollbar::Paint() will paint the scrollbar.
   CullRect cull_rect(interest_rect);
   cull_rect.Move(graphics_layer->OffsetFromLayoutObject());
-  PaintLayerScrollableArea* scrollable_area =
-      owning_layer_->GetScrollableArea();
+  PaintLayerScrollableArea* scrollable_area = owning_layer_.GetScrollableArea();
   ScrollableAreaPainter painter(*scrollable_area);
   if (graphics_layer == LayerForHorizontalScrollbar()) {
     if (Scrollbar* scrollbar = scrollable_area->HorizontalScrollbar())
@@ -1936,7 +1927,7 @@
 bool CompositedLayerMapping::IsScrollableAreaLayerWhichNeedsRepaint(
     const GraphicsLayer* graphics_layer) const {
   if (PaintLayerScrollableArea* scrollable_area =
-          owning_layer_->GetScrollableArea()) {
+          owning_layer_.GetScrollableArea()) {
     if (graphics_layer == LayerForHorizontalScrollbar())
       return scrollable_area->HorizontalScrollbarNeedsPaintInvalidation();
 
@@ -1952,7 +1943,7 @@
 
 bool CompositedLayerMapping::ShouldSkipPaintingSubtree() const {
   return GetLayoutObject().GetFrame()->ShouldThrottleRendering() ||
-         owning_layer_->IsUnderSVGHiddenContainer() ||
+         owning_layer_.IsUnderSVGHiddenContainer() ||
          DisplayLockUtilities::NearestLockedExclusiveAncestor(
              GetLayoutObject());
 }
@@ -2073,7 +2064,7 @@
 static void RemoveExtraSquashedLayers(
     Vector<GraphicsLayerPaintInfo>& squashed_layers,
     wtf_size_t new_count,
-    HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) {
+    Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   DCHECK_GE(squashed_layers.size(), new_count);
   if (squashed_layers.size() == new_count)
     return;
@@ -2085,7 +2076,7 @@
 void CompositedLayerMapping::FinishAccumulatingSquashingLayers(
     wtf_size_t new_non_scrolling_squashed_layer_count,
     wtf_size_t new_squashed_layer_in_scrolling_contents_count,
-    HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) {
+    Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   wtf_size_t first_removed_layer = layers_needing_paint_invalidation.size();
   RemoveExtraSquashedLayers(non_scrolling_squashed_layers_,
                             new_non_scrolling_squashed_layer_count,
@@ -2096,10 +2087,9 @@
   for (auto i = first_removed_layer;
        i < layers_needing_paint_invalidation.size(); i++) {
     PaintLayer* layer = layers_needing_paint_invalidation[i];
-    // Deal with layers that are no longer squashed. Need to check both
-    // vectors to exclude the layers that are still squashed. A layer may
-    // change from scrolling to non-scrolling or vice versa and still be
-    // squashed.
+    // Deal with layers that are no longer squashed. Need to check both vectors
+    // to exclude the layers that are still squashed. A layer may change from
+    // scrolling to non-scrolling or vice versa and still be squashed.
     if (!LayerInSquashedLayersVector(non_scrolling_squashed_layers_, *layer) &&
         !LayerInSquashedLayersVector(squashed_layers_in_scrolling_contents_,
                                      *layer)) {
@@ -2115,7 +2105,7 @@
     const GraphicsLayer* graphics_layer) const {
   String name;
   if (graphics_layer == graphics_layer_.get()) {
-    name = owning_layer_->DebugName();
+    name = owning_layer_.DebugName();
   } else if (graphics_layer == non_scrolling_squashing_layer_.get()) {
     name = "Squashing Layer (first squashed layer: " +
            (non_scrolling_squashed_layers_.size() > 0
@@ -2123,7 +2113,7 @@
                 : "") +
            ")";
   } else if (graphics_layer == foreground_layer_.get()) {
-    name = owning_layer_->DebugName() + " (foreground) Layer";
+    name = owning_layer_.DebugName() + " (foreground) Layer";
   } else if (graphics_layer == mask_layer_.get()) {
     name = "Mask Layer";
   } else if (graphics_layer == layer_for_horizontal_scrollbar_.get()) {
@@ -2146,7 +2136,7 @@
 const ScrollableArea* CompositedLayerMapping::GetScrollableAreaForTesting(
     const GraphicsLayer* layer) const {
   if (layer == scrolling_contents_layer_.get())
-    return owning_layer_->GetScrollableArea();
+    return owning_layer_.GetScrollableArea();
   return nullptr;
 }
 
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
index b03d89f..4d09a47 100644
--- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
+++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
@@ -49,26 +49,23 @@
   DISALLOW_NEW();
 
  public:
-  // TODO(crbug.com/1161155): Use Member or WeakMember
-  UntracedMember<PaintLayer> paint_layer = nullptr;
+  PaintLayer* paint_layer;
 
   PhysicalRect composited_bounds;
 
   // The clip rect to apply, in the local coordinate space of the squashed
   // layer, when painting it.
   ClipRect local_clip_rect_for_squashed_layer;
-
-  // TODO(crbug.com/1161155): Use Member or WeakMember
-  UntracedMember<PaintLayer> local_clip_rect_root = nullptr;
-
+  PaintLayer* local_clip_rect_root;
   PhysicalOffset offset_from_clip_rect_root;
 
   // Offset describing where this squashed Layer paints into the shared
   // GraphicsLayer backing.
   IntSize offset_from_layout_object;
-  bool offset_from_layout_object_set = false;
+  bool offset_from_layout_object_set;
 
-  GraphicsLayerPaintInfo() = default;
+  GraphicsLayerPaintInfo()
+      : paint_layer(nullptr), offset_from_layout_object_set(false) {}
 };
 
 enum GraphicsLayerUpdateScope {
@@ -92,19 +89,21 @@
 // - Otherwise the PaintLayer doesn't own or directly reference any
 //   CompositedLayerMapping.
 class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
+  USING_FAST_MALLOC(CompositedLayerMapping);
+
  public:
   explicit CompositedLayerMapping(PaintLayer&);
   CompositedLayerMapping(const CompositedLayerMapping&) = delete;
   CompositedLayerMapping& operator=(const CompositedLayerMapping&) = delete;
   ~CompositedLayerMapping() override;
 
-  PaintLayer& OwningLayer() const { return *owning_layer_; }
+  PaintLayer& OwningLayer() const { return owning_layer_; }
 
   bool UpdateGraphicsLayerConfiguration(
       const PaintLayer* compositing_container);
   void UpdateGraphicsLayerGeometry(
       const PaintLayer* compositing_container,
-      HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation);
+      Vector<PaintLayer*>& layers_needing_paint_invalidation);
 
   // Update whether layer needs blending.
   void UpdateContentsOpaque();
@@ -146,7 +145,7 @@
   void PositionOverflowControlsLayers();
 
   bool MayBeSquashedIntoScrollingContents(const PaintLayer& layer) const {
-    return layer.AncestorScrollingLayer() == owning_layer_;
+    return layer.AncestorScrollingLayer() == &owning_layer_;
   }
 
   // Returns true if the assignment actually changed the assigned squashing
@@ -163,7 +162,7 @@
   void FinishAccumulatingSquashingLayers(
       wtf_size_t new_non_scrolling_squashed_layer_count,
       wtf_size_t new_squashed_layer_in_scrolling_contents_count,
-      HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation);
+      Vector<PaintLayer*>& layers_needing_paint_invalidation);
 
   void UpdateElementId();
 
@@ -302,14 +301,14 @@
       const PaintLayer* compositing_container,
       const IntPoint& snapped_offset_from_composited_ancestor,
       Vector<GraphicsLayerPaintInfo>& layers,
-      HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation);
+      Vector<PaintLayer*>& layers_needing_paint_invalidation);
   void UpdateMainGraphicsLayerGeometry(const IntRect& local_compositing_bounds);
   void UpdateMaskLayerGeometry();
   void UpdateForegroundLayerGeometry();
   void UpdateDecorationOutlineLayerGeometry(
       const IntSize& relative_compositing_bounds_size);
   void UpdateScrollingContentsLayerGeometry(
-      HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation);
+      Vector<PaintLayer*>& layers_needing_paint_invalidation);
 
   void CreatePrimaryGraphicsLayer();
 
@@ -321,10 +320,10 @@
                                     CompositingReasons);
 
   LayoutBoxModelObject& GetLayoutObject() const {
-    return owning_layer_->GetLayoutObject();
+    return owning_layer_.GetLayoutObject();
   }
   PaintLayerCompositor* Compositor() const {
-    return owning_layer_->Compositor();
+    return owning_layer_.Compositor();
   }
 
   void UpdateInternalHierarchy();
@@ -385,8 +384,7 @@
       wtf_size_t next_squashed_layer_index);
   void RemoveSquashedLayers(Vector<GraphicsLayerPaintInfo>& squashed_layers);
 
-  // TODO(crbug.com/1161155): Use Member or WeakMember
-  UntracedMember<PaintLayer> owning_layer_;
+  PaintLayer& owning_layer_;
 
   // The hierarchy of layers that is maintained by the CompositedLayerMapping
   // looks like this:
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.cc b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.cc
index 2dc3444..1086d93 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.cc
@@ -33,8 +33,4 @@
   root_layer_ = common_ancestor;
 }
 
-void CompositingInputsRoot::Trace(Visitor* visitor) const {
-  visitor->Trace(root_layer_);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.h b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.h
index 37ccb88c..fe5b27d 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.h
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.h
@@ -5,7 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_INPUTS_ROOT_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_INPUTS_ROOT_H_
 
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 namespace blink {
@@ -21,10 +20,8 @@
   void Update(PaintLayer* new_root_layer);
   void Clear() { root_layer_ = nullptr; }
 
-  void Trace(Visitor* visitor) const;
-
  private:
-  Member<PaintLayer> root_layer_ = nullptr;
+  PaintLayer* root_layer_ = nullptr;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
index fd86cc2..3b7251a 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
@@ -14,7 +14,6 @@
 #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
 #include "third_party/blink/renderer/core/paint/paint_layer.h"
 #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
 
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc b/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc
index b668236..999e1d61 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc
@@ -49,7 +49,7 @@
 
 void CompositingLayerAssigner::Assign(
     PaintLayer* update_root,
-    HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) {
+    Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   TRACE_EVENT0("blink", "CompositingLayerAssigner::assign");
 
   SquashingState squashing_state;
@@ -66,7 +66,7 @@
 void CompositingLayerAssigner::SquashingState::
     UpdateSquashingStateForNewMapping(
         CompositedLayerMapping* new_composited_layer_mapping,
-        HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) {
+        Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   // The most recent backing is done accumulating any more squashing layers.
   if (most_recent_mapping) {
     most_recent_mapping->FinishAccumulatingSquashingLayers(
@@ -252,7 +252,7 @@
     PaintLayer* layer,
     SquashingState& squashing_state,
     const CompositingStateTransitionType composited_layer_update,
-    HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) {
+    Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   // NOTE: In the future as we generalize this, the background of this layer may
   // need to be assigned to a different backing than the squashed PaintLayer's
   // own primary contents. This would happen when we have a composited negative
@@ -306,7 +306,7 @@
     PaintLayer* layer,
     PaintLayer* paint_invalidation_container,
     SquashingState& squashing_state,
-    HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) {
+    Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   if (layer->NeedsCompositingLayerAssignment()) {
     if (RequiresSquashing(layer->GetCompositingReasons())) {
       SquashingDisallowedReasons reasons_preventing_squashing =
@@ -370,7 +370,7 @@
     paint_invalidation_container = layer;
 
   if (layer->StackingDescendantNeedsCompositingLayerAssignment()) {
-    PaintLayerPaintOrderIterator iterator(layer, kNegativeZOrderChildren);
+    PaintLayerPaintOrderIterator iterator(*layer, kNegativeZOrderChildren);
     while (PaintLayer* child_node = iterator.Next()) {
       AssignLayersToBackingsInternal(child_node, paint_invalidation_container,
                                      squashing_state,
@@ -388,7 +388,7 @@
   }
 
   if (layer->StackingDescendantNeedsCompositingLayerAssignment()) {
-    PaintLayerPaintOrderIterator iterator(layer,
+    PaintLayerPaintOrderIterator iterator(*layer,
                                           kNormalFlowAndPositiveZOrderChildren);
     while (PaintLayer* curr_layer = iterator.Next()) {
       AssignLayersToBackingsInternal(curr_layer, paint_invalidation_container,
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h b/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h
index 8134157..f94de7c 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h
@@ -44,9 +44,8 @@
  public:
   explicit CompositingLayerAssigner(PaintLayerCompositor*);
 
-  void Assign(
-      PaintLayer* update_root,
-      HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation);
+  void Assign(PaintLayer* update_root,
+              Vector<PaintLayer*>& layers_needing_paint_invalidation);
 
   bool LayersChanged() const { return layers_changed_; }
 
@@ -61,7 +60,7 @@
    public:
     void UpdateSquashingStateForNewMapping(
         CompositedLayerMapping*,
-        HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation);
+        Vector<PaintLayer*>& layers_needing_paint_invalidation);
 
     // The most recent composited backing that the layer should squash onto if
     // needed.
@@ -69,15 +68,15 @@
 
     // Whether all Layers in the stacking subtree rooted at the most recent
     // mapping's owning layer have had CompositedLayerMappings assigned. Layers
-    // cannot squash into a CompositedLayerMapping owned by a stacking
-    // ancestor, since this changes paint order.
+    // cannot squash into a CompositedLayerMapping owned by a stacking ancestor,
+    // since this changes paint order.
     bool have_assigned_backings_to_entire_squashing_layer_subtree = false;
 
     // This is set to true when most_recent_mapping supports composited
     // scrolling, and reset to false whenever any layer is not squashed into
-    // scrolling contents, to ensure all layers squashed into scrolling
-    // contents are continuous with the scroller in stacking order, without any
-    // other layer interlacing among them.
+    // scrolling contents, to ensure all layers squashed into scrolling contents
+    // are continuous with the scroller in stacking order, without any other
+    // layer interlacing among them.
     bool next_layer_may_squash_into_scrolling_contents = false;
 
     // Counter that tracks what index the next Layer would be if it gets
@@ -100,7 +99,7 @@
       PaintLayer* layer,
       PaintLayer* paint_invalidation_container,
       SquashingState&,
-      HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation);
+      Vector<PaintLayer*>& layers_needing_paint_invalidation);
   SquashingDisallowedReasons GetReasonsPreventingSquashing(
       const PaintLayer*,
       const SquashingState&);
@@ -110,7 +109,7 @@
       PaintLayer*,
       SquashingState&,
       CompositingStateTransitionType,
-      HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation);
+      Vector<PaintLayer*>& layers_needing_paint_invalidation);
   bool NeedsOwnBacking(const PaintLayer*) const;
 
   PaintLayerCompositor* compositor_;
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
index 791e9da8..054da346 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h"
 
+#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/core/css/css_property_names.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/node.h"
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
index 362aa72..67da1f6 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
@@ -177,7 +177,8 @@
 void CompositingReasonFinderTest::CheckCompositingReasonsForAnimation(
     bool supports_transform_animation) {
   auto* object = GetLayoutObjectByElementId("target");
-  ComputedStyle* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style =
+      GetDocument().GetStyleResolver().CreateComputedStyle();
 
   style->SetSubtreeWillChangeContents(false);
   style->SetHasCurrentTransformAnimation(false);
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
index bed93e4..6aaec88 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
@@ -231,7 +231,7 @@
   // of them dynamically, we are requiring a full tree walk. This
   // should be removed as soon as proper overlap testing based on
   // scrolling and animation bounds is implemented (crbug.com/252472).
-  HeapVector<Member<PaintLayer>> unclipped_descendants;
+  Vector<PaintLayer*> unclipped_descendants;
   IntRect absolute_descendant_bounding_box;
   UpdateRecursive(nullptr, root, overlap_test_request_map, recursion_data,
                   saw3d_transform, unclipped_descendants,
@@ -243,7 +243,7 @@
   if (layer->GetLayoutObject().ChildPrePaintBlockedByDisplayLock())
     return;
 
-  PaintLayerPaintOrderIterator iterator(layer, kAllChildren);
+  PaintLayerPaintOrderIterator iterator(*layer, kAllChildren);
   while (PaintLayer* cur_layer = iterator.Next()) {
     DCHECK(cur_layer->GetCompositingState() == kNotComposited);
     DCHECK(!cur_layer->DirectCompositingReasons() ||
@@ -259,7 +259,7 @@
     OverlapMap& overlap_map,
     RecursionData& current_recursion_data,
     bool& descendant_has3d_transform,
-    HeapVector<Member<PaintLayer>>& unclipped_descendants,
+    Vector<PaintLayer*>& unclipped_descendants,
     IntRect& absolute_descendant_bounding_box,
     CompositingReasonsStats& compositing_reasons_stats) {
   PaintLayerCompositor* compositor = layout_view_.Compositor();
@@ -402,7 +402,7 @@
   }
 
 #if DCHECK_IS_ON()
-  PaintLayerListMutationDetector mutation_checker(layer);
+  PaintLayerListMutationDetector mutation_checker(*layer);
 #endif
 
   bool any_descendant_has3d_transform = false;
@@ -437,7 +437,7 @@
       recursion_blocked_by_display_lock || skip_children_ignoring_display_lock;
 
   if (!skip_children) {
-    PaintLayerPaintOrderIterator iterator(layer, kNegativeZOrderChildren);
+    PaintLayerPaintOrderIterator iterator(*layer, kNegativeZOrderChildren);
     while (PaintLayer* child_layer = iterator.Next()) {
       IntRect absolute_child_descendant_bounding_box;
       UpdateRecursive(layer, child_layer, overlap_map, child_recursion_data,
@@ -487,7 +487,7 @@
   }
 
   if (!skip_children) {
-    PaintLayerPaintOrderIterator iterator(layer,
+    PaintLayerPaintOrderIterator iterator(*layer,
                                           kNormalFlowAndPositiveZOrderChildren);
     while (PaintLayer* child_layer = iterator.Next()) {
       IntRect absolute_child_descendant_bounding_box;
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
index cb966b6..6f1d051d 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
@@ -29,7 +29,6 @@
 
 #include "third_party/blink/renderer/platform/geometry/int_rect.h"
 #include "third_party/blink/renderer/platform/graphics/compositing_reasons.h"
-#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
@@ -66,7 +65,7 @@
                        OverlapMap&,
                        RecursionData&,
                        bool& descendant_has3d_transform,
-                       HeapVector<Member<PaintLayer>>& unclipped_descendants,
+                       Vector<PaintLayer*>& unclipped_descendants,
                        IntRect& absolute_descendant_bounding_box,
                        CompositingReasonsStats&);
 
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc b/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc
index 0f39cad..58d9221 100644
--- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc
@@ -82,7 +82,7 @@
                                    : &pending_reparents;
 
 #if DCHECK_IS_ON()
-  PaintLayerListMutationDetector mutation_checker(&layer);
+  PaintLayerListMutationDetector mutation_checker(layer);
 #endif
 
   bool recursion_blocked_by_display_lock =
@@ -99,7 +99,7 @@
 
   if (layer.IsStackingContextWithNegativeZOrderChildren()) {
     if (!recursion_blocked_by_display_lock) {
-      PaintLayerPaintOrderIterator iterator(&layer, kNegativeZOrderChildren);
+      PaintLayerPaintOrderIterator iterator(layer, kNegativeZOrderChildren);
       while (PaintLayer* child_layer = iterator.Next()) {
         RebuildRecursive(*child_layer, *layer_vector_for_children,
                          *pending_reparents_for_children);
@@ -116,7 +116,7 @@
   }
 
   if (!recursion_blocked_by_display_lock) {
-    PaintLayerPaintOrderIterator iterator(&layer,
+    PaintLayerPaintOrderIterator iterator(layer,
                                           kNormalFlowAndPositiveZOrderChildren);
     while (PaintLayer* child_layer = iterator.Next()) {
       RebuildRecursive(*child_layer, *layer_vector_for_children,
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h b/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h
index 27617ab..b1ef0a4 100644
--- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h
+++ b/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h
@@ -46,8 +46,7 @@
   // Maps from PaintLayer::ScrollParent to index into |child_layers| (see below
   // for child_layers parameter) at which to insert the overflow controls
   // graphics layers for ScrollParent when reparenting them.
-  using PendingOverflowControlReparents =
-      HeapHashMap<Member<const PaintLayer>, size_t>;
+  using PendingOverflowControlReparents = HashMap<const PaintLayer*, size_t>;
 
   void RebuildRecursive(PaintLayer&,
                         GraphicsLayerVector& child_layers,
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc
index 1c8485e..80be0f4 100644
--- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc
+++ b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc
@@ -108,7 +108,7 @@
 
 void GraphicsLayerUpdater::Update(
     PaintLayer& layer,
-    HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) {
+    Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   TRACE_EVENT0("blink", "GraphicsLayerUpdater::update");
   UpdateContext update_context;
   UpdateRecursive(layer, kDoNotForceUpdate, update_context,
@@ -119,7 +119,7 @@
     PaintLayer& layer,
     UpdateType update_type,
     UpdateContext& context,
-    HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation) {
+    Vector<PaintLayer*>& layers_needing_paint_invalidation) {
   if (layer.HasCompositedLayerMapping()) {
     CompositedLayerMapping* mapping = layer.GetCompositedLayerMapping();
 
diff --git a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h
index 69b2313..ec76693b 100644
--- a/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h
+++ b/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h
@@ -46,9 +46,8 @@
     kForceUpdate,
   };
 
-  void Update(
-      PaintLayer&,
-      HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation);
+  void Update(PaintLayer&,
+              Vector<PaintLayer*>& layers_needing_paint_invalidation);
 
   bool NeedsRebuildTree() const { return needs_rebuild_tree_; }
 
@@ -79,11 +78,10 @@
   };
 
  private:
-  void UpdateRecursive(
-      PaintLayer&,
-      UpdateType,
-      UpdateContext&,
-      HeapVector<Member<PaintLayer>>& layers_needing_paint_invalidation);
+  void UpdateRecursive(PaintLayer&,
+                       UpdateType,
+                       UpdateContext&,
+                       Vector<PaintLayer*>& layers_needing_paint_invalidation);
 
   bool needs_rebuild_tree_;
 };
diff --git a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
index a0775ad0..0bdfbd5 100644
--- a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
+++ b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
@@ -311,7 +311,7 @@
 
   PaintLayer* update_root = RootLayer();
 
-  HeapVector<Member<PaintLayer>> layers_needing_paint_invalidation;
+  Vector<PaintLayer*> layers_needing_paint_invalidation;
 
   if (update_type >= kCompositingUpdateAfterCompositingInputChange) {
     CompositingRequirementsUpdater(*layout_view_)
@@ -358,7 +358,7 @@
     }
   }
 
-  for (auto& layer : layers_needing_paint_invalidation) {
+  for (auto* layer : layers_needing_paint_invalidation) {
     PaintInvalidationOnCompositingChange(layer);
   }
 }
@@ -556,9 +556,4 @@
   return layout_view_->GetFrame()->IsMainFrame();
 }
 
-void PaintLayerCompositor::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_view_);
-  visitor->Trace(compositing_inputs_root_);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
index aa47baf..32c7597 100644
--- a/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
+++ b/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
@@ -33,7 +33,6 @@
 #include "third_party/blink/renderer/core/paint/compositing/compositing_inputs_root.h"
 #include "third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h"
 #include "third_party/blink/renderer/core/paint/compositing/compositing_update_type.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 
 namespace blink {
 
@@ -63,8 +62,9 @@
 // With CompositeAfterPaint, PaintLayerCompositor will be eventually replaced by
 // PaintArtifactCompositor.
 
-class CORE_EXPORT PaintLayerCompositor final
-    : public GarbageCollected<PaintLayerCompositor> {
+class CORE_EXPORT PaintLayerCompositor {
+  USING_FAST_MALLOC(PaintLayerCompositor);
+
  public:
   explicit PaintLayerCompositor(LayoutView&);
   ~PaintLayerCompositor();
@@ -145,8 +145,6 @@
     compositing_inputs_root_.Update(layer);
   }
 
-  void Trace(Visitor*) const;
-
  private:
 #if DCHECK_IS_ON()
   void AssertNoUnresolvedDirtyBits();
@@ -172,7 +170,7 @@
 
   bool IsMainFrame() const;
 
-  Member<LayoutView> layout_view_;
+  LayoutView* const layout_view_;
 
   bool compositing_ = false;
   bool root_layer_attachment_dirty_ = false;
diff --git a/third_party/blink/renderer/core/paint/cull_rect_updater.cc b/third_party/blink/renderer/core/paint/cull_rect_updater.cc
index b439a25f..9dd41b2 100644
--- a/third_party/blink/renderer/core/paint/cull_rect_updater.cc
+++ b/third_party/blink/renderer/core/paint/cull_rect_updater.cc
@@ -160,7 +160,7 @@
 
   // Then stacked children (which may not be direct children in PaintLayer
   // hierarchy) in paint order.
-  PaintLayerPaintOrderIterator iterator(&layer, kStackedChildren);
+  PaintLayerPaintOrderIterator iterator(layer, kStackedChildren);
   while (PaintLayer* child = iterator.Next())
     UpdateRecursively(*child, layer, force_update_children);
 }
diff --git a/third_party/blink/renderer/core/paint/fragment_data.cc b/third_party/blink/renderer/core/paint/fragment_data.cc
index a90c485..e4ecbb65 100644
--- a/third_party/blink/renderer/core/paint/fragment_data.cc
+++ b/third_party/blink/renderer/core/paint/fragment_data.cc
@@ -14,30 +14,22 @@
 
 FragmentData::RareData::~RareData() = default;
 
-void FragmentData::RareData::SetLayer(PaintLayer* new_layer) {
-  if (layer && layer != new_layer)
-    layer->Destroy();
-  layer = new_layer;
-}
-
-void FragmentData::RareData::Trace(Visitor* visitor) const {
-  visitor->Trace(layer);
-  visitor->Trace(next_fragment_);
-}
-
-void FragmentData::ClearNextFragment() {
+void FragmentData::DestroyTail() {
   if (!rare_data_)
     return;
   // Take next_fragment_ which clears it in this fragment.
-  FragmentData* next = rare_data_->next_fragment_.Release();
+  std::unique_ptr<FragmentData> next = std::move(rare_data_->next_fragment_);
   while (next && next->rare_data_) {
-    next = next->rare_data_->next_fragment_.Release();
+    // Take next_fragment_ which clears it in that fragment, and the assignment
+    // deletes the previous |next|.
+    next = std::move(next->rare_data_->next_fragment_);
   }
+  // The last |next| will be deleted on return.
 }
 
 FragmentData& FragmentData::EnsureNextFragment() {
   if (!NextFragment())
-    EnsureRareData().next_fragment_ = MakeGarbageCollected<FragmentData>();
+    EnsureRareData().next_fragment_ = std::make_unique<FragmentData>();
   return *rare_data_->next_fragment_;
 }
 
@@ -56,13 +48,13 @@
 
 FragmentData::RareData& FragmentData::EnsureRareData() {
   if (!rare_data_)
-    rare_data_ = MakeGarbageCollected<RareData>();
+    rare_data_ = std::make_unique<RareData>();
   return *rare_data_;
 }
 
-void FragmentData::SetLayer(PaintLayer* layer) {
+void FragmentData::SetLayer(std::unique_ptr<PaintLayer> layer) {
   if (rare_data_ || layer)
-    EnsureRareData().SetLayer(layer);
+    EnsureRareData().layer = std::move(layer);
 }
 
 const TransformPaintPropertyNodeOrAlias& FragmentData::PreTransform() const {
diff --git a/third_party/blink/renderer/core/paint/fragment_data.h b/third_party/blink/renderer/core/paint/fragment_data.h
index 8d59fd1..0396afe 100644
--- a/third_party/blink/renderer/core/paint/fragment_data.h
+++ b/third_party/blink/renderer/core/paint/fragment_data.h
@@ -10,7 +10,6 @@
 #include "third_party/blink/renderer/core/paint/object_paint_properties.h"
 #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
 #include "third_party/blink/renderer/platform/graphics/paint/ref_counted_property_tree_state.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 namespace blink {
@@ -19,18 +18,15 @@
 
 // Represents the data for a particular fragment of a LayoutObject.
 // See README.md.
-class CORE_EXPORT FragmentData final : public GarbageCollected<FragmentData> {
+class CORE_EXPORT FragmentData {
+  USING_FAST_MALLOC(FragmentData);
+
  public:
   FragmentData* NextFragment() const {
-    return rare_data_ ? rare_data_->next_fragment_ : nullptr;
+    return rare_data_ ? rare_data_->next_fragment_.get() : nullptr;
   }
   FragmentData& EnsureNextFragment();
-
-  // We could let the compiler generate code to automatically clear the
-  // next_fragment_ chain, but the code would cause stack overflow in some
-  // cases (e.g. fast/multicol/infinitely-tall-content-in-outer-crash.html).
-  // This function crear the next_fragment_ chain non-recursively.
-  void ClearNextFragment();
+  void ClearNextFragment() { DestroyTail(); }
 
   FragmentData& LastFragment();
   const FragmentData& LastFragment() const;
@@ -51,8 +47,10 @@
 
   // The PaintLayer associated with this LayoutBoxModelObject. This can be null
   // depending on the return value of LayoutBoxModelObject::LayerTypeRequired().
-  PaintLayer* Layer() const { return rare_data_ ? rare_data_->layer : nullptr; }
-  void SetLayer(PaintLayer*);
+  PaintLayer* Layer() const {
+    return rare_data_ ? rare_data_->layer.get() : nullptr;
+  }
+  void SetLayer(std::unique_ptr<PaintLayer>);
 
   LayoutUnit LogicalTopInFlowThread() const {
     return rare_data_ ? rare_data_->logical_top_in_flow_thread : LayoutUnit();
@@ -196,27 +194,33 @@
   // border box space. Both fragments must have local border box properties.
   void MapRectToFragment(const FragmentData& fragment, IntRect&) const;
 
-  ~FragmentData() = default;
-  void Trace(Visitor* visitor) const { visitor->Trace(rare_data_); }
+  ~FragmentData() {
+    if (NextFragment())
+      DestroyTail();
+  }
 
  private:
   friend class FragmentDataTest;
 
+  // We could let the compiler generate code to automatically destroy the
+  // next_fragment_ chain, but the code would cause stack overflow in some
+  // cases (e.g. fast/multicol/infinitely-tall-content-in-outer-crash.html).
+  // This function destroy the next_fragment_ chain non-recursively.
+  void DestroyTail();
+
   // Contains rare data that that is not needed on all fragments.
-  struct CORE_EXPORT RareData final : public GarbageCollected<RareData> {
+  struct CORE_EXPORT RareData {
+    USING_FAST_MALLOC(RareData);
+
    public:
     RareData();
     RareData(const RareData&) = delete;
     RareData& operator=(const RareData&) = delete;
     ~RareData();
 
-    void SetLayer(PaintLayer*);
-
-    void Trace(Visitor* visitor) const;
-
     // The following data fields are not fragment specific. Placed here just to
     // avoid separate data structure for them.
-    Member<PaintLayer> layer;
+    std::unique_ptr<PaintLayer> layer;
     UniqueObjectId unique_id;
 
     // Fragment specific data.
@@ -229,13 +233,13 @@
     scoped_refptr<const RefCountedPath> clip_path_path;
     CullRect cull_rect_;
     CullRect contents_cull_rect_;
-    Member<FragmentData> next_fragment_;
+    std::unique_ptr<FragmentData> next_fragment_;
   };
 
   RareData& EnsureRareData();
 
   PhysicalOffset paint_offset_;
-  Member<RareData> rare_data_;
+  std::unique_ptr<RareData> rare_data_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/highlight_painting_utils.cc b/third_party/blink/renderer/core/paint/highlight_painting_utils.cc
index 3d49b74..76e28cc 100644
--- a/third_party/blink/renderer/core/paint/highlight_painting_utils.cc
+++ b/third_party/blink/renderer/core/paint/highlight_painting_utils.cc
@@ -120,7 +120,8 @@
   }
 }
 
-const ComputedStyle* HighlightPseudoStyle(Node* node, PseudoId pseudo) {
+scoped_refptr<const ComputedStyle> HighlightPseudoStyle(Node* node,
+                                                        PseudoId pseudo) {
   if (!node)
     return nullptr;
 
@@ -175,7 +176,8 @@
     }
   }
 
-  const ComputedStyle* pseudo_style = HighlightPseudoStyle(node, pseudo);
+  scoped_refptr<const ComputedStyle> pseudo_style =
+      HighlightPseudoStyle(node, pseudo);
 
   mojom::blink::ColorScheme color_scheme = style.UsedColorScheme();
   if (pseudo_style) {
@@ -204,7 +206,8 @@
   }
 
   mojom::blink::ColorScheme color_scheme = style.UsedColorScheme();
-  if (const ComputedStyle* pseudo_style = HighlightPseudoStyle(node, pseudo)) {
+  if (scoped_refptr<const ComputedStyle> pseudo_style =
+          HighlightPseudoStyle(node, pseudo)) {
     if (!document.InForcedColorsMode() ||
         pseudo_style->ForcedColorAdjust() == EForcedColorAdjust::kNone) {
       Color highlight_color =
@@ -295,7 +298,8 @@
         document, style, node, pseudo, global_paint_flags);
   }
 
-  if (const ComputedStyle* pseudo_style = HighlightPseudoStyle(node, pseudo)) {
+  if (scoped_refptr<const ComputedStyle> pseudo_style =
+          HighlightPseudoStyle(node, pseudo)) {
     highlight_style.stroke_color =
         uses_text_as_clip ? Color::kBlack
                           : pseudo_style->VisitedDependentColor(
diff --git a/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc b/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc
index f74932f1..e44355f 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_table_painters.cc
@@ -643,7 +643,7 @@
     if (!child.fragment->IsTableNGCell())
       continue;
     wtf_size_t cell_column =
-        To<NGPhysicalBoxFragment>(child.fragment.Get())->TableCellColumnIndex();
+        To<NGPhysicalBoxFragment>(child.fragment)->TableCellColumnIndex();
     // if cell is in the column, generate column physical rect
     for (current_column = smallest_viable_column;
          current_column < column_geometries.size(); ++current_column) {
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.cc b/third_party/blink/renderer/core/paint/paint_invalidator.cc
index d1015ce..fb7a8e775 100644
--- a/third_party/blink/renderer/core/paint/paint_invalidator.cc
+++ b/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -395,7 +395,7 @@
 }
 
 void PaintInvalidator::ProcessPendingDelayedPaintInvalidations() {
-  for (const auto& target : pending_delayed_paint_invalidations_)
+  for (auto* target : pending_delayed_paint_invalidations_)
     target->GetMutableForPainting().SetShouldDelayFullPaintInvalidation();
 }
 
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.h b/third_party/blink/renderer/core/paint/paint_invalidator.h
index 80342b0..a3e6438 100644
--- a/third_party/blink/renderer/core/paint/paint_invalidator.h
+++ b/third_party/blink/renderer/core/paint/paint_invalidator.h
@@ -118,7 +118,7 @@
       const PaintPropertyTreeBuilderFragmentContext&,
       PaintInvalidatorContext&);
 
-  HeapVector<Member<const LayoutObject>> pending_delayed_paint_invalidations_;
+  Vector<const LayoutObject*> pending_delayed_paint_invalidations_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc
index 96115d8..41cbf36 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -111,19 +111,19 @@
     kCompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases;
 
 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
-struct SameSizeAsPaintLayer : GarbageCollected<PaintLayer>, DisplayItemClient {
+struct SameSizeAsPaintLayer : DisplayItemClient {
   // The bit fields may fit into the machine word of DisplayItemClient which
   // has only 8-bit data.
   unsigned bit_fields1 : 24;
-  unsigned bit_fields2 : 24;
+  unsigned bit_fields2;
+  void* pointers[10];
 #if DCHECK_IS_ON()
-  bool is_destroyed;
+  void* pointer;
 #endif
-  Member<void*> members1[6];
   LayoutUnit layout_units[4];
   IntSize size;
+  Persistent<PaintLayerScrollableArea> scrollable_area;
   CullRect previous_cull_rect;
-  Member<void*> members2[5];
 };
 
 ASSERT_SIZE(PaintLayer, SameSizeAsPaintLayer);
@@ -171,12 +171,7 @@
 
 PaintLayerRareData::~PaintLayerRareData() = default;
 
-void PaintLayerRareData::Trace(Visitor* visitor) const {
-  visitor->Trace(enclosing_pagination_layer);
-  visitor->Trace(resource_info);
-}
-
-PaintLayer::PaintLayer(LayoutBoxModelObject* layout_object)
+PaintLayer::PaintLayer(LayoutBoxModelObject& layout_object)
     : is_root_layer_(IsA<LayoutView>(layout_object)),
       has_visible_content_(false),
       needs_descendant_dependent_flags_update_(true),
@@ -227,7 +222,7 @@
 #if DCHECK_IS_ON()
       layer_list_mutation_allowed_(true),
 #endif
-      layout_object_(layout_object),
+      layout_object_(&layout_object),
       parent_(nullptr),
       previous_(nullptr),
       next_(nullptr),
@@ -235,22 +230,18 @@
       last_(nullptr),
       static_inline_position_(0),
       static_block_position_(0),
-      ancestor_scroll_container_layer_(nullptr) {
+      ancestor_scroll_container_layer_(nullptr)
+#if DCHECK_IS_ON()
+      ,
+      stacking_parent_(nullptr)
+#endif
+{
   is_self_painting_layer_ = ShouldBeSelfPaintingLayer();
 
   UpdateScrollableArea();
 }
 
 PaintLayer::~PaintLayer() {
-#if DCHECK_IS_ON()
-  DCHECK(is_destroyed_);
-#endif
-}
-
-void PaintLayer::Destroy() {
-#if DCHECK_IS_ON()
-  DCHECK(!is_destroyed_);
-#endif
   if (rare_data_ && rare_data_->resource_info) {
     const ComputedStyle& style = GetLayoutObject().StyleRef();
     if (style.HasFilter())
@@ -281,7 +272,10 @@
     scrollable_area_->Dispose();
 
 #if DCHECK_IS_ON()
-  is_destroyed_ = true;
+  // stacking_parent_ should be cleared because DirtyStackingContextZOrderLists
+  // should have been called.
+  if (!GetLayoutObject().DocumentBeingDestroyed())
+    DCHECK(!stacking_parent_);
 #endif
 }
 
@@ -832,7 +826,7 @@
 
   // Transformed or preserve-3d descendants can only be in the z-order lists,
   // not in the normal flow list, so we only need to check those.
-  PaintLayerPaintOrderIterator iterator(this, kStackedChildren);
+  PaintLayerPaintOrderIterator iterator(*this, kStackedChildren);
   while (PaintLayer* child_layer = iterator.Next()) {
     bool child_has3d = false;
     // If the child lives in a 3d hierarchy, then the layer at the root of
@@ -1257,7 +1251,7 @@
   DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
   if (!ancestor_dependent_compositing_inputs_) {
     ancestor_dependent_compositing_inputs_ =
-        MakeGarbageCollected<AncestorDependentCompositingInputs>();
+        std::make_unique<AncestorDependentCompositingInputs>();
   }
   ancestor_dependent_compositing_inputs_->opacity_ancestor = opacity_ancestor;
   ancestor_dependent_compositing_inputs_->transform_ancestor =
@@ -1352,6 +1346,15 @@
   return false;
 }
 
+void* PaintLayer::operator new(size_t sz) {
+  return WTF::Partitions::LayoutPartition()->Alloc(
+      sz, WTF_HEAP_PROFILER_TYPE_NAME(PaintLayer));
+}
+
+void PaintLayer::operator delete(void* ptr) {
+  WTF::Partitions::LayoutPartition()->Free(ptr);
+}
+
 void PaintLayer::AddChild(PaintLayer* child, PaintLayer* before_child) {
 #if DCHECK_IS_ON()
   DCHECK(layer_list_mutation_allowed_);
@@ -1652,11 +1655,10 @@
       GetLayoutObject().IsStackingContext();
 
   if (needs_stacking_node != !!stacking_node_) {
-    if (needs_stacking_node) {
-      stacking_node_ = MakeGarbageCollected<PaintLayerStackingNode>(this);
-    } else {
-      stacking_node_.Clear();
-    }
+    if (needs_stacking_node)
+      stacking_node_ = std::make_unique<PaintLayerStackingNode>(*this);
+    else
+      stacking_node_.reset();
   }
 
   if (stacking_node_)
@@ -2229,7 +2231,7 @@
   // See if the hit test pos is inside the resizer of the child layers which
   // has reordered the painting of the overlay overflow controls.
   if (stacking_node_) {
-    for (auto& layer : base::Reversed(
+    for (auto* layer : base::Reversed(
              stacking_node_->OverlayOverflowControlsReorderedList())) {
       if (layer->HitTestLayer(
               root_layer, nullptr, result, recursion_data,
@@ -2569,7 +2571,7 @@
   PaintLayer* stop_layer = stop_node ? stop_node->PaintingLayer() : nullptr;
 
   PaintLayer* result_layer = nullptr;
-  PaintLayerPaintOrderReverseIterator iterator(this, children_to_visit);
+  PaintLayerPaintOrderReverseIterator iterator(*this, children_to_visit);
   while (PaintLayer* child_layer = iterator.Next()) {
     if (child_layer->IsReplacedNormalFlowStacking())
       continue;
@@ -2823,7 +2825,7 @@
       // |layer|'s bounds.
       PhysicalRect children_bounds;
       if (!GetLayoutObject().ChildPaintBlockedByDisplayLock()) {
-        PaintLayerPaintOrderIterator iterator(this, kAllChildren);
+        PaintLayerPaintOrderIterator iterator(*this, kAllChildren);
         while (PaintLayer* child_layer = iterator.Next()) {
           // Note that we intentionally include children irrespective of if they
           // are composited or not.
@@ -2884,7 +2886,7 @@
     }
   }
 
-  PaintLayerPaintOrderIterator iterator(this, kAllChildren);
+  PaintLayerPaintOrderIterator iterator(*this, kAllChildren);
   while (PaintLayer* child_layer = iterator.Next()) {
     // Here we exclude both directly composited layers and squashing layers
     // because those Layers don't paint into the graphics layer
@@ -3199,7 +3201,7 @@
 
 bool PaintLayer::ChildBackgroundIsKnownToBeOpaqueInRect(
     const PhysicalRect& local_rect) const {
-  PaintLayerPaintOrderReverseIterator reverse_iterator(this, kAllChildren);
+  PaintLayerPaintOrderReverseIterator reverse_iterator(*this, kAllChildren);
   while (PaintLayer* child_layer = reverse_iterator.Next()) {
     // Stop at composited paint boundaries and non-self-painting layers.
     if (child_layer->IsPaintInvalidationContainer())
@@ -3519,8 +3521,8 @@
 
 PaintLayerClipper PaintLayer::Clipper(
     GeometryMapperOption geometry_mapper_option) const {
-  return PaintLayerClipper(
-      this, geometry_mapper_option == GeometryMapperOption::kUseGeometryMapper);
+  return PaintLayerClipper(*this, geometry_mapper_option ==
+                                      GeometryMapperOption::kUseGeometryMapper);
 }
 
 bool PaintLayer::ScrollsOverflow() const {
@@ -3864,35 +3866,6 @@
   DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
 }
 
-void PaintLayer::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_object_);
-  visitor->Trace(parent_);
-  visitor->Trace(previous_);
-  visitor->Trace(next_);
-  visitor->Trace(first_);
-  visitor->Trace(last_);
-  visitor->Trace(ancestor_scroll_container_layer_);
-  visitor->Trace(ancestor_dependent_compositing_inputs_);
-  visitor->Trace(scrollable_area_);
-  visitor->Trace(stacking_node_);
-  visitor->Trace(rare_data_);
-}
-
-void PaintLayer::AncestorDependentCompositingInputs::Trace(
-    Visitor* visitor) const {
-  visitor->Trace(opacity_ancestor);
-  visitor->Trace(transform_ancestor);
-  visitor->Trace(filter_ancestor);
-  visitor->Trace(clip_path_ancestor);
-  visitor->Trace(mask_ancestor);
-  visitor->Trace(ancestor_scrolling_layer);
-  visitor->Trace(nearest_fixed_position_layer);
-  visitor->Trace(scroll_parent);
-  visitor->Trace(clip_parent);
-  visitor->Trace(nearest_contained_layout_layer);
-  visitor->Trace(clipping_container);
-}
-
 }  // namespace blink
 
 #if DCHECK_IS_ON()
diff --git a/third_party/blink/renderer/core/paint/paint_layer.h b/third_party/blink/renderer/core/paint/paint_layer.h
index a7c75343..9ec703a 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.h
+++ b/third_party/blink/renderer/core/paint/paint_layer.h
@@ -119,16 +119,15 @@
   base::AutoReset<CompositingQueryMode> disabler_;
 };
 
-struct CORE_EXPORT PaintLayerRareData final
-    : public GarbageCollected<PaintLayerRareData> {
+struct PaintLayerRareData {
+  USING_FAST_MALLOC(PaintLayerRareData);
+
  public:
   PaintLayerRareData();
   PaintLayerRareData(const PaintLayerRareData&) = delete;
   PaintLayerRareData& operator=(const PaintLayerRareData&) = delete;
   ~PaintLayerRareData();
 
-  void Trace(Visitor* visitor) const;
-
   // The offset for an in-flow relative-positioned PaintLayer. This is not
   // set by any other style.
   PhysicalOffset offset_for_in_flow_rel_position;
@@ -145,7 +144,7 @@
   // coordinates when working with multicol in Layer, since Layer is one of the
   // few places where we have to worry about the visual ones. Internally we try
   // to use flow-thread coordinates whenever possible.
-  Member<PaintLayer> enclosing_pagination_layer;
+  PaintLayer* enclosing_pagination_layer;
 
   // These compositing reasons are updated whenever style changes, not while
   // updating compositing layers.  They should not be used to infer the
@@ -172,7 +171,7 @@
   // composited or paints into its own backing.
   CompositedLayerMapping* grouped_mapping;
 
-  Member<PaintLayerResourceInfo> resource_info;
+  Persistent<PaintLayerResourceInfo> resource_info;
 
   // The accumulated subpixel offset of a composited layer's composited bounds
   // compared to absolute coordinates.
@@ -246,23 +245,20 @@
 // A good example of this is PaintLayerScrollableArea, which can only happen
 // be instanciated for LayoutBoxes. With the current design, it's hard to know
 // that by reading the code.
-class CORE_EXPORT PaintLayer : public GarbageCollected<PaintLayer>,
-                               public DisplayItemClient {
+class CORE_EXPORT PaintLayer : public DisplayItemClient {
  public:
-  explicit PaintLayer(LayoutBoxModelObject*);
+  PaintLayer(LayoutBoxModelObject&);
   PaintLayer(const PaintLayer&) = delete;
   PaintLayer& operator=(const PaintLayer&) = delete;
   ~PaintLayer() override;
 
-  void Destroy();
-
   // DisplayItemClient methods
   String DebugName() const final;
   DOMNodeId OwnerNodeId() const final;
 
   LayoutBoxModelObject& GetLayoutObject() const { return *layout_object_; }
   LayoutBox* GetLayoutBox() const {
-    return DynamicTo<LayoutBox>(layout_object_.Get());
+    return DynamicTo<LayoutBox>(layout_object_);
   }
   PaintLayer* Parent() const { return parent_; }
   PaintLayer* PreviousSibling() const { return previous_; }
@@ -327,7 +323,7 @@
   // blocks writing mode.
   IntSize PixelSnappedSize() const {
     LayoutPoint location = layout_object_->IsBox()
-                               ? To<LayoutBox>(layout_object_.Get())->Location()
+                               ? To<LayoutBox>(layout_object_)->Location()
                                : LayoutPoint();
     return PixelSnappedIntSize(Size(), location);
   }
@@ -561,6 +557,10 @@
     return GetLayoutObject().HasFilterInducingProperty();
   }
 
+  void* operator new(size_t);
+  // Only safe to call from LayoutBoxModelObject::destroyLayer()
+  void operator delete(void*);
+
   CompositingState GetCompositingState() const;
 
   // This returns true if our document is in a phase of its lifestyle during
@@ -772,23 +772,18 @@
            CompositingReason::kComboAllDirectStyleDeterminedReasons;
   }
 
-  class CORE_EXPORT AncestorDependentCompositingInputs final
-      : public GarbageCollected<AncestorDependentCompositingInputs> {
-   public:
-    AncestorDependentCompositingInputs() = default;
-    void Trace(Visitor*) const;
-
-    Member<const PaintLayer> opacity_ancestor = nullptr;
-    Member<const PaintLayer> transform_ancestor = nullptr;
-    Member<const PaintLayer> filter_ancestor = nullptr;
-    Member<const PaintLayer> clip_path_ancestor = nullptr;
-    Member<const PaintLayer> mask_ancestor = nullptr;
+  struct AncestorDependentCompositingInputs {
+    const PaintLayer* opacity_ancestor = nullptr;
+    const PaintLayer* transform_ancestor = nullptr;
+    const PaintLayer* filter_ancestor = nullptr;
+    const PaintLayer* clip_path_ancestor = nullptr;
+    const PaintLayer* mask_ancestor = nullptr;
 
     // The first ancestor which can scroll. This is a subset of the
     // ancestorOverflowLayer chain where the scrolling layer is visible and
     // has a larger scroll content than its bounds.
-    Member<const PaintLayer> ancestor_scrolling_layer = nullptr;
-    Member<const PaintLayer> nearest_fixed_position_layer = nullptr;
+    const PaintLayer* ancestor_scrolling_layer = nullptr;
+    const PaintLayer* nearest_fixed_position_layer = nullptr;
 
     // A scroll parent is a compositor concept. It's only needed in blink
     // because we need to use it as a promotion trigger. A layer has a
@@ -796,21 +791,21 @@
     // other layer scrolled by this ancestor, is a stacking ancestor of this
     // layer. Layers with scroll parents must be scrolled with the main
     // scrolling layer by the compositor.
-    Member<const PaintLayer> scroll_parent = nullptr;
+    const PaintLayer* scroll_parent = nullptr;
 
     // A clip parent is another compositor concept that has leaked into
     // blink so that it may be used as a promotion trigger. Layers with clip
     // parents escape the clip of a stacking tree ancestor. The compositor
     // needs to know about clip parents in order to circumvent its normal
     // clipping logic.
-    Member<const PaintLayer> clip_parent = nullptr;
+    const PaintLayer* clip_parent = nullptr;
 
     // Nearest layer that has layout containment applied to its LayoutObject.
     // Squashing is disallowed across contain layout boundaries to provide
     // better isolation.
-    Member<const PaintLayer> nearest_contained_layout_layer = nullptr;
+    const PaintLayer* nearest_contained_layout_layer = nullptr;
 
-    Member<const LayoutBoxModelObject> clipping_container;
+    const LayoutBoxModelObject* clipping_container;
   };
 
   bool NeedsVisualOverflowRecalc() const {
@@ -1131,6 +1126,10 @@
   }
 
 #if DCHECK_IS_ON()
+  void SetStackingParent(PaintLayerStackingNode* stacking_parent) {
+    stacking_parent_ = stacking_parent;
+  }
+  PaintLayerStackingNode* StackingParent() { return stacking_parent_; }
   bool IsInStackingParentZOrderLists() const;
   bool LayerListMutationAllowed() const { return layer_list_mutation_allowed_; }
 #endif
@@ -1163,8 +1162,6 @@
     needs_paint_offset_translation_for_compositing_ = b;
   }
 
-  void Trace(Visitor*) const;
-
  private:
   PhysicalRect LocalBoundingBoxForCompositingOverlapTest() const;
   bool PaintsWithDirectReasonIntoOwnBacking(GlobalPaintFlags) const;
@@ -1294,7 +1291,7 @@
 
   PaintLayerRareData& EnsureRareData() {
     if (!rare_data_)
-      rare_data_ = MakeGarbageCollected<PaintLayerRareData>();
+      rare_data_ = std::make_unique<PaintLayerRareData>();
     return *rare_data_;
   }
 
@@ -1323,14 +1320,14 @@
       const {
     if (!ancestor_dependent_compositing_inputs_) {
       ancestor_dependent_compositing_inputs_ =
-          MakeGarbageCollected<AncestorDependentCompositingInputs>();
+          std::make_unique<AncestorDependentCompositingInputs>();
     }
     return *ancestor_dependent_compositing_inputs_;
   }
 
   // This is private because PaintLayerStackingNode is only for PaintLayer and
   // PaintLayerPaintOrderIterator.
-  PaintLayerStackingNode* StackingNode() const { return stacking_node_; }
+  PaintLayerStackingNode* StackingNode() const { return stacking_node_.get(); }
 
   void SetNeedsReorderOverlayOverflowControls(bool b) {
     needs_reorder_overlay_overflow_controls_ = b;
@@ -1430,16 +1427,15 @@
 
 #if DCHECK_IS_ON()
   mutable unsigned layer_list_mutation_allowed_ : 1;
-  bool is_destroyed_ = false;
 #endif
 
-  const Member<LayoutBoxModelObject> layout_object_;
+  LayoutBoxModelObject* const layout_object_;
 
-  Member<PaintLayer> parent_;
-  Member<PaintLayer> previous_;
-  Member<PaintLayer> next_;
-  Member<PaintLayer> first_;
-  Member<PaintLayer> last_;
+  PaintLayer* parent_;
+  PaintLayer* previous_;
+  PaintLayer* next_;
+  PaintLayer* first_;
+  PaintLayer* last_;
 
   // Our (x,y) coordinates are in our containing layer's coordinate space,
   // excluding positioning offset and scroll.
@@ -1456,22 +1452,26 @@
   LayoutUnit static_inline_position_;
   LayoutUnit static_block_position_;
 
-  CullRect previous_cull_rect_;
-
   // The first ancestor that is a scroll container. This is not a member of
   // AncestorDependentCompositingInputs as it is needed when
   // |needs_descendant_dependent_flags_update_| is true. In other words, it is
   // accessed and used out of band with normal compositing inputs updating.
-  Member<const PaintLayer> ancestor_scroll_container_layer_;
+  const PaintLayer* ancestor_scroll_container_layer_;
 
-  mutable Member<AncestorDependentCompositingInputs>
+  mutable std::unique_ptr<AncestorDependentCompositingInputs>
       ancestor_dependent_compositing_inputs_;
 
-  Member<PaintLayerScrollableArea> scrollable_area_;
+  Persistent<PaintLayerScrollableArea> scrollable_area_;
 
-  Member<PaintLayerStackingNode> stacking_node_;
+  std::unique_ptr<PaintLayerStackingNode> stacking_node_;
 
-  Member<PaintLayerRareData> rare_data_;
+  CullRect previous_cull_rect_;
+
+  std::unique_ptr<PaintLayerRareData> rare_data_;
+
+#if DCHECK_IS_ON()
+  PaintLayerStackingNode* stacking_parent_;
+#endif
 
   // For layer_list_mutation_allowed_.
   friend class PaintLayerListMutationDetector;
@@ -1511,18 +1511,18 @@
   STACK_ALLOCATED();
 
  public:
-  explicit PaintLayerListMutationDetector(const PaintLayer* layer)
+  explicit PaintLayerListMutationDetector(const PaintLayer& layer)
       : layer_(layer),
-        previous_mutation_allowed_state_(layer->layer_list_mutation_allowed_) {
-    layer->layer_list_mutation_allowed_ = false;
+        previous_mutation_allowed_state_(layer.layer_list_mutation_allowed_) {
+    layer.layer_list_mutation_allowed_ = false;
   }
 
   ~PaintLayerListMutationDetector() {
-    layer_->layer_list_mutation_allowed_ = previous_mutation_allowed_state_;
+    layer_.layer_list_mutation_allowed_ = previous_mutation_allowed_state_;
   }
 
  private:
-  const PaintLayer* layer_;
+  const PaintLayer& layer_;
   bool previous_mutation_allowed_state_;
 };
 #endif
diff --git a/third_party/blink/renderer/core/paint/paint_layer_clipper.cc b/third_party/blink/renderer/core/paint/paint_layer_clipper.cc
index 1e01913..85d08c8 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_clipper.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_clipper.cc
@@ -121,7 +121,7 @@
   }
 }
 
-PaintLayerClipper::PaintLayerClipper(const PaintLayer* layer,
+PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer,
                                      bool usegeometry_mapper)
     : layer_(layer), use_geometry_mapper_(usegeometry_mapper) {}
 
@@ -134,7 +134,7 @@
 
   ClipRect clip_rect;
   CalculateBackgroundClipRectWithGeometryMapper(
-      context, layer_->GetLayoutObject().FirstFragment(), kRespectOverflowClip,
+      context, layer_.GetLayoutObject().FirstFragment(), kRespectOverflowClip,
       clip_rect);
 
   if (clip_rect.IsInfinite())
@@ -148,7 +148,7 @@
 
   const auto& clip_root_layer_transform =
       context.root_fragment->LocalBorderBoxProperties().Transform();
-  const auto& layer_transform = layer_->GetLayoutObject()
+  const auto& layer_transform = layer_.GetLayoutObject()
                                     .FirstFragment()
                                     .LocalBorderBoxProperties()
                                     .Transform();
@@ -157,7 +157,7 @@
       clip_root_layer_transform, layer_transform, clipped_rect_in_local_space);
   // TODO(chrishtr): not correct for fragmentation.
   clipped_rect_in_local_space.MoveBy(
-      -FloatPoint(layer_->GetLayoutObject().FirstFragment().PaintOffset()));
+      -FloatPoint(layer_.GetLayoutObject().FirstFragment().PaintOffset()));
 
   return PhysicalRect::FastAndLossyFromFloatRect(clipped_rect_in_local_space);
 }
@@ -170,12 +170,12 @@
     ClipRect& background_rect,
     ClipRect& foreground_rect,
     const PhysicalOffset* offset_from_root) const {
-  layer_bounds.size = PhysicalSize(layer_->PixelSnappedSize());
+  layer_bounds.size = PhysicalSize(layer_.PixelSnappedSize());
   if (offset_from_root) {
     layer_bounds.offset = *offset_from_root;
   } else {
     layer_bounds.offset = context.sub_pixel_accumulation;
-    if (layer_ == context.root_layer) {
+    if (&layer_ == context.root_layer) {
       DCHECK_EQ(&fragment_data, context.root_fragment);
     } else {
       layer_bounds.Move(fragment_data.PaintOffset());
@@ -197,7 +197,7 @@
     background_rect.Intersect(PhysicalRect(cull_rect->Rect()));
 
   if (ShouldClipOverflowAlongEitherAxis(context)) {
-    LayoutBoxModelObject& layout_object = layer_->GetLayoutObject();
+    LayoutBoxModelObject& layout_object = layer_.GetLayoutObject();
     foreground_rect =
         To<LayoutBox>(layout_object)
             .OverflowClipRect(layer_bounds.offset,
@@ -231,10 +231,10 @@
   }
   DCHECK(!fragment_data);
 
-  bool is_clipping_root = layer_ == context.root_layer;
-  LayoutBoxModelObject& layout_object = layer_->GetLayoutObject();
+  bool is_clipping_root = &layer_ == context.root_layer;
+  LayoutBoxModelObject& layout_object = layer_.GetLayoutObject();
 
-  if (!is_clipping_root && layer_->Parent()) {
+  if (!is_clipping_root && layer_.Parent()) {
     CalculateBackgroundClipRect(context, background_rect);
     background_rect.Move(context.sub_pixel_accumulation);
   }
@@ -247,8 +247,8 @@
   if (offset_from_root)
     offset = *offset_from_root;
   else
-    layer_->ConvertToLayerCoords(context.root_layer, offset);
-  layer_bounds = PhysicalRect(offset, PhysicalSize(layer_->PixelSnappedSize()));
+    layer_.ConvertToLayerCoords(context.root_layer, offset);
+  layer_bounds = PhysicalRect(offset, PhysicalSize(layer_.PixelSnappedSize()));
 
   // Update the clip rects that will be passed to child layers.
   if (ShouldClipOverflowAlongEitherAxis(context)) {
@@ -279,8 +279,8 @@
 
 void PaintLayerClipper::CalculateClipRects(const ClipRectsContext& context,
                                            ClipRects& clip_rects) const {
-  const LayoutBoxModelObject& layout_object = layer_->GetLayoutObject();
-  bool is_clipping_root = layer_ == context.root_layer;
+  const LayoutBoxModelObject& layout_object = layer_.GetLayoutObject();
+  bool is_clipping_root = &layer_ == context.root_layer;
 
   if (is_clipping_root && !context.ShouldRespectRootLayerClip()) {
     clip_rects.Reset(PhysicalRect(LayoutRect::InfiniteIntRect()));
@@ -292,11 +292,11 @@
   // For transformed layers, the root layer was shifted to be us, so there is no
   // need to examine the parent. We want to cache clip rects with us as the
   // root.
-  PaintLayer* parent_layer = !is_clipping_root ? layer_->Parent() : nullptr;
+  PaintLayer* parent_layer = !is_clipping_root ? layer_.Parent() : nullptr;
   // Ensure that our parent's clip has been calculated so that we can examine
   // the values.
   if (parent_layer) {
-    PaintLayerClipper(parent_layer, use_geometry_mapper_)
+    PaintLayerClipper(*parent_layer, use_geometry_mapper_)
         .CalculateClipRects(context, clip_rects);
   } else {
     clip_rects.Reset(PhysicalRect(LayoutRect::InfiniteIntRect()));
@@ -306,7 +306,7 @@
 
   // Computing paint offset is expensive, skip the computation if the object
   // is known to have no clip. This check is redundant otherwise.
-  if (HasNonVisibleOverflow(*layer_) || layout_object.HasClip()) {
+  if (HasNonVisibleOverflow(layer_) || layout_object.HasClip()) {
     // This offset cannot use convertToLayerCoords, because sometimes our
     // rootLayer may be across some transformed layer boundary, for example, in
     // the PaintLayerCompositor overlapMap, where clipRects are needed in view
@@ -337,7 +337,7 @@
   DCHECK(use_geometry_mapper_);
 
   output.Reset();
-  bool is_clipping_root = layer_ == context.root_layer;
+  bool is_clipping_root = &layer_ == context.root_layer;
   if (is_clipping_root && !context.ShouldRespectRootLayerClip())
     return;
 
@@ -364,7 +364,7 @@
   // rects, so we should add methods to GeometryMapper that guarantee there
   // are tight results, or else signal an error.
   if ((should_apply_self_overflow_clip == kRespectOverflowClip) &&
-      HasNonVisibleOverflow(*layer_)) {
+      HasNonVisibleOverflow(layer_)) {
     // Implement the following special case: if computing clip rects with
     // respect to the root, don't exclude overlay scrollbars for the background
     // rect if layer_ is the same as the root.
@@ -399,7 +399,7 @@
 
 PhysicalRect PaintLayerClipper::LocalVisualRect(
     const ClipRectsContext& context) const {
-  const LayoutObject& layout_object = layer_->GetLayoutObject();
+  const LayoutObject& layout_object = layer_.GetLayoutObject();
   // The LayoutView or Global Root Scroller is special since its overflow
   // clipping rect may be larger than its box rect (crbug.com/492871).
   bool affected_by_url_bar = layout_object.IsGlobalRootScroller();
@@ -410,12 +410,12 @@
   // At this point layer_bounds_with_visual_overflow only includes the visual
   // overflow induced by paint, prior to applying filters. This function is
   // expected the return the final visual rect after filtering.
-  if (layer_->PaintsWithFilters() &&
+  if (layer_.PaintsWithFilters() &&
       // If we use GeometryMapper to map to an ancestor layer, GeometryMapper
       // will handle filter effects.
-      (!use_geometry_mapper_ || context.root_layer == layer_)) {
+      (!use_geometry_mapper_ || context.root_layer == &layer_)) {
     layer_bounds_with_visual_overflow =
-        layer_->MapRectForFilter(layer_bounds_with_visual_overflow);
+        layer_.MapRectForFilter(layer_bounds_with_visual_overflow);
   }
   return layer_bounds_with_visual_overflow;
 }
@@ -424,7 +424,7 @@
     const ClipRectsContext& context,
     ClipRect& output) const {
   if (use_geometry_mapper_) {
-    const auto& fragment_data = layer_->GetLayoutObject().FirstFragment();
+    const auto& fragment_data = layer_.GetLayoutObject().FirstFragment();
     DCHECK(fragment_data.HasLocalBorderBoxProperties());
     // TODO(chrishtr): find the root cause of not having a fragment and fix it.
     if (!fragment_data.HasLocalBorderBoxProperties())
@@ -434,20 +434,20 @@
                                                   kIgnoreOverflowClip, output);
     return;
   }
-  DCHECK(layer_->Parent());
-  LayoutView* layout_view = layer_->GetLayoutObject().View();
+  DCHECK(layer_.Parent());
+  LayoutView* layout_view = layer_.GetLayoutObject().View();
   DCHECK(layout_view);
 
   scoped_refptr<ClipRects> parent_clip_rects = ClipRects::Create();
-  if (layer_ == context.root_layer) {
+  if (&layer_ == context.root_layer) {
     parent_clip_rects->Reset(PhysicalRect(LayoutRect::InfiniteIntRect()));
   } else {
-    PaintLayerClipper(layer_->Parent(), use_geometry_mapper_)
+    PaintLayerClipper(*layer_.Parent(), use_geometry_mapper_)
         .CalculateClipRects(context, *parent_clip_rects);
   }
 
   output = BackgroundClipRectForPosition(
-      *parent_clip_rects, layer_->GetLayoutObject().StyleRef().GetPosition());
+      *parent_clip_rects, layer_.GetLayoutObject().StyleRef().GetPosition());
   output.Move(context.sub_pixel_accumulation);
 
   // Note: infinite clipRects should not be scrolled here, otherwise they will
@@ -461,15 +461,15 @@
 
 bool PaintLayerClipper::ShouldClipOverflowAlongEitherAxis(
     const ClipRectsContext& context) const {
-  if (layer_ == context.root_layer && !context.ShouldRespectRootLayerClip())
+  if (&layer_ == context.root_layer && !context.ShouldRespectRootLayerClip())
     return false;
   // Embedded objects with border radius need to compute clip rects when
   // painting child mask layers. We do not have access to paint phases here,
   // so always claim to clip and ignore it later when painting the foreground
   // phases.
-  return HasNonVisibleOverflow(*layer_) ||
-         (layer_->GetLayoutObject().IsLayoutEmbeddedContent() &&
-          layer_->GetLayoutObject().StyleRef().HasBorderRadius());
+  return HasNonVisibleOverflow(layer_) ||
+         (layer_.GetLayoutObject().IsLayoutEmbeddedContent() &&
+          layer_.GetLayoutObject().StyleRef().HasBorderRadius());
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_layer_clipper.h b/third_party/blink/renderer/core/paint/paint_layer_clipper.h
index 6d6a28d0..680c0b5 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_clipper.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_clipper.h
@@ -165,7 +165,7 @@
   STACK_ALLOCATED();
 
  public:
-  explicit PaintLayerClipper(const PaintLayer*, bool use_geometry_mapper);
+  explicit PaintLayerClipper(const PaintLayer&, bool use_geometry_mapper);
 
   // Returns the background clip rect of the layer in the local coordinate
   // space. Only looks for clips up to the given ancestor.
@@ -220,7 +220,7 @@
   // filter effects if needed.
   ALWAYS_INLINE PhysicalRect LocalVisualRect(const ClipRectsContext&) const;
 
-  const PaintLayer* layer_;
+  const PaintLayer& layer_;
   bool use_geometry_mapper_;
 
   friend class PaintLayerClipperTest;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_fragment.cc b/third_party/blink/renderer/core/paint/paint_layer_fragment.cc
deleted file mode 100644
index f68e082..0000000
--- a/third_party/blink/renderer/core/paint/paint_layer_fragment.cc
+++ /dev/null
@@ -1,17 +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/core/paint/paint_layer_fragment.h"
-#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
-#include "third_party/blink/renderer/core/paint/fragment_data.h"
-
-namespace blink {
-
-void PaintLayerFragment::Trace(Visitor* visitor) const {
-  visitor->Trace(root_fragment_data);
-  visitor->Trace(fragment_data);
-  visitor->Trace(physical_fragment);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_layer_fragment.h b/third_party/blink/renderer/core/paint/paint_layer_fragment.h
index 18978c7..9ffa07ab 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_fragment.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_fragment.h
@@ -27,7 +27,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_LAYER_FRAGMENT_H_
 
 #include "third_party/blink/renderer/core/paint/clip_rect.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
@@ -51,8 +50,6 @@
   DISALLOW_NEW();
 
  public:
-  void Trace(Visitor*) const;
-
   // See |root_fragment_data| for the coordinate space of |layer_bounds|,
   // |background_rect| and |foreground_rect|.
 
@@ -84,18 +81,16 @@
   // Defines the coordinate space of the above rects:
   // root_fragment_data->LocalBorderBoxProperties().Transform() +
   // root_fragment_data.PaintOffset().
-  Member<const FragmentData> root_fragment_data = nullptr;
+  const FragmentData* root_fragment_data = nullptr;
 
   // The corresponding FragmentData of this structure.
-  Member<const FragmentData> fragment_data = nullptr;
+  const FragmentData* fragment_data = nullptr;
 
-  Member<const NGPhysicalBoxFragment> physical_fragment;
+  const NGPhysicalBoxFragment* physical_fragment = nullptr;
 };
 
-typedef HeapVector<PaintLayerFragment, 1> PaintLayerFragments;
+typedef Vector<PaintLayerFragment, 1> PaintLayerFragments;
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::PaintLayerFragment)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_LAYER_FRAGMENT_H_
diff --git a/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc b/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc
index 355c3e7..85790409 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc
@@ -37,8 +37,8 @@
 
 PaintLayer* PaintLayerPaintOrderIterator::Next() {
   if (remaining_children_ & kNegativeZOrderChildren) {
-    if (root_->StackingNode()) {
-      const auto& neg_z_order_list = root_->StackingNode()->NegZOrderList();
+    if (root_.StackingNode()) {
+      const auto& neg_z_order_list = root_.StackingNode()->NegZOrderList();
       if (index_ < neg_z_order_list.size())
         return neg_z_order_list[index_++];
     }
@@ -60,13 +60,13 @@
     }
 
     // We reset the iterator in case we reuse it.
-    current_normal_flow_child_ = root_->FirstChild();
+    current_normal_flow_child_ = root_.FirstChild();
     remaining_children_ &= ~kNormalFlowChildren;
   }
 
   if (remaining_children_ & kPositiveZOrderChildren) {
-    if (root_->StackingNode()) {
-      const auto& pos_z_order_list = root_->StackingNode()->PosZOrderList();
+    if (root_.StackingNode()) {
+      const auto& pos_z_order_list = root_.StackingNode()->PosZOrderList();
       if (index_ < pos_z_order_list.size())
         return pos_z_order_list[index_++];
     }
@@ -80,8 +80,8 @@
 
 PaintLayer* PaintLayerPaintOrderReverseIterator::Next() {
   if (remaining_children_ & kNegativeZOrderChildren) {
-    if (root_->StackingNode()) {
-      const auto& neg_z_order_list = root_->StackingNode()->NegZOrderList();
+    if (root_.StackingNode()) {
+      const auto& neg_z_order_list = root_.StackingNode()->NegZOrderList();
       if (index_ >= 0)
         return neg_z_order_list[index_--];
     }
@@ -108,8 +108,8 @@
   }
 
   if (remaining_children_ & kPositiveZOrderChildren) {
-    if (root_->StackingNode()) {
-      const auto& pos_z_order_list = root_->StackingNode()->PosZOrderList();
+    if (root_.StackingNode()) {
+      const auto& pos_z_order_list = root_.StackingNode()->PosZOrderList();
       if (index_ >= 0)
         return pos_z_order_list[index_--];
     }
@@ -123,8 +123,8 @@
 
 void PaintLayerPaintOrderReverseIterator::SetIndexToLastItem() {
   if (remaining_children_ & kNegativeZOrderChildren) {
-    if (root_->StackingNode()) {
-      const auto& neg_z_order_list = root_->StackingNode()->NegZOrderList();
+    if (root_.StackingNode()) {
+      const auto& neg_z_order_list = root_.StackingNode()->NegZOrderList();
       if (!neg_z_order_list.IsEmpty()) {
         index_ = neg_z_order_list.size() - 1;
         return;
@@ -135,13 +135,13 @@
   }
 
   if (remaining_children_ & kNormalFlowChildren) {
-    current_normal_flow_child_ = root_->LastChild();
+    current_normal_flow_child_ = root_.LastChild();
     return;
   }
 
   if (remaining_children_ & kPositiveZOrderChildren) {
-    if (root_->StackingNode()) {
-      const auto& pos_z_order_list = root_->StackingNode()->PosZOrderList();
+    if (root_.StackingNode()) {
+      const auto& pos_z_order_list = root_.StackingNode()->PosZOrderList();
       if (!pos_z_order_list.IsEmpty()) {
         index_ = pos_z_order_list.size() - 1;
         return;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.h b/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.h
index 8325904..4ab2774b 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.h
@@ -43,12 +43,12 @@
   STACK_ALLOCATED();
 
  public:
-  PaintLayerPaintOrderIterator(const PaintLayer* root,
+  PaintLayerPaintOrderIterator(const PaintLayer& root,
                                PaintLayerIteration which_children)
       : root_(root),
         remaining_children_(which_children),
         index_(0),
-        current_normal_flow_child_(root->FirstChild())
+        current_normal_flow_child_(root.FirstChild())
 #if DCHECK_IS_ON()
         ,
         mutation_detector_(root)
@@ -61,16 +61,16 @@
 
   PaintLayer* Next();
 
-  const HeapVector<Member<PaintLayer>>*
-  LayersPaintingOverlayOverflowControlsAfter(const PaintLayer* layer) const {
-    return root_->stacking_node_
-               ? root_->stacking_node_
+  const Vector<PaintLayer*>* LayersPaintingOverlayOverflowControlsAfter(
+      const PaintLayer* layer) const {
+    return root_.stacking_node_
+               ? root_.stacking_node_
                      ->LayersPaintingOverlayOverflowControlsAfter(layer)
                : nullptr;
   }
 
  private:
-  const PaintLayer* root_;
+  const PaintLayer& root_;
   unsigned remaining_children_;
   unsigned index_;
   PaintLayer* current_normal_flow_child_;
@@ -85,7 +85,7 @@
   STACK_ALLOCATED();
 
  public:
-  PaintLayerPaintOrderReverseIterator(const PaintLayer* root,
+  PaintLayerPaintOrderReverseIterator(const PaintLayer& root,
                                       unsigned which_children)
       : root_(root),
         remaining_children_(which_children)
@@ -106,7 +106,7 @@
  private:
   void SetIndexToLastItem();
 
-  const PaintLayer* root_;
+  const PaintLayer& root_;
   unsigned remaining_children_;
   int index_;
   PaintLayer* current_normal_flow_child_;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
index 032495b..6b73dd0 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_painter.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -662,7 +662,7 @@
   if (paint_layer_.GetLayoutObject().ChildPaintBlockedByDisplayLock())
     return result;
 
-  PaintLayerPaintOrderIterator iterator(&paint_layer_, children_to_visit);
+  PaintLayerPaintOrderIterator iterator(paint_layer_, children_to_visit);
   while (PaintLayer* child = iterator.Next()) {
     // If this Layer should paint into its own backing or a grouped backing,
     // that will be done via CompositedLayerMapping::PaintContents() and
@@ -680,7 +680,7 @@
 
     if (const auto* layers_painting_overlay_overflow_controls_after =
             iterator.LayersPaintingOverlayOverflowControlsAfter(child)) {
-      for (auto& reparent_overflow_controls_layer :
+      for (auto* reparent_overflow_controls_layer :
            *layers_painting_overlay_overflow_controls_after) {
         DCHECK(reparent_overflow_controls_layer
                    ->NeedsReorderOverlayOverflowControls());
diff --git a/third_party/blink/renderer/core/paint/paint_layer_resource_info.h b/third_party/blink/renderer/core/paint/paint_layer_resource_info.h
index d3b4db9..d09e944 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_resource_info.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_resource_info.h
@@ -65,11 +65,9 @@
 
   void ResourceContentChanged(SVGResource*) override;
 
-  void Trace(Visitor* visitor) const override { visitor->Trace(layer_); }
-
  private:
   // |ClearLayer| must be called before *layer_ becomes invalid.
-  Member<PaintLayer> layer_;
+  PaintLayer* layer_;
   FloatRect filter_reference_box_;
 };
 
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 5c4495f0..3242820 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -118,10 +118,6 @@
 
 PaintLayerScrollableAreaRareData::PaintLayerScrollableAreaRareData() = default;
 
-void PaintLayerScrollableAreaRareData::Trace(Visitor* visitor) const {
-  visitor->Trace(sticky_constraints_map_);
-}
-
 const int kResizerControlExpandRatioForTouch = 2;
 
 PaintLayerScrollableArea::PaintLayerScrollableArea(PaintLayer& layer)
@@ -193,7 +189,7 @@
 }
 
 void PaintLayerScrollableArea::DisposeImpl() {
-  rare_data_.Clear();
+  rare_data_.reset();
 
   GetLayoutBox()->GetDocument().GetSnapCoordinator().RemoveSnapContainer(
       *GetLayoutBox());
@@ -277,13 +273,9 @@
 
 void PaintLayerScrollableArea::Trace(Visitor* visitor) const {
   visitor->Trace(scrollbar_manager_);
-  visitor->Trace(scroll_corner_);
-  visitor->Trace(resizer_);
   visitor->Trace(scroll_anchor_);
   visitor->Trace(scrolling_background_display_item_client_);
   visitor->Trace(scroll_corner_display_item_client_);
-  visitor->Trace(layer_);
-  visitor->Trace(rare_data_);
   ScrollableArea::Trace(visitor);
 }
 
@@ -2014,11 +2006,11 @@
     return;
   }
   const LayoutObject& style_source = ScrollbarStyleSource(*GetLayoutBox());
-  ComputedStyle* corner =
+  scoped_refptr<ComputedStyle> corner =
       GetLayoutBox()->IsScrollContainer()
           ? style_source.GetUncachedPseudoElementStyle(
                 StyleRequest(kPseudoIdScrollbarCorner, style_source.Style()))
-          : nullptr;
+          : scoped_refptr<ComputedStyle>(nullptr);
   if (corner) {
     if (!scroll_corner_) {
       scroll_corner_ = LayoutCustomScrollbarPart::CreateAnonymous(
@@ -2156,12 +2148,11 @@
     return;
 
   const LayoutObject& style_source = ScrollbarStyleSource(*GetLayoutBox());
-
-  ComputedStyle* resizer =
+  scoped_refptr<ComputedStyle> resizer =
       GetLayoutBox()->IsScrollContainer()
           ? style_source.GetUncachedPseudoElementStyle(
                 StyleRequest(kPseudoIdResizer, style_source.Style()))
-          : nullptr;
+          : scoped_refptr<ComputedStyle>(nullptr);
   if (resizer) {
     if (!resizer_) {
       resizer_ = LayoutCustomScrollbarPart::CreateAnonymous(
@@ -2179,12 +2170,12 @@
   auto it = EnsureRareData().sticky_constraints_map_.find(layer);
   if (it == EnsureRareData().sticky_constraints_map_.end())
     return nullptr;
-  return it->value;
+  return &it->value;
 }
 
 void PaintLayerScrollableArea::AddStickyConstraints(
     PaintLayer* layer,
-    StickyPositionScrollingConstraints* constraints) {
+    StickyPositionScrollingConstraints constraints) {
   UseCounter::Count(GetLayoutBox()->GetDocument(), WebFeature::kPositionSticky);
   EnsureRareData().sticky_constraints_map_.Set(layer, constraints);
 }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
index 8cacbc84..8d6cf2c 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -68,8 +68,9 @@
 class ScrollingCoordinator;
 class SubtreeLayoutScope;
 
-struct CORE_EXPORT PaintLayerScrollableAreaRareData final
-    : public GarbageCollected<PaintLayerScrollableAreaRareData> {
+struct CORE_EXPORT PaintLayerScrollableAreaRareData {
+  USING_FAST_MALLOC(PaintLayerScrollableAreaRareData);
+
  public:
   PaintLayerScrollableAreaRareData();
   PaintLayerScrollableAreaRareData(const PaintLayerScrollableAreaRareData&) =
@@ -77,8 +78,6 @@
   PaintLayerScrollableAreaRareData& operator=(
       const PaintLayerScrollableAreaRareData&) = delete;
 
-  void Trace(Visitor* visitor) const;
-
   StickyConstraintsMap sticky_constraints_map_;
   base::Optional<cc::SnapContainerData> snap_container_data_;
   bool snap_container_data_needs_update_ = true;
@@ -551,7 +550,7 @@
     return EnsureRareData().sticky_constraints_map_;
   }
   StickyPositionScrollingConstraints* GetStickyConstraints(PaintLayer*);
-  void AddStickyConstraints(PaintLayer*, StickyPositionScrollingConstraints*);
+  void AddStickyConstraints(PaintLayer*, StickyPositionScrollingConstraints);
 
   void InvalidateAllStickyConstraints();
   void InvalidateStickyConstraintsFor(PaintLayer*);
@@ -708,15 +707,15 @@
 
   ScrollingCoordinator* GetScrollingCoordinator() const;
 
-  PaintLayerScrollableAreaRareData* RareData() { return rare_data_; }
+  PaintLayerScrollableAreaRareData* RareData() { return rare_data_.get(); }
   const PaintLayerScrollableAreaRareData* RareData() const {
-    return rare_data_;
+    return rare_data_.get();
   }
 
   PaintLayerScrollableAreaRareData& EnsureRareData() {
     if (!rare_data_)
-      rare_data_ = MakeGarbageCollected<PaintLayerScrollableAreaRareData>();
-    return *rare_data_;
+      rare_data_ = std::make_unique<PaintLayerScrollableAreaRareData>();
+    return *rare_data_.get();
   }
 
   IntRect CornerRect() const;
@@ -742,7 +741,7 @@
   // PaintLayer is destructed before PaintLayerScrollable area, during this
   // time before PaintLayerScrollableArea has been collected layer_ will
   // be set to nullptr by the Dispose method.
-  Member<PaintLayer> layer_;
+  PaintLayer* layer_;
 
   // Keeps track of whether the layer is currently resizing, so events can cause
   // resizing to start and stop.
@@ -807,14 +806,14 @@
   ScrollOffset last_committed_scroll_offset_;
 
   // LayoutObject to hold our custom scroll corner.
-  Member<LayoutCustomScrollbarPart> scroll_corner_;
+  LayoutCustomScrollbarPart* scroll_corner_;
 
   // LayoutObject to hold our custom resizer.
-  Member<LayoutCustomScrollbarPart> resizer_;
+  LayoutCustomScrollbarPart* resizer_;
 
   ScrollAnchor scroll_anchor_;
 
-  Member<PaintLayerScrollableAreaRareData> rare_data_;
+  std::unique_ptr<PaintLayerScrollableAreaRareData> rare_data_;
 
   // MainThreadScrollingReason due to the properties of the LayoutObject
   uint32_t non_composited_main_thread_scrolling_reasons_;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc
index 576a3251..2add15f 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc
@@ -60,21 +60,29 @@
 // FIXME: This should not require PaintLayer. There is currently a cycle where
 // in order to determine if we isStacked() we have to ask the paint
 // layer about some of its state.
-PaintLayerStackingNode::PaintLayerStackingNode(PaintLayer* layer)
+PaintLayerStackingNode::PaintLayerStackingNode(PaintLayer& layer)
     : layer_(layer) {
-  DCHECK(layer->GetLayoutObject().IsStackingContext());
+  DCHECK(layer.GetLayoutObject().IsStackingContext());
+}
+
+PaintLayerStackingNode::~PaintLayerStackingNode() {
+#if DCHECK_IS_ON()
+  if (!layer_.GetLayoutObject().DocumentBeingDestroyed())
+    UpdateStackingParentForZOrderLists(nullptr);
+#endif
 }
 
 PaintLayerCompositor* PaintLayerStackingNode::Compositor() const {
-  DCHECK(layer_->GetLayoutObject().View());
-  if (!layer_->GetLayoutObject().View())
+  DCHECK(layer_.GetLayoutObject().View());
+  if (!layer_.GetLayoutObject().View())
     return nullptr;
-  return layer_->GetLayoutObject().View()->Compositor();
+  return layer_.GetLayoutObject().View()->Compositor();
 }
 
 void PaintLayerStackingNode::DirtyZOrderLists() {
 #if DCHECK_IS_ON()
-  DCHECK(layer_->LayerListMutationAllowed());
+  DCHECK(layer_.LayerListMutationAllowed());
+  UpdateStackingParentForZOrderLists(nullptr);
 #endif
 
   pos_z_order_list_.clear();
@@ -82,7 +90,7 @@
 
   for (auto& entry :
        layer_to_overlay_overflow_controls_painting_after_.Values()) {
-    for (PaintLayer* layer : *entry)
+    for (PaintLayer* layer : entry)
       layer->SetNeedsReorderOverlayOverflowControls(false);
   }
   layer_to_overlay_overflow_controls_painting_after_.clear();
@@ -90,7 +98,7 @@
 
   z_order_lists_dirty_ = true;
 
-  if (!layer_->GetLayoutObject().DocumentBeingDestroyed() && Compositor())
+  if (!layer_.GetLayoutObject().DocumentBeingDestroyed() && Compositor())
     Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
 }
 
@@ -171,12 +179,12 @@
 
 void PaintLayerStackingNode::RebuildZOrderLists() {
 #if DCHECK_IS_ON()
-  DCHECK(layer_->LayerListMutationAllowed());
+  DCHECK(layer_.LayerListMutationAllowed());
 #endif
   DCHECK(z_order_lists_dirty_);
 
-  layer_->SetNeedsReorderOverlayOverflowControls(false);
-  for (PaintLayer* child = layer_->FirstChild(); child;
+  layer_.SetNeedsReorderOverlayOverflowControls(false);
+  for (PaintLayer* child = layer_.FirstChild(); child;
        child = child->NextSibling())
     CollectLayers(*child, nullptr);
 
@@ -190,8 +198,8 @@
   // ensure they are on top regardless of z-indexes.  The layoutObjects of top
   // layer elements are children of the view, sorted in top layer stacking
   // order.
-  if (layer_->IsRootLayer()) {
-    LayoutBlockFlow* root_block = layer_->GetLayoutObject().View();
+  if (layer_.IsRootLayer()) {
+    LayoutBlockFlow* root_block = layer_.GetLayoutObject().View();
     // If the viewport is paginated, everything (including "top-layer" elements)
     // gets redirected to the flow thread. So that's where we have to look, in
     // that case.
@@ -207,6 +215,11 @@
       }
     }
   }
+
+#if DCHECK_IS_ON()
+  UpdateStackingParentForZOrderLists(this);
+#endif
+
   z_order_lists_dirty_ = false;
 }
 
@@ -226,7 +239,7 @@
   if (object.IsStacked()) {
     auto& list =
         style.EffectiveZIndex() >= 0 ? pos_z_order_list_ : neg_z_order_list_;
-    list.push_back(paint_layer);
+    list.push_back(&paint_layer);
   }
 
   if (object.IsStackingContext())
@@ -260,10 +273,9 @@
 
     if (layer_to_paint_overlay_overflow_controls_after) {
       layer_to_overlay_overflow_controls_painting_after_
-          .insert(layer_to_paint_overlay_overflow_controls_after,
-                  MakeGarbageCollected<PaintLayers>())
-          .stored_value->value->push_back(paint_layer);
-      overlay_overflow_controls_reordered_list_.push_back(paint_layer);
+          .insert(layer_to_paint_overlay_overflow_controls_after, PaintLayers())
+          .stored_value->value.push_back(&paint_layer);
+      overlay_overflow_controls_reordered_list_.push_back(&paint_layer);
     }
     paint_layer.SetNeedsReorderOverlayOverflowControls(
         !!layer_to_paint_overlay_overflow_controls_after);
@@ -273,6 +285,17 @@
   }
 }
 
+#if DCHECK_IS_ON()
+void PaintLayerStackingNode::UpdateStackingParentForZOrderLists(
+    PaintLayerStackingNode* stacking_parent) {
+  for (auto* layer : pos_z_order_list_)
+    layer->SetStackingParent(stacking_parent);
+  for (auto* layer : neg_z_order_list_)
+    layer->SetStackingParent(stacking_parent);
+}
+
+#endif
+
 bool PaintLayerStackingNode::StyleDidChange(PaintLayer& paint_layer,
                                             const ComputedStyle* old_style) {
   bool was_stacking_context = false;
@@ -317,12 +340,4 @@
     RebuildZOrderLists();
 }
 
-void PaintLayerStackingNode::Trace(Visitor* visitor) const {
-  visitor->Trace(layer_);
-  visitor->Trace(pos_z_order_list_);
-  visitor->Trace(neg_z_order_list_);
-  visitor->Trace(layer_to_overlay_overflow_controls_painting_after_);
-  visitor->Trace(overlay_overflow_controls_reordered_list_);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h
index 168ab630..ff04f7c7a 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h
@@ -88,13 +88,14 @@
 // We create PaintLayerStackingNode only for real stacking contexts with stacked
 // children. PaintLayerPaintOrder[Reverse]Iterator can iterate normal flow
 // children in paint order with or without a stacking node.
-class CORE_EXPORT PaintLayerStackingNode
-    : public GarbageCollected<PaintLayerStackingNode> {
+class CORE_EXPORT PaintLayerStackingNode {
+  USING_FAST_MALLOC(PaintLayerStackingNode);
+
  public:
-  explicit PaintLayerStackingNode(PaintLayer*);
+  explicit PaintLayerStackingNode(PaintLayer&);
   PaintLayerStackingNode(const PaintLayerStackingNode&) = delete;
   PaintLayerStackingNode& operator=(const PaintLayerStackingNode&) = delete;
-  ~PaintLayerStackingNode() = default;
+  ~PaintLayerStackingNode();
 
   void DirtyZOrderLists();
   void UpdateZOrderLists();
@@ -103,7 +104,7 @@
   static bool StyleDidChange(PaintLayer& paint_layer,
                              const ComputedStyle* old_style);
 
-  using PaintLayers = HeapVector<Member<PaintLayer>>;
+  using PaintLayers = Vector<PaintLayer*>;
 
   const PaintLayers& PosZOrderList() const {
     DCHECK(!z_order_lists_dirty_);
@@ -120,7 +121,7 @@
     auto it = layer_to_overlay_overflow_controls_painting_after_.find(layer);
     return it == layer_to_overlay_overflow_controls_painting_after_.end()
                ? nullptr
-               : it->value;
+               : &it->value;
   }
 
   const PaintLayers& OverlayOverflowControlsReorderedList() const {
@@ -130,17 +131,20 @@
 
   void ClearNeedsReorderOverlayOverflowControls();
 
-  void Trace(Visitor* visitor) const;
-
  private:
   void RebuildZOrderLists();
 
   struct HighestLayers;
   void CollectLayers(PaintLayer&, HighestLayers*);
 
+#if DCHECK_IS_ON()
+  void UpdateStackingParentForZOrderLists(
+      PaintLayerStackingNode* stacking_parent);
+#endif
+
   PaintLayerCompositor* Compositor() const;
 
-  Member<PaintLayer> layer_;
+  PaintLayer& layer_;
 
   // Holds a sorted list of all the descendant nodes within that have z-indices
   // of 0 (or is treated as 0 for positioned objects) or greater.
@@ -187,7 +191,7 @@
   // the map). The value of the map is a list of PaintLayers because there may
   // be more than one scrolling or resizing container in the same stacking
   // context with overlay overflow controls.
-  HeapHashMap<Member<const PaintLayer>, Member<PaintLayers>>
+  HashMap<const PaintLayer*, PaintLayers>
       layer_to_overlay_overflow_controls_painting_after_;
 
   // All PaintLayers (just in current stacking context, child stacking contexts
diff --git a/third_party/blink/renderer/core/paint/paint_layer_test.cc b/third_party/blink/renderer/core/paint/paint_layer_test.cc
index d3ef1c69..5bf75df 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_test.cc
@@ -440,9 +440,9 @@
   EXPECT_FALSE(child->HasSelfPaintingLayerDescendant());
 }
 
-static const HeapVector<Member<PaintLayer>>*
-LayersPaintingOverlayOverflowControlsAfter(const PaintLayer* layer) {
-  return PaintLayerPaintOrderIterator(layer->AncestorStackingContext(),
+static const Vector<PaintLayer*>* LayersPaintingOverlayOverflowControlsAfter(
+    const PaintLayer* layer) {
+  return PaintLayerPaintOrderIterator(*layer->AncestorStackingContext(),
                                       kPositiveZOrderChildren)
       .LayersPaintingOverlayOverflowControlsAfter(layer);
 }
@@ -1127,18 +1127,18 @@
   PaintLayer* target = GetPaintLayerByElementId("target");
 
   EXPECT_TRUE(
-      PaintLayerPaintOrderIterator(target, kNegativeZOrderChildren).Next());
+      PaintLayerPaintOrderIterator(*target, kNegativeZOrderChildren).Next());
   EXPECT_FALSE(
-      PaintLayerPaintOrderIterator(target, kPositiveZOrderChildren).Next());
+      PaintLayerPaintOrderIterator(*target, kPositiveZOrderChildren).Next());
 
   GetDocument().getElementById("child")->setAttribute(html_names::kStyleAttr,
                                                       "z-index: 1");
   UpdateAllLifecyclePhasesForTest();
 
   EXPECT_FALSE(
-      PaintLayerPaintOrderIterator(target, kNegativeZOrderChildren).Next());
+      PaintLayerPaintOrderIterator(*target, kNegativeZOrderChildren).Next());
   EXPECT_TRUE(
-      PaintLayerPaintOrderIterator(target, kPositiveZOrderChildren).Next());
+      PaintLayerPaintOrderIterator(*target, kPositiveZOrderChildren).Next());
 }
 
 TEST_P(PaintLayerTest, HasVisibleDescendant) {
@@ -1986,7 +1986,7 @@
   EXPECT_EQ(nullptr, target_paint_layer->Transform());
 
   const ComputedStyle* old_style = target_object->Style();
-  ComputedStyle* new_style = ComputedStyle::Clone(*old_style);
+  scoped_refptr<ComputedStyle> new_style = ComputedStyle::Clone(*old_style);
   new_style->SetHasCurrentTransformAnimation(true);
   target_paint_layer->UpdateTransform(old_style, *new_style);
 
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index b6b5c05..8620470 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -110,17 +110,6 @@
       was_layout_shift_root(false),
       was_main_thread_scrolling(false) {}
 
-void PaintPropertyTreeBuilderFragmentContext::Trace(Visitor* visitor) const {
-  visitor->Trace(current);
-  visitor->Trace(absolute_position);
-  visitor->Trace(fixed_position);
-}
-
-void PaintPropertyTreeBuilderFragmentContext::ContainingBlockContext::Trace(
-    Visitor* visitor) const {
-  visitor->Trace(paint_offset_root);
-}
-
 PaintPropertyChangeType VisualViewportPaintPropertyTreeBuilder::Update(
     VisualViewport& visual_viewport,
     PaintPropertyTreeBuilderContext& full_context) {
@@ -705,29 +694,29 @@
               .NearestScrollTranslationNode()
               .ScrollNode() == context_.current.scroll;
       if (nearest_scroller_is_clip && translates_with_nearest_scroller) {
-        const StickyPositionScrollingConstraints* layout_constraint =
+        const StickyPositionScrollingConstraints& layout_constraint =
             layer->AncestorScrollContainerLayer()
                 ->GetScrollableArea()
                 ->GetStickyConstraintsMap()
                 .at(layer);
         auto constraint = std::make_unique<CompositorStickyConstraint>();
-        constraint->is_anchored_left = layout_constraint->is_anchored_left;
-        constraint->is_anchored_right = layout_constraint->is_anchored_right;
-        constraint->is_anchored_top = layout_constraint->is_anchored_top;
-        constraint->is_anchored_bottom = layout_constraint->is_anchored_bottom;
+        constraint->is_anchored_left = layout_constraint.is_anchored_left;
+        constraint->is_anchored_right = layout_constraint.is_anchored_right;
+        constraint->is_anchored_top = layout_constraint.is_anchored_top;
+        constraint->is_anchored_bottom = layout_constraint.is_anchored_bottom;
 
-        constraint->left_offset = layout_constraint->left_offset.ToFloat();
-        constraint->right_offset = layout_constraint->right_offset.ToFloat();
-        constraint->top_offset = layout_constraint->top_offset.ToFloat();
-        constraint->bottom_offset = layout_constraint->bottom_offset.ToFloat();
+        constraint->left_offset = layout_constraint.left_offset.ToFloat();
+        constraint->right_offset = layout_constraint.right_offset.ToFloat();
+        constraint->top_offset = layout_constraint.top_offset.ToFloat();
+        constraint->bottom_offset = layout_constraint.bottom_offset.ToFloat();
         constraint->constraint_box_rect =
             FloatRect(box_model.ComputeStickyConstrainingRect());
         constraint->scroll_container_relative_sticky_box_rect = FloatRect(
-            layout_constraint->scroll_container_relative_sticky_box_rect);
+            layout_constraint.scroll_container_relative_sticky_box_rect);
         constraint->scroll_container_relative_containing_block_rect = FloatRect(
-            layout_constraint->scroll_container_relative_containing_block_rect);
+            layout_constraint.scroll_container_relative_containing_block_rect);
         if (PaintLayer* sticky_box_shifting_ancestor =
-                layout_constraint->nearest_sticky_layer_shifting_sticky_box) {
+                layout_constraint.nearest_sticky_layer_shifting_sticky_box) {
           constraint->nearest_element_shifting_sticky_box =
               CompositorElementIdFromUniqueObjectId(
                   sticky_box_shifting_ancestor->GetLayoutObject().UniqueId(),
@@ -735,7 +724,7 @@
         }
         if (PaintLayer* containing_block_shifting_ancestor =
                 layout_constraint
-                    ->nearest_sticky_layer_shifting_containing_block) {
+                    .nearest_sticky_layer_shifting_containing_block) {
           constraint->nearest_element_shifting_containing_block =
               CompositorElementIdFromUniqueObjectId(
                   containing_block_shifting_ancestor->GetLayoutObject()
@@ -2532,8 +2521,7 @@
 
         // Absolutely positioned content in an inline should be positioned
         // relative to the inline.
-        const LayoutObject* container =
-            full_context_.container_for_absolute_position;
+        const auto* container = full_context_.container_for_absolute_position;
         if (container && container->IsLayoutInline()) {
           DCHECK(container->CanContainAbsolutePositionObjects());
           DCHECK(box_model_object.IsBox());
@@ -2565,8 +2553,7 @@
         if (context_.fixed_position.fixed_position_children_fixed_to_root)
           context_.current.paint_offset_root = &box_model_object;
 
-        const LayoutObject* container =
-            full_context_.container_for_fixed_position;
+        const auto* container = full_context_.container_for_fixed_position;
         if (container && container->IsLayoutInline()) {
           DCHECK(container->CanContainFixedPositionObjects());
           DCHECK(box_model_object.IsBox());
@@ -3446,7 +3433,7 @@
   FragmentainerIterator iterator(
       flow_thread, object_bounding_box_in_flow_thread.ToLayoutRect());
   bool fragments_changed = false;
-  HeapVector<PaintPropertyTreeBuilderFragmentContext, 1> new_fragment_contexts;
+  Vector<PaintPropertyTreeBuilderFragmentContext, 1> new_fragment_contexts;
   for (; !iterator.AtEnd(); iterator.Advance()) {
     auto pagination_offset =
         PhysicalOffsetToBeNoop(iterator.PaginationOffset());
@@ -3531,7 +3518,7 @@
     if (current_fragment_data->NextFragment())
       fragments_changed = true;
     current_fragment_data->ClearNextFragment();
-    context_.fragments = new_fragment_contexts;
+    context_.fragments = std::move(new_fragment_contexts);
   }
 
   // Need to update subtree paint properties for the changed fragments.
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.h b/third_party/blink/renderer/core/paint/paint_property_tree_builder.h
index 51a3c614..6350901 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.h
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.h
@@ -13,7 +13,6 @@
 #include "third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h"
 #include "third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h"
 #include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 namespace blink {
@@ -36,16 +35,12 @@
   // Initializes all property tree nodes to the roots.
   PaintPropertyTreeBuilderFragmentContext();
 
-  void Trace(Visitor*) const;
-
   // State that propagates on the containing block chain (and so is adjusted
   // when an absolute or fixed position object is encountered).
   struct ContainingBlockContext {
     DISALLOW_NEW();
 
    public:
-    void Trace(Visitor*) const;
-
     // The combination of a transform and paint offset describes a linear space.
     // When a layout object recur to its children, the main context is expected
     // to refer the object's border box, then the callee will derive its own
@@ -85,7 +80,7 @@
     PhysicalOffset directly_composited_container_paint_offset_subpixel_delta;
 
     // The PaintLayer corresponding to the origin of |paint_offset|.
-    Member<const LayoutObject> paint_offset_root;
+    const LayoutObject* paint_offset_root = nullptr;
     // Whether newly created children should flatten their inherited transform
     // (equivalently, draw into the plane of their parent). Should generally
     // be updated whenever |transform| is; flattening only needs to happen
@@ -178,7 +173,7 @@
   PaintPropertyTreeBuilderContext(const PaintPropertyTreeBuilderContext&) =
       default;
 
-  HeapVector<PaintPropertyTreeBuilderFragmentContext, 1> fragments;
+  Vector<PaintPropertyTreeBuilderFragmentContext, 1> fragments;
 
   // TODO(mstensho): Stop using these in LayoutNGFragmentTraversal.
   const LayoutObject* container_for_absolute_position = nullptr;
@@ -346,7 +341,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::PaintPropertyTreeBuilderFragmentContext)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_PROPERTY_TREE_BUILDER_H_
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
index ca56343..279953b0 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
@@ -1666,7 +1666,7 @@
   )HTML");
 
   auto* target = GetLayoutObjectByElementId("target");
-  ComputedStyle* style = ComputedStyle::Clone(target->StyleRef());
+  auto style = ComputedStyle::Clone(target->StyleRef());
   GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
   // Simulates starting a composite animation.
   style->SetHasCurrentTransformAnimation(true);
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
index ff1bf57..99841cc 100644
--- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
+++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
@@ -174,7 +174,4 @@
 
 }  // namespace blink
 
-WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(
-    blink::PrePaintTreeWalk::PrePaintTreeWalkContext)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PRE_PAINT_TREE_WALK_H_
diff --git a/third_party/blink/renderer/core/paint/table_section_painter.cc b/third_party/blink/renderer/core/paint/table_section_painter.cc
index 5f2a93e..7f55a6a 100644
--- a/third_party/blink/renderer/core/paint/table_section_painter.cc
+++ b/third_party/blink/renderer/core/paint/table_section_painter.cc
@@ -232,10 +232,10 @@
     // This path paints section with a reasonable number of overflowing cells.
     // This is the "partial paint path" for overflowing cells referred in
     // LayoutTableSection::ComputeOverflowFromDescendants().
-    HeapVector<Member<const LayoutTableCell>> cells;
+    Vector<const LayoutTableCell*> cells;
     CopyToVector(visually_overflowing_cells, cells);
 
-    HeapHashSet<Member<const LayoutTableCell>> spanning_cells;
+    HashSet<const LayoutTableCell*> spanning_cells;
     for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.End(); r++) {
       const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r);
       // TODO(crbug.com/577282): This painting order is inconsistent with other
@@ -256,7 +256,7 @@
 
     // Sort the dirty cells by paint order.
     std::sort(cells.begin(), cells.end(), LayoutTableCell::CompareInDOMOrder);
-    for (const auto& cell : cells)
+    for (const auto* cell : cells)
       PaintCell(*cell, paint_info_for_descendants);
   }
 }
diff --git a/third_party/blink/renderer/core/paint/text_decoration_info.cc b/third_party/blink/renderer/core/paint/text_decoration_info.cc
index e96a7dd..0e1ba78c 100644
--- a/third_party/blink/renderer/core/paint/text_decoration_info.cc
+++ b/third_party/blink/renderer/core/paint/text_decoration_info.cc
@@ -161,24 +161,24 @@
     const ComputedStyle& style,
     const base::Optional<AppliedTextDecoration> selection_text_decoration,
     const ComputedStyle* decorating_box_style)
-    : style_(&style),
+    : style_(style),
       selection_text_decoration_(selection_text_decoration),
       baseline_type_(baseline_type),
       width_(width),
-      font_data_(style_->GetFont().PrimaryFont()),
+      font_data_(style_.GetFont().PrimaryFont()),
       baseline_(font_data_ ? font_data_->GetFontMetrics().FloatAscent() : 0),
-      underline_position_(ResolveUnderlinePosition(*style_, baseline_type_)),
+      underline_position_(ResolveUnderlinePosition(style_, baseline_type_)),
       local_origin_(FloatPoint(local_origin)),
       antialias_(ShouldSetDecorationAntialias(style)),
       decoration_index_(kUndefinedDecorationIndex) {
   DCHECK(font_data_);
 
   for (const AppliedTextDecoration& decoration :
-       style_->AppliedTextDecorations()) {
+       style_.AppliedTextDecorations()) {
     applied_decorations_thickness_.push_back(ComputeUnderlineThickness(
         decoration.Thickness(), decorating_box_style));
   }
-  DCHECK_EQ(style_->AppliedTextDecorations().size(),
+  DCHECK_EQ(style_.AppliedTextDecorations().size(),
             applied_decorations_thickness_.size());
 }
 
@@ -200,19 +200,19 @@
 }
 
 ETextDecorationStyle TextDecorationInfo::DecorationStyle() const {
-  return style_->AppliedTextDecorations()[decoration_index_].Style();
+  return style_.AppliedTextDecorations()[decoration_index_].Style();
 }
 
 Color TextDecorationInfo::LineColor() const {
   // Find the matched normal and selection |AppliedTextDecoration|
   // and use the text-decoration-color from selection when it is.
   if (selection_text_decoration_ &&
-      style_->AppliedTextDecorations()[decoration_index_].Lines() ==
+      style_.AppliedTextDecorations()[decoration_index_].Lines() ==
           selection_text_decoration_.value().Lines()) {
     return selection_text_decoration_.value().GetColor();
   }
 
-  return style_->AppliedTextDecorations()[decoration_index_].GetColor();
+  return style_.AppliedTextDecorations()[decoration_index_].GetColor();
 }
 
 FloatPoint TextDecorationInfo::StartPoint(TextDecoration line) const {
@@ -236,8 +236,8 @@
        ResolvedUnderlinePosition::kNearAlphabeticBaselineAuto) ||
       underline_position_ ==
           ResolvedUnderlinePosition::kNearAlphabeticBaselineFromFont) {
-    thickness = ComputeDecorationThickness(
-        applied_decoration_thickness, *style_, style_->GetFont().PrimaryFont());
+    thickness = ComputeDecorationThickness(applied_decoration_thickness, style_,
+                                           style_.GetFont().PrimaryFont());
   } else {
     // Compute decorating box. Position and thickness are computed from the
     // decorating box.
@@ -248,9 +248,8 @@
           applied_decoration_thickness, *decorating_box_style,
           decorating_box_style->GetFont().PrimaryFont());
     } else {
-      thickness =
-          ComputeDecorationThickness(applied_decoration_thickness, *style_,
-                                     style_->GetFont().PrimaryFont());
+      thickness = ComputeDecorationThickness(
+          applied_decoration_thickness, style_, style_.GetFont().PrimaryFont());
     }
   }
   return thickness;
diff --git a/third_party/blink/renderer/core/paint/text_decoration_info.h b/third_party/blink/renderer/core/paint/text_decoration_info.h
index 9897041..9651589 100644
--- a/third_party/blink/renderer/core/paint/text_decoration_info.h
+++ b/third_party/blink/renderer/core/paint/text_decoration_info.h
@@ -15,7 +15,6 @@
 #include "third_party/blink/renderer/platform/geometry/float_rect.h"
 #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
 #include "third_party/blink/renderer/platform/graphics/path.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 namespace blink {
@@ -66,7 +65,7 @@
   // These methods do not depend on SetDecorationIndex
   LayoutUnit Width() const { return width_; }
   float Baseline() const { return baseline_; }
-  const ComputedStyle& Style() const { return *style_; }
+  const ComputedStyle& Style() const { return style_; }
   const SimpleFontData* FontData() const { return font_data_; }
   ResolvedUnderlinePosition UnderlinePosition() const {
     return underline_position_;
@@ -108,7 +107,7 @@
   FloatRect BoundsForDottedOrDashed(TextDecoration line) const;
   FloatRect BoundsForWavy(TextDecoration line) const;
 
-  const ComputedStyle* style_;
+  const ComputedStyle& style_;
   const base::Optional<AppliedTextDecoration> selection_text_decoration_;
   const FontBaseline baseline_type_;
   const LayoutUnit width_;
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
index 71c60b3..e8317a47 100644
--- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
+++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
@@ -386,8 +386,6 @@
           paint_timing_detector)) {}
 
 void TextRecordsManager::Trace(Visitor* visitor) const {
-  visitor->Trace(visible_objects_);
-  visitor->Trace(invisible_objects_);
   visitor->Trace(text_element_timing_);
   visitor->Trace(ltp_manager_);
 }
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
index 46ff815..04bcc78 100644
--- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
+++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
@@ -201,9 +201,8 @@
   // Once LayoutObject* is destroyed, |visible_objects_| and
   // |invisible_objects_| must immediately clear the corresponding record from
   // themselves.
-  HeapHashMap<Member<const LayoutObject>, std::unique_ptr<TextRecord>>
-      visible_objects_;
-  HeapHashSet<Member<const LayoutObject>> invisible_objects_;
+  HashMap<const LayoutObject*, std::unique_ptr<TextRecord>> visible_objects_;
+  HashSet<const LayoutObject*> invisible_objects_;
 
   Deque<base::WeakPtr<TextRecord>> texts_queued_for_paint_time_;
   // These are text records created to notify Element Timing of texts which are
diff --git a/third_party/blink/renderer/core/paint/text_painter_test.cc b/third_party/blink/renderer/core/paint/text_painter_test.cc
index 2ad04d6..08ddf3e3 100644
--- a/third_party/blink/renderer/core/paint/text_painter_test.cc
+++ b/third_party/blink/renderer/core/paint/text_painter_test.cc
@@ -53,7 +53,7 @@
     ASSERT_EQ("Hello world", layout_text_->GetText());
   }
 
-  Persistent<LayoutText> layout_text_;
+  LayoutText* layout_text_;
   std::unique_ptr<PaintController> paint_controller_;
   GraphicsContext context_;
 };
diff --git a/third_party/blink/renderer/core/script/mock_script_element_base.h b/third_party/blink/renderer/core/script/mock_script_element_base.h
index a87ef204..f545c451 100644
--- a/third_party/blink/renderer/core/script/mock_script_element_base.h
+++ b/third_party/blink/renderer/core/script/mock_script_element_base.h
@@ -49,6 +49,7 @@
                     const String&));
   MOCK_CONST_METHOD0(GetDocument, Document&());
   MOCK_CONST_METHOD0(GetExecutionContext, ExecutionContext*());
+  MOCK_METHOD0(AsV8HTMLOrSVGScriptElement, V8HTMLOrSVGScriptElement*());
   MOCK_METHOD1(SetScriptElementForBinding,
                void(HTMLScriptElementOrSVGScriptElement&));
   MOCK_CONST_METHOD0(Loader, ScriptLoader*());
diff --git a/third_party/blink/renderer/core/script/script_element_base.h b/third_party/blink/renderer/core/script/script_element_base.h
index 492863e..3c7ce524 100644
--- a/third_party/blink/renderer/core/script/script_element_base.h
+++ b/third_party/blink/renderer/core/script/script_element_base.h
@@ -21,6 +21,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_SCRIPT_ELEMENT_BASE_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_SCRIPT_ELEMENT_BASE_H_
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/create_element_flags.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -30,6 +31,7 @@
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
+
 class Document;
 class Element;
 class ExecutionContext;
@@ -91,8 +93,12 @@
   virtual Document& GetDocument() const = 0;
   virtual ExecutionContext* GetExecutionContext() const = 0;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  virtual V8HTMLOrSVGScriptElement* AsV8HTMLOrSVGScriptElement() = 0;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   virtual void SetScriptElementForBinding(
       HTMLScriptElementOrSVGScriptElement&) = 0;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   virtual void DispatchLoadEvent() = 0;
   virtual void DispatchErrorEvent() = 0;
diff --git a/third_party/blink/renderer/core/streams/readable_stream.cc b/third_party/blink/renderer/core/streams/readable_stream.cc
index 4054ccc2..8687da39 100644
--- a/third_party/blink/renderer/core/streams/readable_stream.cc
+++ b/third_party/blink/renderer/core/streams/readable_stream.cc
@@ -16,6 +16,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_stream_pipe_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_underlying_source.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_readablestreambyobreader_readablestreamdefaultreader.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_writable_stream.h"
 #include "third_party/blink/renderer/core/dom/abort_signal.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -1228,6 +1229,20 @@
   return ScriptPromise(script_state, result);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8ReadableStreamReader* ReadableStream::getReader(
+    ScriptState* script_state,
+    ExceptionState& exception_state) {
+  // https://streams.spec.whatwg.org/#rs-get-reader
+  // 1. If options["mode"] does not exist, return ?
+  // AcquireReadableStreamDefaultReader(this).
+  ReadableStreamDefaultReader* reader =
+      AcquireDefaultReader(script_state, this, true, exception_state);
+  if (!reader)
+    return nullptr;
+  return MakeGarbageCollected<V8ReadableStreamReader>(reader);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void ReadableStream::getReader(
     ScriptState* script_state,
     ReadableStreamDefaultReaderOrReadableStreamBYOBReader& return_value,
@@ -1238,7 +1253,30 @@
   return_value.SetReadableStreamDefaultReader(
       AcquireDefaultReader(script_state, this, true, exception_state));
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8ReadableStreamReader* ReadableStream::getReader(
+    ScriptState* script_state,
+    const ReadableStreamGetReaderOptions* options,
+    ExceptionState& exception_state) {
+  // https://streams.spec.whatwg.org/#rs-get-reader
+  if (options->hasMode()) {
+    DCHECK_EQ(options->mode(), "byob");
+
+    UseCounter::Count(ExecutionContext::From(script_state),
+                      WebFeature::kReadableStreamBYOBReader);
+
+    ReadableStreamBYOBReader* reader =
+        AcquireBYOBReader(script_state, this, exception_state);
+    if (!reader)
+      return nullptr;
+    return MakeGarbageCollected<V8ReadableStreamReader>(reader);
+  }
+
+  return getReader(script_state, exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void ReadableStream::getReader(
     ScriptState* script_state,
     ReadableStreamGetReaderOptions* options,
@@ -1257,13 +1295,21 @@
     getReader(script_state, return_value, exception_state);
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 ReadableStreamDefaultReader* ReadableStream::GetDefaultReaderForTesting(
     ScriptState* script_state,
     ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* result = getReader(script_state, exception_state);
+  if (!result)
+    return nullptr;
+  return result->GetAsReadableStreamDefaultReader();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ReadableStreamDefaultReaderOrReadableStreamBYOBReader return_value;
   getReader(script_state, return_value, exception_state);
   return return_value.GetAsReadableStreamDefaultReader();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 ReadableStream* ReadableStream::pipeThrough(ScriptState* script_state,
diff --git a/third_party/blink/renderer/core/streams/readable_stream.h b/third_party/blink/renderer/core/streams/readable_stream.h
index 160fc08..a1cc929 100644
--- a/third_party/blink/renderer/core/streams/readable_stream.h
+++ b/third_party/blink/renderer/core/streams/readable_stream.h
@@ -10,6 +10,7 @@
 
 #include "base/optional.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/streams/readable_stream_byob_reader.h"
 #include "third_party/blink/renderer/core/streams/readable_stream_default_reader.h"
 #include "third_party/blink/renderer/core/streams/transferable_streams.h"
@@ -124,17 +125,29 @@
   // https://streams.spec.whatwg.org/#rs-cancel
   ScriptPromise cancel(ScriptState*, ScriptValue reason, ExceptionState&);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8ReadableStreamReader* getReader(ScriptState* script_state,
+                                    ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void getReader(
       ScriptState*,
       ReadableStreamDefaultReaderOrReadableStreamBYOBReader& return_value,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // https://streams.spec.whatwg.org/#rs-get-reader
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8ReadableStreamReader* getReader(
+      ScriptState* script_state,
+      const ReadableStreamGetReaderOptions* options,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void getReader(
       ScriptState*,
       ReadableStreamGetReaderOptions* options,
       ReadableStreamDefaultReaderOrReadableStreamBYOBReader& return_value,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   ReadableStreamDefaultReader* GetDefaultReaderForTesting(ScriptState*,
                                                           ExceptionState&);
diff --git a/third_party/blink/renderer/core/streams/readable_stream_test.cc b/third_party/blink/renderer/core/streams/readable_stream_test.cc
index 73843e2..b7a977d 100644
--- a/third_party/blink/renderer/core/streams/readable_stream_test.cc
+++ b/third_party/blink/renderer/core/streams/readable_stream_test.cc
@@ -15,6 +15,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream_get_reader_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_readablestreambyobreader_readablestreamdefaultreader.h"
 #include "third_party/blink/renderer/core/messaging/message_channel.h"
 #include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h"
 #include "third_party/blink/renderer/core/streams/readable_stream_default_reader.h"
@@ -250,10 +251,18 @@
   auto* options = ReadableStreamGetReaderOptions::Create();
   options->setMode("byob");
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ReadableStreamBYOBReader* reader = nullptr;
+  if (const auto* result =
+          stream->getReader(script_state, options, ASSERT_NO_EXCEPTION)) {
+    reader = result->GetAsReadableStreamBYOBReader();
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ReadableStreamDefaultReaderOrReadableStreamBYOBReader return_value;
   stream->getReader(script_state, options, return_value, ASSERT_NO_EXCEPTION);
   ReadableStreamBYOBReader* reader =
       return_value.GetAsReadableStreamBYOBReader();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ASSERT_TRUE(reader);
 
   EXPECT_TRUE(stream->locked());
diff --git a/third_party/blink/renderer/core/style/build.gni b/third_party/blink/renderer/core/style/build.gni
index f10c7ff..3f955ff 100644
--- a/third_party/blink/renderer/core/style/build.gni
+++ b/third_party/blink/renderer/core/style/build.gni
@@ -61,7 +61,6 @@
   "shape_value.h",
   "style_aspect_ratio.h",
   "style_cached_data.h",
-  "style_cached_data.cc",
   "style_content_alignment_data.h",
   "style_difference.cc",
   "style_difference.h",
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index 294fd1d..73dc42ad 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -107,13 +107,12 @@
   unsigned bitfields[5];
 };
 
-struct SameSizeAsComputedStyle
-    : public GarbageCollected<SameSizeAsComputedStyle>,
-      public SameSizeAsComputedStyleBase {
-  SameSizeAsComputedStyle() { base::debug::Alias(&members); }
+struct SameSizeAsComputedStyle : public SameSizeAsComputedStyleBase,
+                                 public RefCounted<SameSizeAsComputedStyle> {
+  SameSizeAsComputedStyle() { base::debug::Alias(&own_ptrs); }
 
  private:
-  Member<void*> members[1];
+  void* own_ptrs[1];
 };
 
 // If this assert fails, it means that size of ComputedStyle has changed. Please
@@ -124,7 +123,7 @@
 
 StyleCachedData& ComputedStyle::EnsureCachedData() const {
   if (!cached_data_)
-    cached_data_ = MakeGarbageCollected<StyleCachedData>();
+    cached_data_ = std::make_unique<StyleCachedData>();
   return *cached_data_;
 }
 
@@ -135,40 +134,37 @@
 
 PseudoElementStyleCache* ComputedStyle::GetPseudoElementStyleCache() const {
   if (cached_data_)
-    return cached_data_->pseudo_element_styles_;
+    return cached_data_->pseudo_element_styles_.get();
   return nullptr;
 }
 
 PseudoElementStyleCache& ComputedStyle::EnsurePseudoElementStyleCache() const {
   if (!cached_data_ || !cached_data_->pseudo_element_styles_) {
     EnsureCachedData().pseudo_element_styles_ =
-        MakeGarbageCollected<PseudoElementStyleCache>();
+        std::make_unique<PseudoElementStyleCache>();
   }
   return *cached_data_->pseudo_element_styles_;
 }
 
-ComputedStyle* ComputedStyle::CreateInitialStyleSingleton() {
-  return MakeGarbageCollected<ComputedStyle>(PassKey());
+scoped_refptr<ComputedStyle> ComputedStyle::CreateInitialStyleSingleton() {
+  return base::MakeRefCounted<ComputedStyle>(PassKey());
 }
 
-ComputedStyle* ComputedStyle::Clone(const ComputedStyle& other) {
-  return MakeGarbageCollected<ComputedStyle>(PassKey(), other);
+scoped_refptr<ComputedStyle> ComputedStyle::Clone(const ComputedStyle& other) {
+  return base::AdoptRef(new ComputedStyle(PassKey(), other));
 }
 
-ALWAYS_INLINE ComputedStyle::ComputedStyle() : ComputedStyleBase() {}
+ALWAYS_INLINE ComputedStyle::ComputedStyle()
+    : ComputedStyleBase(), RefCounted<ComputedStyle>() {}
 
 ALWAYS_INLINE ComputedStyle::ComputedStyle(const ComputedStyle& o)
-    : ComputedStyleBase(o) {}
+    : ComputedStyleBase(o), RefCounted<ComputedStyle>() {}
 
 ALWAYS_INLINE ComputedStyle::ComputedStyle(PassKey key) : ComputedStyle() {}
 
 ALWAYS_INLINE ComputedStyle::ComputedStyle(PassKey key, const ComputedStyle& o)
     : ComputedStyle(o) {}
 
-void ComputedStyle::Trace(Visitor* visitor) const {
-  visitor->Trace(cached_data_);
-}
-
 static bool PseudoElementStylesEqual(const ComputedStyle& old_style,
                                      const ComputedStyle& new_style) {
   if (!old_style.HasAnyPseudoElementStyles() &&
@@ -496,7 +492,7 @@
     if (pseudo_style->StyleType() == pseudo_id &&
         (!PseudoElementHasArguments(pseudo_id) ||
          pseudo_style->PseudoArgument() == pseudo_argument))
-      return pseudo_style;
+      return pseudo_style.get();
   }
 
   return nullptr;
@@ -517,11 +513,11 @@
 }
 
 const ComputedStyle* ComputedStyle::AddCachedPseudoElementStyle(
-    const ComputedStyle* pseudo) const {
+    scoped_refptr<const ComputedStyle> pseudo) const {
   DCHECK(pseudo);
   DCHECK_GT(pseudo->StyleType(), kPseudoIdNone);
 
-  const ComputedStyle* result = pseudo;
+  const ComputedStyle* result = pseudo.get();
 
   EnsurePseudoElementStyleCache().push_back(std::move(pseudo));
 
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index 7d7051c..74f067e 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -147,7 +147,7 @@
 // Blink. It acts as a container where the computed value of every CSS property
 // can be stored and retrieved:
 //
-//   auto* style = ComputedStyle::CreateInitialStyleSingleton();
+//   auto style = ComputedStyle::CreateInitialStyleSingleton();
 //   style->SetDisplay(EDisplay::kNone); //'display' keyword property
 //   style->Display();
 //
@@ -196,8 +196,8 @@
 //
 // Since this class is huge, do not mark all of it CORE_EXPORT.  Instead,
 // export only the methods you need below.
-class ComputedStyle final : public GarbageCollected<ComputedStyle>,
-                            public ComputedStyleBase {
+class ComputedStyle : public ComputedStyleBase,
+                      public RefCounted<ComputedStyle> {
   // Needed to allow access to private/protected getters of fields to allow diff
   // generation
   friend class ComputedStyleBase;
@@ -273,7 +273,7 @@
   friend class StyleResolver;
 
  protected:
-  mutable Member<StyleCachedData> cached_data_;
+  mutable std::unique_ptr<StyleCachedData> cached_data_;
 
   StyleCachedData& EnsureCachedData() const;
 
@@ -291,14 +291,13 @@
 
   ALWAYS_INLINE ComputedStyle(PassKey, const ComputedStyle&);
   ALWAYS_INLINE explicit ComputedStyle(PassKey);
-  CORE_EXPORT void Trace(Visitor*) const;
 
   // Create the per-document/context singleton that is used for shallow-copying
   // into new instances.
-  CORE_EXPORT static ComputedStyle* CreateInitialStyleSingleton();
+  CORE_EXPORT static scoped_refptr<ComputedStyle> CreateInitialStyleSingleton();
 
   // Shallow copy into a new instance sharing DataPtrs.
-  CORE_EXPORT static ComputedStyle* Clone(const ComputedStyle&);
+  CORE_EXPORT static scoped_refptr<ComputedStyle> Clone(const ComputedStyle&);
 
   // Find out how two ComputedStyles differ. Used for figuring out if style
   // recalc needs to propagate style changes down the tree. The constants are
@@ -381,7 +380,8 @@
   CORE_EXPORT const ComputedStyle* GetCachedPseudoElementStyle(
       PseudoId,
       const AtomicString& pseudo_argument = g_null_atom) const;
-  const ComputedStyle* AddCachedPseudoElementStyle(const ComputedStyle*) const;
+  const ComputedStyle* AddCachedPseudoElementStyle(
+      scoped_refptr<const ComputedStyle>) const;
   void ClearCachedPseudoElementStyles() const;
 
   /**
diff --git a/third_party/blink/renderer/core/style/computed_style_test.cc b/third_party/blink/renderer/core/style/computed_style_test.cc
index 1fbcc46..fb60bb01 100644
--- a/third_party/blink/renderer/core/style/computed_style_test.cc
+++ b/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -44,19 +44,19 @@
     initial_style_ = ComputedStyle::CreateInitialStyleSingleton();
   }
 
-  ComputedStyle* CreateComputedStyle() {
+  scoped_refptr<ComputedStyle> CreateComputedStyle() {
     return ComputedStyle::Clone(*initial_style_);
   }
 
  private:
-  Persistent<const ComputedStyle> initial_style_;
+  scoped_refptr<const ComputedStyle> initial_style_;
 };
 
 TEST_F(ComputedStyleTest, ShapeOutsideBoxEqual) {
   auto* shape1 = MakeGarbageCollected<ShapeValue>(CSSBoxType::kContent);
   auto* shape2 = MakeGarbageCollected<ShapeValue>(CSSBoxType::kContent);
-  ComputedStyle* style1 = CreateComputedStyle();
-  ComputedStyle* style2 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style1 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style2 = CreateComputedStyle();
   style1->SetShapeOutside(shape1);
   style2->SetShapeOutside(shape2);
   EXPECT_EQ(*style1, *style2);
@@ -69,8 +69,8 @@
                                                   CSSBoxType::kContent);
   auto* shape2 = MakeGarbageCollected<ShapeValue>(std::move(circle2),
                                                   CSSBoxType::kContent);
-  ComputedStyle* style1 = CreateComputedStyle();
-  ComputedStyle* style2 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style1 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style2 = CreateComputedStyle();
   style1->SetShapeOutside(shape1);
   style2->SetShapeOutside(shape2);
   EXPECT_EQ(*style1, *style2);
@@ -82,15 +82,15 @@
       ShapeClipPathOperation::Create(shape);
   scoped_refptr<ShapeClipPathOperation> path2 =
       ShapeClipPathOperation::Create(shape);
-  ComputedStyle* style1 = CreateComputedStyle();
-  ComputedStyle* style2 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style1 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style2 = CreateComputedStyle();
   style1->SetClipPath(path1);
   style2->SetClipPath(path2);
   EXPECT_EQ(*style1, *style2);
 }
 
 TEST_F(ComputedStyleTest, FocusRingWidth) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   if (::features::IsFormControlsRefreshEnabled()) {
     style->SetOutlineStyleIsAuto(static_cast<bool>(OutlineIsAuto::kOn));
     EXPECT_EQ(3, style->GetOutlineStrokeWidthForFocusRing());
@@ -118,7 +118,7 @@
 }
 
 TEST_F(ComputedStyleTest, FocusRingOutset) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   style->SetOutlineStyle(EBorderStyle::kSolid);
   style->SetOutlineStyleIsAuto(static_cast<bool>(OutlineIsAuto::kOn));
   style->SetEffectiveZoom(4.75);
@@ -134,13 +134,13 @@
 }
 
 TEST_F(ComputedStyleTest, SVGStackingContext) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   style->UpdateIsStackingContextWithoutContainment(false, false, true);
   EXPECT_TRUE(style->IsStackingContextWithoutContainment());
 }
 
 TEST_F(ComputedStyleTest, Preserve3dForceStackingContext) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   style->SetTransformStyle3D(ETransformStyle3D::kPreserve3d);
   style->SetOverflowX(EOverflow::kHidden);
   style->SetOverflowY(EOverflow::kHidden);
@@ -150,7 +150,7 @@
 }
 
 TEST_F(ComputedStyleTest, LayoutContainmentStackingContext) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   EXPECT_FALSE(style->IsStackingContextWithoutContainment());
   style->SetContain(kContainsLayout);
   style->UpdateIsStackingContextWithoutContainment(false, false, false);
@@ -162,7 +162,7 @@
   static_assert(kFirstPublicPseudoId == kPseudoIdFirstLine,
                 "Make sure we are testing the first public pseudo id");
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   style->SetHasPseudoElementStyle(kPseudoIdFirstLine);
   EXPECT_TRUE(style->HasPseudoElementStyle(kPseudoIdFirstLine));
   EXPECT_TRUE(style->HasAnyPseudoElementStyles());
@@ -172,7 +172,7 @@
   static_assert(kFirstInternalPseudoId - 1 == kPseudoIdGrammarError,
                 "Make sure we are testing the last public pseudo id");
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   style->SetHasPseudoElementStyle(kPseudoIdGrammarError);
   EXPECT_TRUE(style->HasPseudoElementStyle(kPseudoIdGrammarError));
   EXPECT_TRUE(style->HasAnyPseudoElementStyles());
@@ -180,8 +180,8 @@
 
 TEST_F(ComputedStyleTest,
        UpdatePropertySpecificDifferencesRespectsTransformAnimation) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
   other->SetHasCurrentTransformAnimation(true);
   StyleDifference diff;
   style->UpdatePropertySpecificDifferences(*other, diff);
@@ -190,8 +190,8 @@
 
 TEST_F(ComputedStyleTest,
        UpdatePropertySpecificDifferencesCompositingReasonsTransforom) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
 
   TransformOperations operations;
   // An operation is necessary since having either a non-empty transform list
@@ -211,8 +211,8 @@
 
 TEST_F(ComputedStyleTest,
        UpdatePropertySpecificDifferencesCompositingReasonsOpacity) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
 
   other->SetHasCurrentOpacityAnimation(true);
   StyleDifference diff;
@@ -222,8 +222,8 @@
 
 TEST_F(ComputedStyleTest,
        UpdatePropertySpecificDifferencesCompositingReasonsFilter) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
 
   other->SetHasCurrentFilterAnimation(true);
   StyleDifference diff;
@@ -233,8 +233,8 @@
 
 TEST_F(ComputedStyleTest,
        UpdatePropertySpecificDifferencesCompositingReasonsBackdropFilter) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
 
   other->SetHasCurrentBackdropFilterAnimation(true);
   StyleDifference diff;
@@ -244,8 +244,8 @@
 
 TEST_F(ComputedStyleTest,
        UpdatePropertySpecificDifferencesCompositingReasonsBackfaceVisibility) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
 
   other->SetBackfaceVisibility(EBackfaceVisibility::kHidden);
   StyleDifference diff;
@@ -255,8 +255,8 @@
 
 TEST_F(ComputedStyleTest,
        UpdatePropertySpecificDifferencesCompositingReasonsWillChange) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
 
   other->SetBackfaceVisibility(EBackfaceVisibility::kHidden);
   StyleDifference diff;
@@ -266,9 +266,9 @@
 
 TEST_F(ComputedStyleTest,
        UpdatePropertySpecificDifferencesCompositingReasonsUsedStylePreserve3D) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   style->SetTransformStyle3D(ETransformStyle3D::kPreserve3d);
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
 
   // This induces a flat used transform style.
   other->SetOpacity(0.5);
@@ -279,8 +279,8 @@
 
 TEST_F(ComputedStyleTest,
        UpdatePropertySpecificDifferencesCompositingReasonsOverflow) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
 
   other->SetOverflowX(EOverflow::kHidden);
   StyleDifference diff;
@@ -290,8 +290,8 @@
 
 TEST_F(ComputedStyleTest,
        UpdatePropertySpecificDifferencesCompositingReasonsContainsPaint) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
 
   // This induces a flat used transform style.
   other->SetContain(kContainsPaint);
@@ -301,8 +301,8 @@
 }
 
 TEST_F(ComputedStyleTest, UpdateBackgroundColorDifferencesHasAlpha) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
 
   StyleDifference diff;
   style->AdjustDiffForBackgroundVisuallyEqual(*other, diff);
@@ -321,8 +321,8 @@
 }
 
 TEST_F(ComputedStyleTest, UpdateBackgroundLayerDifferencesHasAlpha) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
 
   StyleDifference diff;
   style->AdjustDiffForBackgroundVisuallyEqual(*other, diff);
@@ -334,7 +334,7 @@
 }
 
 TEST_F(ComputedStyleTest, HasOutlineWithCurrentColor) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   EXPECT_FALSE(style->HasOutline());
   EXPECT_FALSE(style->HasOutlineWithCurrentColor());
   style->SetOutlineColor(StyleColor::CurrentColor());
@@ -346,7 +346,7 @@
 }
 
 TEST_F(ComputedStyleTest, HasBorderColorReferencingCurrentColor) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   EXPECT_FALSE(style->HasBorderColorReferencingCurrentColor());
   style->SetBorderBottomColor(StyleColor::CurrentColor());
   EXPECT_FALSE(style->HasBorderColorReferencingCurrentColor());
@@ -357,7 +357,7 @@
 }
 
 TEST_F(ComputedStyleTest, BorderWidth) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   style->SetBorderBottomWidth(5);
   EXPECT_EQ(style->BorderBottomWidth(), 0);
   EXPECT_EQ(style->BorderBottom().Width(), 5);
@@ -367,8 +367,8 @@
 }
 
 TEST_F(ComputedStyleTest, CursorList) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = CreateComputedStyle();
 
   auto* gradient = MakeGarbageCollected<cssvalue::CSSLinearGradientValue>(
       nullptr, nullptr, nullptr, nullptr, nullptr, cssvalue::kRepeating);
@@ -385,8 +385,8 @@
 }
 
 TEST_F(ComputedStyleTest, BorderStyle) {
-  ComputedStyle* style = CreateComputedStyle();
-  ComputedStyle* other = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> other = CreateComputedStyle();
   style->SetBorderLeftStyle(EBorderStyle::kSolid);
   style->SetBorderTopStyle(EBorderStyle::kSolid);
   style->SetBorderRightStyle(EBorderStyle::kSolid);
@@ -449,34 +449,34 @@
   EXPECT_TRUE(style->BorderSizeEquals(*other));
 }
 
-#define TEST_ANIMATION_FLAG(flag, inherited)                      \
-  do {                                                            \
-    auto* style = CreateComputedStyle();                          \
-    auto* other = CreateComputedStyle();                          \
-    EXPECT_FALSE(style->flag());                                  \
-    EXPECT_FALSE(other->flag());                                  \
-    style->Set##flag(true);                                       \
-    EXPECT_TRUE(style->flag());                                   \
-    EXPECT_EQ(ComputedStyle::Difference::inherited,               \
-              ComputedStyle::ComputeDifference(style, other));    \
-    auto diff = style->VisualInvalidationDiff(*document, *other); \
-    EXPECT_TRUE(diff.HasDifference());                            \
-    EXPECT_TRUE(diff.CompositingReasonsChanged());                \
+#define TEST_ANIMATION_FLAG(flag, inherited)                               \
+  do {                                                                     \
+    auto style = CreateComputedStyle();                                    \
+    auto other = CreateComputedStyle();                                    \
+    EXPECT_FALSE(style->flag());                                           \
+    EXPECT_FALSE(other->flag());                                           \
+    style->Set##flag(true);                                                \
+    EXPECT_TRUE(style->flag());                                            \
+    EXPECT_EQ(ComputedStyle::Difference::inherited,                        \
+              ComputedStyle::ComputeDifference(style.get(), other.get())); \
+    auto diff = style->VisualInvalidationDiff(*document, *other);          \
+    EXPECT_TRUE(diff.HasDifference());                                     \
+    EXPECT_TRUE(diff.CompositingReasonsChanged());                         \
   } while (false)
 
-#define TEST_ANIMATION_FLAG_NO_DIFF(flag)                         \
-  do {                                                            \
-    auto* style = CreateComputedStyle();                          \
-    auto* other = CreateComputedStyle();                          \
-    EXPECT_FALSE(style->flag());                                  \
-    EXPECT_FALSE(other->flag());                                  \
-    style->Set##flag(true);                                       \
-    EXPECT_TRUE(style->flag());                                   \
-    EXPECT_EQ(ComputedStyle::Difference::kEqual,                  \
-              ComputedStyle::ComputeDifference(style, other));    \
-    auto diff = style->VisualInvalidationDiff(*document, *other); \
-    EXPECT_FALSE(diff.HasDifference());                           \
-    EXPECT_FALSE(diff.CompositingReasonsChanged());               \
+#define TEST_ANIMATION_FLAG_NO_DIFF(flag)                                  \
+  do {                                                                     \
+    auto style = CreateComputedStyle();                                    \
+    auto other = CreateComputedStyle();                                    \
+    EXPECT_FALSE(style->flag());                                           \
+    EXPECT_FALSE(other->flag());                                           \
+    style->Set##flag(true);                                                \
+    EXPECT_TRUE(style->flag());                                            \
+    EXPECT_EQ(ComputedStyle::Difference::kEqual,                           \
+              ComputedStyle::ComputeDifference(style.get(), other.get())); \
+    auto diff = style->VisualInvalidationDiff(*document, *other);          \
+    EXPECT_FALSE(diff.HasDifference());                                    \
+    EXPECT_FALSE(diff.CompositingReasonsChanged());                        \
   } while (false)
 
 TEST_F(ComputedStyleTest, AnimationFlags) {
@@ -497,8 +497,8 @@
   css_test_helpers::RegisterProperty(dummy->GetDocument(), "--x", "<length>",
                                      "0px", false);
 
-  ComputedStyle* style1 = CreateComputedStyle();
-  ComputedStyle* style2 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style1 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style2 = CreateComputedStyle();
 
   using UnitType = CSSPrimitiveValue::UnitType;
 
@@ -527,8 +527,8 @@
   css_test_helpers::RegisterProperty(dummy->GetDocument(), "--x", "<length>",
                                      "0px", false);
 
-  ComputedStyle* style1 = CreateComputedStyle();
-  ComputedStyle* style2 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style1 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style2 = CreateComputedStyle();
 
   auto value1 = css_test_helpers::CreateVariableData("foo");
   auto value2 = css_test_helpers::CreateVariableData("bar");
@@ -555,8 +555,8 @@
   css_test_helpers::RegisterProperty(dummy->GetDocument(), "--x", "<length>",
                                      "0px", true);
 
-  ComputedStyle* old_style = CreateComputedStyle();
-  ComputedStyle* new_style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> old_style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> new_style = CreateComputedStyle();
 
   using UnitType = CSSPrimitiveValue::UnitType;
 
@@ -571,7 +571,7 @@
   // Removed variable
   old_style->SetVariableValue("--x", value1, true);
   EXPECT_EQ(ComputedStyle::Difference::kIndependentInherited,
-            ComputedStyle::ComputeDifference(old_style, new_style));
+            ComputedStyle::ComputeDifference(old_style.get(), new_style.get()));
 
   old_style = CreateComputedStyle();
   new_style = CreateComputedStyle();
@@ -579,7 +579,7 @@
   // Added a new variable
   new_style->SetVariableValue("--x", value2, true);
   EXPECT_EQ(ComputedStyle::Difference::kIndependentInherited,
-            ComputedStyle::ComputeDifference(old_style, new_style));
+            ComputedStyle::ComputeDifference(old_style.get(), new_style.get()));
 
   // Change value of variable
   old_style->SetVariableValue("--x", value1, true);
@@ -588,7 +588,7 @@
   EXPECT_FALSE(new_style->HasVariableDeclaration());
   EXPECT_TRUE(new_style->HasVariableReference());
   EXPECT_EQ(ComputedStyle::Difference::kIndependentInherited,
-            ComputedStyle::ComputeDifference(old_style, new_style));
+            ComputedStyle::ComputeDifference(old_style.get(), new_style.get()));
 
   old_style = CreateComputedStyle();
   new_style = CreateComputedStyle();
@@ -600,7 +600,7 @@
   EXPECT_TRUE(new_style->HasVariableDeclaration());
   EXPECT_FALSE(new_style->HasVariableReference());
   EXPECT_EQ(ComputedStyle::Difference::kIndependentInherited,
-            ComputedStyle::ComputeDifference(old_style, new_style));
+            ComputedStyle::ComputeDifference(old_style.get(), new_style.get()));
 
   old_style = CreateComputedStyle();
   new_style = CreateComputedStyle();
@@ -613,7 +613,7 @@
   EXPECT_TRUE(new_style->HasVariableDeclaration());
   EXPECT_TRUE(new_style->HasVariableReference());
   EXPECT_EQ(ComputedStyle::Difference::kIndependentInherited,
-            ComputedStyle::ComputeDifference(old_style, new_style));
+            ComputedStyle::ComputeDifference(old_style.get(), new_style.get()));
 }
 
 TEST_F(ComputedStyleTest, CustomPropertiesInheritance_StyleRecalc) {
@@ -621,8 +621,8 @@
   css_test_helpers::RegisterProperty(dummy->GetDocument(), "--x", "<length>",
                                      "0px", true);
 
-  ComputedStyle* old_style = CreateComputedStyle();
-  ComputedStyle* new_style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> old_style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> new_style = CreateComputedStyle();
 
   using UnitType = CSSPrimitiveValue::UnitType;
 
@@ -640,7 +640,7 @@
   old_style->SetVariableValue("--x", value2, true);
   EXPECT_TRUE(old_style->HasVariableReference());
   EXPECT_EQ(ComputedStyle::Difference::kInherited,
-            ComputedStyle::ComputeDifference(old_style, new_style));
+            ComputedStyle::ComputeDifference(old_style.get(), new_style.get()));
 
   old_style = CreateComputedStyle();
   new_style = CreateComputedStyle();
@@ -651,7 +651,7 @@
   new_style->SetVariableValue("--x", value2, true);
   EXPECT_TRUE(old_style->HasVariableDeclaration());
   EXPECT_EQ(ComputedStyle::Difference::kInherited,
-            ComputedStyle::ComputeDifference(old_style, new_style));
+            ComputedStyle::ComputeDifference(old_style.get(), new_style.get()));
 
   old_style = CreateComputedStyle();
   new_style = CreateComputedStyle();
@@ -663,7 +663,7 @@
   old_style->SetHasVariableDeclaration();
   EXPECT_TRUE(old_style->HasVariableDeclaration());
   EXPECT_EQ(ComputedStyle::Difference::kInherited,
-            ComputedStyle::ComputeDifference(old_style, new_style));
+            ComputedStyle::ComputeDifference(old_style.get(), new_style.get()));
 
   old_style = CreateComputedStyle();
   new_style = CreateComputedStyle();
@@ -675,7 +675,7 @@
   old_style->SetHasVariableReference();
   EXPECT_TRUE(old_style->HasVariableReference());
   EXPECT_EQ(ComputedStyle::Difference::kInherited,
-            ComputedStyle::ComputeDifference(old_style, new_style));
+            ComputedStyle::ComputeDifference(old_style.get(), new_style.get()));
 }
 
 TEST_F(ComputedStyleTest, ApplyColorSchemeLightOnDark) {
@@ -684,16 +684,16 @@
   std::unique_ptr<DummyPageHolder> dummy_page_holder =
       std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
   Document& document = dummy_page_holder->GetDocument();
-  const ComputedStyle* initial =
+  scoped_refptr<const ComputedStyle> initial =
       document.GetStyleResolver().InitialStyleForElement();
 
   ColorSchemeHelper color_scheme_helper(document);
   color_scheme_helper.SetPreferredColorScheme(
       mojom::blink::PreferredColorScheme::kDark);
   StyleResolverState state(document, *document.documentElement(),
-                           StyleRequest(initial));
+                           StyleRequest(initial.get()));
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   state.SetStyle(style);
 
   CSSPropertyRef ref("color-scheme", state.GetDocument());
@@ -719,16 +719,16 @@
   std::unique_ptr<DummyPageHolder> dummy_page_holder =
       std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
   Document& document = dummy_page_holder->GetDocument();
-  const ComputedStyle* initial =
+  scoped_refptr<const ComputedStyle> initial =
       document.GetStyleResolver().InitialStyleForElement();
 
   ColorSchemeHelper color_scheme_helper(document);
   color_scheme_helper.SetPreferredColorScheme(
       mojom::blink::PreferredColorScheme::kDark);
   StyleResolverState state(document, *document.documentElement(),
-                           StyleRequest(initial));
+                           StyleRequest(initial.get()));
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   state.SetStyle(style);
 
   CSSValueList* dark_value = CSSValueList::CreateSpaceSeparated();
@@ -763,16 +763,16 @@
   std::unique_ptr<DummyPageHolder> dummy_page_holder =
       std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
   Document& document = dummy_page_holder->GetDocument();
-  const ComputedStyle* initial =
+  scoped_refptr<const ComputedStyle> initial =
       document.GetStyleResolver().InitialStyleForElement();
 
   ColorSchemeHelper color_scheme_helper(document);
   color_scheme_helper.SetPreferredColorScheme(
       mojom::blink::PreferredColorScheme::kDark);
   StyleResolverState state(document, *document.documentElement(),
-                           StyleRequest(initial));
+                           StyleRequest(initial.get()));
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   state.SetStyle(style);
 
   auto* bgimage_declaration = ParseDeclarationBlock(
@@ -805,13 +805,13 @@
   std::unique_ptr<DummyPageHolder> dummy_page_holder =
       std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
   Document& document = dummy_page_holder->GetDocument();
-  const ComputedStyle* initial =
+  scoped_refptr<const ComputedStyle> initial =
       document.GetStyleResolver().InitialStyleForElement();
 
   StyleResolverState state(document, *document.documentElement(),
-                           StyleRequest(initial));
+                           StyleRequest(initial.get()));
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   style->SetEffectiveZoom(1.5);
   state.SetStyle(style);
 
@@ -834,14 +834,14 @@
 }
 
 TEST_F(ComputedStyleTest, InitialVariableNamesEmpty) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   EXPECT_TRUE(style->GetVariableNames().IsEmpty());
 }
 
 TEST_F(ComputedStyleTest, InitialVariableNames) {
   using css_test_helpers::CreateLengthRegistration;
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
 
   PropertyRegistry* registry = MakeGarbageCollected<PropertyRegistry>();
   registry->RegisterProperty("--x", *CreateLengthRegistration("--x", 1));
@@ -856,7 +856,7 @@
 TEST_F(ComputedStyleTest, InheritedVariableNames) {
   using css_test_helpers::CreateVariableData;
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
 
   const bool inherited = true;
   style->SetVariableData("--a", CreateVariableData("foo"), inherited);
@@ -870,7 +870,7 @@
 TEST_F(ComputedStyleTest, NonInheritedVariableNames) {
   using css_test_helpers::CreateVariableData;
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
 
   const bool inherited = true;
   style->SetVariableData("--a", CreateVariableData("foo"), !inherited);
@@ -884,7 +884,7 @@
 TEST_F(ComputedStyleTest, InheritedAndNonInheritedVariableNames) {
   using css_test_helpers::CreateVariableData;
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
 
   const bool inherited = true;
   style->SetVariableData("--a", CreateVariableData("foo"), inherited);
@@ -903,7 +903,7 @@
   using css_test_helpers::CreateLengthRegistration;
   using css_test_helpers::CreateVariableData;
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
 
   PropertyRegistry* registry = MakeGarbageCollected<PropertyRegistry>();
   registry->RegisterProperty("--b", *CreateLengthRegistration("--b", 1));
@@ -928,13 +928,13 @@
   std::unique_ptr<DummyPageHolder> dummy_page_holder =
       std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
   Document& document = dummy_page_holder->GetDocument();
-  const ComputedStyle* initial =
+  scoped_refptr<const ComputedStyle> initial =
       document.GetStyleResolver().InitialStyleForElement();
 
   StyleResolverState state(document, *document.documentElement(),
-                           StyleRequest(initial));
+                           StyleRequest(initial.get()));
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   style->SetEffectiveZoom(2);
   style->SetBorderLeftStyle(EBorderStyle::kSolid);
   style->SetOutlineStyle(EBorderStyle::kSolid);
@@ -976,13 +976,13 @@
   std::unique_ptr<DummyPageHolder> dummy_page_holder =
       std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
   Document& document = dummy_page_holder->GetDocument();
-  const ComputedStyle* initial =
+  scoped_refptr<const ComputedStyle> initial =
       document.GetStyleResolver().InitialStyleForElement();
 
   StyleResolverState state(document, *document.documentElement(),
-                           StyleRequest(initial));
+                           StyleRequest(initial.get()));
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
 
   // Set up the initial text decoration properties
   style->SetTextDecorationStyle(ETextDecorationStyle::kSolid);
@@ -996,7 +996,7 @@
   StyleAdjuster::AdjustComputedStyle(state, nullptr /* element */);
   EXPECT_EQ(TextDecoration::kUnderline, style->TextDecorationsInEffect());
 
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
   StyleDifference diff1;
   style->UpdatePropertySpecificDifferences(*other, diff1);
   EXPECT_FALSE(diff1.NeedsRecomputeVisualOverflow());
@@ -1016,13 +1016,13 @@
   std::unique_ptr<DummyPageHolder> dummy_page_holder =
       std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
   Document& document = dummy_page_holder->GetDocument();
-  const ComputedStyle* initial =
+  scoped_refptr<const ComputedStyle> initial =
       document.GetStyleResolver().InitialStyleForElement();
 
   StyleResolverState state(document, *document.documentElement(),
-                           StyleRequest(initial));
+                           StyleRequest(initial.get()));
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
 
   // Set up the initial text decoration properties
   style->SetTextDecorationStyle(ETextDecorationStyle::kSolid);
@@ -1036,7 +1036,7 @@
   StyleAdjuster::AdjustComputedStyle(state, nullptr /* element */);
 
   // Change decoration style
-  ComputedStyle* other = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> other = ComputedStyle::Clone(*style);
   other->SetTextDecorationStyle(ETextDecorationStyle::kWavy);
   state.SetStyle(other);
   StyleAdjuster::AdjustComputedStyle(state, nullptr /* element */);
@@ -1085,14 +1085,14 @@
 // Verify that cloned ComputedStyle is independent from source, i.e.
 // copy-on-write works as expected.
 TEST_F(ComputedStyleTest, ClonedStyleAnimationsAreIndependent) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
 
   auto& animations = style->AccessAnimations();
   animations.DelayList().clear();
   animations.DelayList().push_back(CSSAnimationData::InitialDelay());
   EXPECT_EQ(1u, style->Animations()->DelayList().size());
 
-  ComputedStyle* cloned_style = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> cloned_style = ComputedStyle::Clone(*style);
   auto& cloned_style_animations = cloned_style->AccessAnimations();
   EXPECT_EQ(1u, cloned_style_animations.DelayList().size());
   cloned_style_animations.DelayList().push_back(
@@ -1103,14 +1103,14 @@
 }
 
 TEST_F(ComputedStyleTest, ClonedStyleTransitionsAreIndependent) {
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
 
   auto& transitions = style->AccessTransitions();
   transitions.PropertyList().clear();
   transitions.PropertyList().push_back(CSSTransitionData::InitialProperty());
   EXPECT_EQ(1u, style->Transitions()->PropertyList().size());
 
-  ComputedStyle* cloned_style = ComputedStyle::Clone(*style);
+  scoped_refptr<ComputedStyle> cloned_style = ComputedStyle::Clone(*style);
   auto& cloned_style_transitions = cloned_style->AccessTransitions();
   EXPECT_EQ(1u, cloned_style_transitions.PropertyList().size());
   cloned_style_transitions.PropertyList().push_back(
@@ -1124,13 +1124,13 @@
   std::unique_ptr<DummyPageHolder> dummy_page_holder =
       std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
   Document& document = dummy_page_holder->GetDocument();
-  const ComputedStyle* initial =
+  scoped_refptr<const ComputedStyle> initial =
       document.GetStyleResolver().InitialStyleForElement();
 
   StyleResolverState state(document, *document.documentElement(),
-                           StyleRequest(initial));
+                           StyleRequest(initial.get()));
 
-  ComputedStyle* style = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style = CreateComputedStyle();
   state.SetStyle(style);
   EXPECT_FALSE(style->Animations());
   EXPECT_FALSE(style->Transitions());
@@ -1143,8 +1143,8 @@
 
 #define TEST_STYLE_VALUE_NO_DIFF(field_name)                        \
   {                                                                 \
-    ComputedStyle* style1 = CreateComputedStyle();                  \
-    ComputedStyle* style2 = CreateComputedStyle();                  \
+    scoped_refptr<ComputedStyle> style1 = CreateComputedStyle();    \
+    scoped_refptr<ComputedStyle> style2 = CreateComputedStyle();    \
     style1->Set##field_name(                                        \
         ComputedStyleInitialValues::Initial##field_name());         \
     style2->Set##field_name(                                        \
@@ -1156,8 +1156,8 @@
 // Ensures ref-counted values are compared by their values, not by pointers.
 #define TEST_STYLE_REFCOUNTED_VALUE_NO_DIFF(type, field_name)              \
   {                                                                        \
-    ComputedStyle* style1 = CreateComputedStyle();                         \
-    ComputedStyle* style2 = CreateComputedStyle();                         \
+    scoped_refptr<ComputedStyle> style1 = CreateComputedStyle();           \
+    scoped_refptr<ComputedStyle> style2 = CreateComputedStyle();           \
     scoped_refptr<type> value1 = base::MakeRefCounted<type>();             \
     scoped_refptr<type> value2 = base::MakeRefCounted<type>(value1->data); \
     style1->Set##field_name(value1);                                       \
@@ -1189,8 +1189,8 @@
 #if DCHECK_IS_ON()
 
 TEST_F(ComputedStyleTest, DebugDiffFields) {
-  ComputedStyle* style1 = CreateComputedStyle();
-  ComputedStyle* style2 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style1 = CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style2 = CreateComputedStyle();
 
   style1->SetWidth(Length(100.0, Length::kFixed));
   style2->SetWidth(Length(200.0, Length::kFixed));
diff --git a/third_party/blink/renderer/core/style/content_data.cc b/third_party/blink/renderer/core/style/content_data.cc
index 47db7db..ee3a7101 100644
--- a/third_party/blink/renderer/core/style/content_data.cc
+++ b/third_party/blink/renderer/core/style/content_data.cc
@@ -32,7 +32,6 @@
 #include "third_party/blink/renderer/core/layout/layout_quote.h"
 #include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
 #include "third_party/blink/renderer/core/style/computed_style.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
 
 namespace blink {
 
@@ -99,8 +98,7 @@
     PseudoElement& pseudo,
     const ComputedStyle& pseudo_style,
     LegacyLayout) const {
-  LayoutObject* layout_object =
-      MakeGarbageCollected<LayoutCounter>(pseudo, *this);
+  LayoutObject* layout_object = new LayoutCounter(pseudo, *this);
   layout_object->SetPseudoElementStyle(&pseudo_style);
   return layout_object;
 }
@@ -114,8 +112,7 @@
     PseudoElement& pseudo,
     const ComputedStyle& pseudo_style,
     LegacyLayout) const {
-  LayoutObject* layout_object =
-      MakeGarbageCollected<LayoutQuote>(pseudo, quote_);
+  LayoutObject* layout_object = new LayoutQuote(pseudo, quote_);
   layout_object->SetPseudoElementStyle(&pseudo_style);
   return layout_object;
 }
diff --git a/third_party/blink/renderer/core/style/nine_piece_image.cc b/third_party/blink/renderer/core/style/nine_piece_image.cc
index 1f849e72..4e5fdbe 100644
--- a/third_party/blink/renderer/core/style/nine_piece_image.cc
+++ b/third_party/blink/renderer/core/style/nine_piece_image.cc
@@ -29,10 +29,7 @@
 namespace blink {
 
 static DataRef<NinePieceImageData>& DefaultData() {
-  // Use ThreadSpecific to create a ComputedStyle for each thread as this can be
-  // called on a Worker thread.
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<DataRef<NinePieceImageData>>,
-                                  data, ());
+  static DataRef<NinePieceImageData>* data = new DataRef<NinePieceImageData>;
   if (!data->Get())
     data->Init();
   return *data;
diff --git a/third_party/blink/renderer/core/style/style_cached_data.cc b/third_party/blink/renderer/core/style/style_cached_data.cc
deleted file mode 100644
index c76e4c8..0000000
--- a/third_party/blink/renderer/core/style/style_cached_data.cc
+++ /dev/null
@@ -1,15 +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/core/style/style_cached_data.h"
-
-#include "third_party/blink/renderer/core/style/computed_style.h"
-
-namespace blink {
-
-void StyleCachedData::Trace(Visitor* visitor) const {
-  visitor->Trace(pseudo_element_styles_);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/style/style_cached_data.h b/third_party/blink/renderer/core/style/style_cached_data.h
index 3cb96f9..0dc05bd 100644
--- a/third_party/blink/renderer/core/style/style_cached_data.h
+++ b/third_party/blink/renderer/core/style/style_cached_data.h
@@ -12,13 +12,9 @@
 
 class ComputedStyle;
 
-using PseudoElementStyleCache = HeapVector<Member<const ComputedStyle>, 4>;
+using PseudoElementStyleCache = Vector<scoped_refptr<const ComputedStyle>, 4>;
 
-class CORE_EXPORT StyleCachedData final
-    : public GarbageCollected<StyleCachedData> {
- public:
-  void Trace(Visitor*) const;
-
+class CORE_EXPORT StyleCachedData final {
  private:
   friend class ComputedStyle;
 
@@ -40,7 +36,7 @@
   //    <script>
   //      getComputedStyle(div, "::before").color // still green.
   //    </script>
-  Member<PseudoElementStyleCache> pseudo_element_styles_;
+  std::unique_ptr<PseudoElementStyleCache> pseudo_element_styles_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_a_element.cc b/third_party/blink/renderer/core/svg/svg_a_element.cc
index baa73e5..50cb445 100644
--- a/third_party/blink/renderer/core/svg/svg_a_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_a_element.cc
@@ -101,9 +101,9 @@
                                               LegacyLayout) {
   auto* svg_element = DynamicTo<SVGElement>(parentNode());
   if (svg_element && svg_element->IsTextContent())
-    return MakeGarbageCollected<LayoutSVGInline>(this);
+    return new LayoutSVGInline(this);
 
-  return MakeGarbageCollected<LayoutSVGTransformableContainer>(this);
+  return new LayoutSVGTransformableContainer(this);
 }
 
 void SVGAElement::DefaultEventHandler(Event& event) {
diff --git a/third_party/blink/renderer/core/svg/svg_animated_href.cc b/third_party/blink/renderer/core/svg/svg_animated_href.cc
index 734d8094..e194e73d 100644
--- a/third_party/blink/renderer/core/svg/svg_animated_href.cc
+++ b/third_party/blink/renderer/core/svg/svg_animated_href.cc
@@ -45,6 +45,23 @@
   return BackingString()->SVGAnimatedString::CurrentValue();
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8UnionStringOrTrustedScriptURL* SVGAnimatedHref::baseVal() {
+  UseCounter::Count(ContextElement()->GetDocument(),
+                    WebFeature::kSVGHrefBaseVal);
+  return BackingString()->SVGAnimatedString::baseVal();
+}
+
+void SVGAnimatedHref::setBaseVal(const V8UnionStringOrTrustedScriptURL* value,
+                                 ExceptionState& exception_state) {
+  UseCounter::Count(ContextElement()->GetDocument(),
+                    WebFeature::kSVGHrefBaseVal);
+  BackingString()->SVGAnimatedString::setBaseVal(value, exception_state);
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void SVGAnimatedHref::baseVal(
     StringOrTrustedScriptURL& string_or_trusted_script_url) {
   UseCounter::Count(ContextElement()->GetDocument(),
@@ -59,6 +76,8 @@
   return BackingString()->SVGAnimatedString::setBaseVal(value, exception_state);
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 String SVGAnimatedHref::animVal() {
   UseCounter::Count(ContextElement()->GetDocument(),
                     WebFeature::kSVGHrefAnimVal);
diff --git a/third_party/blink/renderer/core/svg/svg_animated_href.h b/third_party/blink/renderer/core/svg/svg_animated_href.h
index cd6d15d..3f53e46 100644
--- a/third_party/blink/renderer/core/svg/svg_animated_href.h
+++ b/third_party/blink/renderer/core/svg/svg_animated_href.h
@@ -26,8 +26,14 @@
   SVGString* CurrentValue();
   const SVGString* CurrentValue() const;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionStringOrTrustedScriptURL* baseVal() override;
+  void setBaseVal(const V8UnionStringOrTrustedScriptURL* value,
+                  ExceptionState& exception_state) override;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void baseVal(StringOrTrustedScriptURL&) override;
   void setBaseVal(const StringOrTrustedScriptURL&, ExceptionState&) override;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   String animVal() override;
 
   bool IsSpecified() const {
diff --git a/third_party/blink/renderer/core/svg/svg_animated_string.cc b/third_party/blink/renderer/core/svg/svg_animated_string.cc
index cdce2cd1..b3b1e5f8 100644
--- a/third_party/blink/renderer/core/svg/svg_animated_string.cc
+++ b/third_party/blink/renderer/core/svg/svg_animated_string.cc
@@ -5,12 +5,45 @@
 #include "third_party/blink/renderer/core/svg/svg_animated_string.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script_url.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_trustedscripturl.h"
 #include "third_party/blink/renderer/core/svg/svg_element.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
 
 namespace blink {
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8UnionStringOrTrustedScriptURL* SVGAnimatedString::baseVal() {
+  return MakeGarbageCollected<V8UnionStringOrTrustedScriptURL>(
+      SVGAnimatedProperty<SVGString>::baseVal());
+}
+
+void SVGAnimatedString::setBaseVal(const V8UnionStringOrTrustedScriptURL* value,
+                                   ExceptionState& exception_state) {
+  DCHECK(value);
+
+  // https://w3c.github.io/webappsec-trusted-types/dist/spec/#integration-with-svg
+  String string;
+  switch (value->GetContentType()) {
+    case V8UnionStringOrTrustedScriptURL::ContentType::kString:
+      string = value->GetAsString();
+      if (ContextElement()->IsScriptElement()) {
+        string = TrustedTypesCheckForScriptURL(
+            string, ContextElement()->GetExecutionContext(), exception_state);
+        if (exception_state.HadException())
+          return;
+      }
+      break;
+    case V8UnionStringOrTrustedScriptURL::ContentType::kTrustedScriptURL:
+      string = value->GetAsTrustedScriptURL()->toString();
+      break;
+  }
+  SVGAnimatedProperty<SVGString>::setBaseVal(string, exception_state);
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void SVGAnimatedString::setBaseVal(
     const StringOrTrustedScriptURL& string_or_trusted_script_url,
     ExceptionState& exception_state) {
@@ -37,6 +70,8 @@
       SVGAnimatedProperty<SVGString>::baseVal());
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 String SVGAnimatedString::animVal() {
   return SVGAnimatedProperty<SVGString>::animVal();
 }
diff --git a/third_party/blink/renderer/core/svg/svg_animated_string.h b/third_party/blink/renderer/core/svg/svg_animated_string.h
index 7fcfb57..c7a85ccc 100644
--- a/third_party/blink/renderer/core/svg/svg_animated_string.h
+++ b/third_party/blink/renderer/core/svg/svg_animated_string.h
@@ -39,6 +39,7 @@
 namespace blink {
 
 class StringOrTrustedScriptURL;
+class V8UnionStringOrTrustedScriptURL;
 
 class SVGAnimatedString : public ScriptWrappable,
                           public SVGAnimatedProperty<SVGString> {
@@ -51,8 +52,14 @@
                                        attribute_name,
                                        MakeGarbageCollected<SVGString>()) {}
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  virtual V8UnionStringOrTrustedScriptURL* baseVal();
+  virtual void setBaseVal(const V8UnionStringOrTrustedScriptURL* value,
+                          ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   virtual void setBaseVal(const StringOrTrustedScriptURL&, ExceptionState&);
   virtual void baseVal(StringOrTrustedScriptURL&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   virtual String animVal();
 
diff --git a/third_party/blink/renderer/core/svg/svg_circle_element.cc b/third_party/blink/renderer/core/svg/svg_circle_element.cc
index 87e380a..3ba4de8d 100644
--- a/third_party/blink/renderer/core/svg/svg_circle_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_circle_element.cc
@@ -117,7 +117,7 @@
 
 LayoutObject* SVGCircleElement::CreateLayoutObject(const ComputedStyle&,
                                                    LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGEllipse>(this);
+  return new LayoutSVGEllipse(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_clip_path_element.cc b/third_party/blink/renderer/core/svg/svg_clip_path_element.cc
index a5562b4..63ff57c8 100644
--- a/third_party/blink/renderer/core/svg/svg_clip_path_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_clip_path_element.cc
@@ -69,7 +69,7 @@
 
 LayoutObject* SVGClipPathElement::CreateLayoutObject(const ComputedStyle&,
                                                      LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGResourceClipper>(this);
+  return new LayoutSVGResourceClipper(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_defs_element.cc b/third_party/blink/renderer/core/svg/svg_defs_element.cc
index 1ec8512..a5a7576 100644
--- a/third_party/blink/renderer/core/svg/svg_defs_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_defs_element.cc
@@ -30,7 +30,7 @@
 
 LayoutObject* SVGDefsElement::CreateLayoutObject(const ComputedStyle&,
                                                  LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGHiddenContainer>(this);
+  return new LayoutSVGHiddenContainer(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_element.cc b/third_party/blink/renderer/core/svg/svg_element.cc
index 25e79269..7a89f8ab 100644
--- a/third_party/blink/renderer/core/svg/svg_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_element.cc
@@ -1007,7 +1007,7 @@
   }
 }
 
-ComputedStyle* SVGElement::CustomStyleForLayoutObject(
+scoped_refptr<ComputedStyle> SVGElement::CustomStyleForLayoutObject(
     const StyleRecalcContext& style_recalc_context) {
   SVGElement* corresponding_element = CorrespondingElement();
   if (!corresponding_element) {
diff --git a/third_party/blink/renderer/core/svg/svg_element.h b/third_party/blink/renderer/core/svg/svg_element.h
index b33fadc..2171cb9 100644
--- a/third_party/blink/renderer/core/svg/svg_element.h
+++ b/third_party/blink/renderer/core/svg/svg_element.h
@@ -165,7 +165,8 @@
   void CollectExtraStyleForPresentationAttribute(
       MutableCSSPropertyValueSet*) override;
 
-  ComputedStyle* CustomStyleForLayoutObject(const StyleRecalcContext&) final;
+  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
+      const StyleRecalcContext&) final;
   bool LayoutObjectIsNeeded(const ComputedStyle&) const override;
 
 #if DCHECK_IS_ON()
diff --git a/third_party/blink/renderer/core/svg/svg_element_rare_data.cc b/third_party/blink/renderer/core/svg/svg_element_rare_data.cc
index ba24ceea..c8b125f 100644
--- a/third_party/blink/renderer/core/svg/svg_element_rare_data.cc
+++ b/third_party/blink/renderer/core/svg/svg_element_rare_data.cc
@@ -49,7 +49,7 @@
     needs_override_computed_style_update_ = false;
   }
   DCHECK(override_computed_style_);
-  return override_computed_style_;
+  return override_computed_style_.get();
 }
 
 void SVGElementRareData::ClearOverriddenComputedStyle() {
@@ -67,7 +67,6 @@
   visitor->Trace(outgoing_references_);
   visitor->Trace(incoming_references_);
   visitor->Trace(animated_smil_style_properties_);
-  visitor->Trace(override_computed_style_);
   visitor->Trace(element_instances_);
   visitor->Trace(corresponding_element_);
   visitor->Trace(resource_client_);
diff --git a/third_party/blink/renderer/core/svg/svg_element_rare_data.h b/third_party/blink/renderer/core/svg/svg_element_rare_data.h
index de65b3c..d48de26 100644
--- a/third_party/blink/renderer/core/svg/svg_element_rare_data.h
+++ b/third_party/blink/renderer/core/svg/svg_element_rare_data.h
@@ -113,7 +113,7 @@
   bool web_animated_attributes_dirty_ : 1;
   HashSet<QualifiedName> web_animated_attributes_;
   Member<MutableCSSPropertyValueSet> animated_smil_style_properties_;
-  Member<ComputedStyle> override_computed_style_;
+  scoped_refptr<ComputedStyle> override_computed_style_;
   // Used by <animateMotion>
   AffineTransform animate_motion_transform_;
   DISALLOW_COPY_AND_ASSIGN(SVGElementRareData);
diff --git a/third_party/blink/renderer/core/svg/svg_ellipse_element.cc b/third_party/blink/renderer/core/svg/svg_ellipse_element.cc
index a2def7f..c12f8f4 100644
--- a/third_party/blink/renderer/core/svg/svg_ellipse_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_ellipse_element.cc
@@ -134,7 +134,7 @@
 
 LayoutObject* SVGEllipseElement::CreateLayoutObject(const ComputedStyle&,
                                                     LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGEllipse>(this);
+  return new LayoutSVGEllipse(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_filter_element.cc b/third_party/blink/renderer/core/svg/svg_filter_element.cc
index 99ffa2e..d1925a7c 100644
--- a/third_party/blink/renderer/core/svg/svg_filter_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_filter_element.cc
@@ -140,7 +140,7 @@
 
 LayoutObject* SVGFilterElement::CreateLayoutObject(const ComputedStyle&,
                                                    LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGResourceFilter>(this);
+  return new LayoutSVGResourceFilter(this);
 }
 
 bool SVGFilterElement::SelfHasRelativeLengths() const {
diff --git a/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc b/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc
index 1f01ba5..6bf7616c 100644
--- a/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc
+++ b/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc
@@ -170,7 +170,7 @@
 LayoutObject* SVGFilterPrimitiveStandardAttributes::CreateLayoutObject(
     const ComputedStyle&,
     LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGFilterPrimitive>(this);
+  return new LayoutSVGFilterPrimitive(this);
 }
 
 bool SVGFilterPrimitiveStandardAttributes::LayoutObjectIsNeeded(
diff --git a/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc b/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc
index f121e77..72385889 100644
--- a/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc
@@ -141,7 +141,7 @@
         ancestor->GetLayoutObject()->IsSVGHiddenContainer())
       return nullptr;
   }
-  return MakeGarbageCollected<LayoutSVGForeignObject>(this);
+  return new LayoutSVGForeignObject(this);
 }
 
 bool SVGForeignObjectElement::SelfHasRelativeLengths() const {
diff --git a/third_party/blink/renderer/core/svg/svg_foreign_object_element_test.cc b/third_party/blink/renderer/core/svg/svg_foreign_object_element_test.cc
index 91bccf1..2c58fb3 100644
--- a/third_party/blink/renderer/core/svg/svg_foreign_object_element_test.cc
+++ b/third_party/blink/renderer/core/svg/svg_foreign_object_element_test.cc
@@ -28,7 +28,8 @@
   Element* foreign_object = GetDocument().getElementById("fo");
   EXPECT_FALSE(foreign_object->GetLayoutObject());
 
-  ComputedStyle* style = GetDocument().GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style =
+      GetDocument().GetStyleResolver().CreateComputedStyle();
   LayoutObject* layout_object =
       foreign_object->CreateLayoutObject(*style, LegacyLayout::kAuto);
   EXPECT_FALSE(layout_object);
diff --git a/third_party/blink/renderer/core/svg/svg_g_element.cc b/third_party/blink/renderer/core/svg/svg_g_element.cc
index 0dd1421..6e85fca 100644
--- a/third_party/blink/renderer/core/svg/svg_g_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_g_element.cc
@@ -37,10 +37,10 @@
   // element, though the subtree may be hidden - we only want the resource
   // layoutObjects to exist so they can be referenced from somewhere else.
   if (style.Display() == EDisplay::kNone)
-    return MakeGarbageCollected<LayoutSVGHiddenContainer>(this);
+    return new LayoutSVGHiddenContainer(this);
   if (style.Display() == EDisplay::kContents)
     return nullptr;
-  return MakeGarbageCollected<LayoutSVGTransformableContainer>(this);
+  return new LayoutSVGTransformableContainer(this);
 }
 
 bool SVGGElement::LayoutObjectIsNeeded(const ComputedStyle&) const {
diff --git a/third_party/blink/renderer/core/svg/svg_geometry_element.cc b/third_party/blink/renderer/core/svg/svg_geometry_element.cc
index c059c817..4a54d968 100644
--- a/third_party/blink/renderer/core/svg/svg_geometry_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_geometry_element.cc
@@ -250,7 +250,7 @@
 LayoutObject* SVGGeometryElement::CreateLayoutObject(const ComputedStyle&,
                                                      LegacyLayout) {
   // By default, any subclass is expected to do path-based drawing.
-  return MakeGarbageCollected<LayoutSVGPath>(this);
+  return new LayoutSVGPath(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_image_element.cc b/third_party/blink/renderer/core/svg/svg_image_element.cc
index 4337ac6..74ba655 100644
--- a/third_party/blink/renderer/core/svg/svg_image_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_image_element.cc
@@ -188,7 +188,7 @@
 
 LayoutObject* SVGImageElement::CreateLayoutObject(const ComputedStyle&,
                                                   LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGImage>(this);
+  return new LayoutSVGImage(this);
 }
 
 bool SVGImageElement::HaveLoadedRequiredResources() {
diff --git a/third_party/blink/renderer/core/svg/svg_linear_gradient_element.cc b/third_party/blink/renderer/core/svg/svg_linear_gradient_element.cc
index eb2cb45..b050ac4 100644
--- a/third_party/blink/renderer/core/svg/svg_linear_gradient_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_linear_gradient_element.cc
@@ -87,7 +87,7 @@
 
 LayoutObject* SVGLinearGradientElement::CreateLayoutObject(const ComputedStyle&,
                                                            LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGResourceLinearGradient>(this);
+  return new LayoutSVGResourceLinearGradient(this);
 }
 
 static void SetGradientAttributes(const SVGGradientElement& element,
diff --git a/third_party/blink/renderer/core/svg/svg_marker_element.cc b/third_party/blink/renderer/core/svg/svg_marker_element.cc
index 5501d95..1018203 100644
--- a/third_party/blink/renderer/core/svg/svg_marker_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_marker_element.cc
@@ -160,7 +160,7 @@
 
 LayoutObject* SVGMarkerElement::CreateLayoutObject(const ComputedStyle&,
                                                    LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGResourceMarker>(this);
+  return new LayoutSVGResourceMarker(this);
 }
 
 bool SVGMarkerElement::SelfHasRelativeLengths() const {
diff --git a/third_party/blink/renderer/core/svg/svg_mask_element.cc b/third_party/blink/renderer/core/svg/svg_mask_element.cc
index 06c657de..2af1739 100644
--- a/third_party/blink/renderer/core/svg/svg_mask_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_mask_element.cc
@@ -156,7 +156,7 @@
 
 LayoutObject* SVGMaskElement::CreateLayoutObject(const ComputedStyle&,
                                                  LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGResourceMasker>(this);
+  return new LayoutSVGResourceMasker(this);
 }
 
 bool SVGMaskElement::SelfHasRelativeLengths() const {
diff --git a/third_party/blink/renderer/core/svg/svg_pattern_element.cc b/third_party/blink/renderer/core/svg/svg_pattern_element.cc
index 6f747010..dc18252 100644
--- a/third_party/blink/renderer/core/svg/svg_pattern_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_pattern_element.cc
@@ -202,7 +202,7 @@
 
 LayoutObject* SVGPatternElement::CreateLayoutObject(const ComputedStyle&,
                                                     LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGResourcePattern>(this);
+  return new LayoutSVGResourcePattern(this);
 }
 
 static void SetPatternAttributes(const SVGPatternElement& element,
diff --git a/third_party/blink/renderer/core/svg/svg_radial_gradient_element.cc b/third_party/blink/renderer/core/svg/svg_radial_gradient_element.cc
index cc12115c..7cc27ba 100644
--- a/third_party/blink/renderer/core/svg/svg_radial_gradient_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_radial_gradient_element.cc
@@ -101,7 +101,7 @@
 
 LayoutObject* SVGRadialGradientElement::CreateLayoutObject(const ComputedStyle&,
                                                            LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGResourceRadialGradient>(this);
+  return new LayoutSVGResourceRadialGradient(this);
 }
 
 static void SetGradientAttributes(const SVGGradientElement& element,
diff --git a/third_party/blink/renderer/core/svg/svg_rect_element.cc b/third_party/blink/renderer/core/svg/svg_rect_element.cc
index 72c6ee1..8f48e0dc 100644
--- a/third_party/blink/renderer/core/svg/svg_rect_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_rect_element.cc
@@ -166,7 +166,7 @@
 
 LayoutObject* SVGRectElement::CreateLayoutObject(const ComputedStyle&,
                                                  LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGRect>(this);
+  return new LayoutSVGRect(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_script_element.cc b/third_party/blink/renderer/core/svg/svg_script_element.cc
index 153028a..e47f4d0d 100644
--- a/third_party/blink/renderer/core/svg/svg_script_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_script_element.cc
@@ -22,6 +22,7 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/html_script_element_or_svg_script_element.h"
 #include "third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_htmlscriptelement_svgscriptelement.h"
 #include "third_party/blink/renderer/core/dom/attribute.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
@@ -170,12 +171,6 @@
   DispatchEvent(*Event::Create(event_type_names::kError));
 }
 
-void SVGScriptElement::SetScriptElementForBinding(
-    HTMLScriptElementOrSVGScriptElement& element) {
-  if (!IsInShadowTree())
-    element.SetSVGScriptElement(this);
-}
-
 ScriptElementBase::Type SVGScriptElement::GetScriptElementType() {
   return ScriptElementBase::Type::kSVGScriptElement;
 }
@@ -199,6 +194,20 @@
   return attribute_map;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8HTMLOrSVGScriptElement* SVGScriptElement::AsV8HTMLOrSVGScriptElement() {
+  if (IsInShadowTree())
+    return nullptr;
+  return MakeGarbageCollected<V8HTMLOrSVGScriptElement>(this);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void SVGScriptElement::SetScriptElementForBinding(
+    HTMLScriptElementOrSVGScriptElement& element) {
+  if (!IsInShadowTree())
+    element.SetSVGScriptElement(this);
+}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void SVGScriptElement::Trace(Visitor* visitor) const {
   visitor->Trace(loader_);
   SVGElement::Trace(visitor);
diff --git a/third_party/blink/renderer/core/svg/svg_script_element.h b/third_party/blink/renderer/core/svg/svg_script_element.h
index 9fa48a98..d57d992 100644
--- a/third_party/blink/renderer/core/svg/svg_script_element.h
+++ b/third_party/blink/renderer/core/svg/svg_script_element.h
@@ -52,6 +52,13 @@
 
   const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8HTMLOrSVGScriptElement* AsV8HTMLOrSVGScriptElement() override;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void SetScriptElementForBinding(
+      HTMLScriptElementOrSVGScriptElement&) override;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
   void Trace(Visitor*) const override;
 
  private:
@@ -98,8 +105,6 @@
   ExecutionContext* GetExecutionContext() const override;
   void DispatchLoadEvent() override;
   void DispatchErrorEvent() override;
-  void SetScriptElementForBinding(
-      HTMLScriptElementOrSVGScriptElement&) override;
 
   Type GetScriptElementType() override;
 
diff --git a/third_party/blink/renderer/core/svg/svg_svg_element.cc b/third_party/blink/renderer/core/svg/svg_svg_element.cc
index ba5f5be..c82f4a6 100644
--- a/third_party/blink/renderer/core/svg/svg_svg_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_svg_element.cc
@@ -514,9 +514,9 @@
                                                 LegacyLayout) {
   UseCounter::Count(GetDocument(), WebFeature::kLegacyLayoutBySVG);
   if (IsOutermostSVGSVGElement())
-    return MakeGarbageCollected<LayoutSVGRoot>(this);
+    return new LayoutSVGRoot(this);
 
-  return MakeGarbageCollected<LayoutSVGViewportContainer>(this);
+  return new LayoutSVGViewportContainer(this);
 }
 
 Node::InsertionNotificationRequest SVGSVGElement::InsertedInto(
diff --git a/third_party/blink/renderer/core/svg/svg_switch_element.cc b/third_party/blink/renderer/core/svg/svg_switch_element.cc
index 5f04948..f29a5f2 100644
--- a/third_party/blink/renderer/core/svg/svg_switch_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_switch_element.cc
@@ -34,7 +34,7 @@
 
 LayoutObject* SVGSwitchElement::CreateLayoutObject(const ComputedStyle&,
                                                    LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGTransformableContainer>(this);
+  return new LayoutSVGTransformableContainer(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_symbol_element.cc b/third_party/blink/renderer/core/svg/svg_symbol_element.cc
index 6b36eb5..8cf42a8 100644
--- a/third_party/blink/renderer/core/svg/svg_symbol_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_symbol_element.cc
@@ -41,7 +41,7 @@
 
 LayoutObject* SVGSymbolElement::CreateLayoutObject(const ComputedStyle&,
                                                    LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGHiddenContainer>(this);
+  return new LayoutSVGHiddenContainer(this);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_text_path_element.cc b/third_party/blink/renderer/core/svg/svg_text_path_element.cc
index f6e9907..f8149a62 100644
--- a/third_party/blink/renderer/core/svg/svg_text_path_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_text_path_element.cc
@@ -113,7 +113,7 @@
 
 LayoutObject* SVGTextPathElement::CreateLayoutObject(const ComputedStyle&,
                                                      LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGTextPath>(this);
+  return new LayoutSVGTextPath(this);
 }
 
 bool SVGTextPathElement::LayoutObjectIsNeeded(
diff --git a/third_party/blink/renderer/core/svg/svg_tspan_element.cc b/third_party/blink/renderer/core/svg/svg_tspan_element.cc
index b61b029..fe7442b 100644
--- a/third_party/blink/renderer/core/svg/svg_tspan_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_tspan_element.cc
@@ -30,7 +30,7 @@
 
 LayoutObject* SVGTSpanElement::CreateLayoutObject(const ComputedStyle&,
                                                   LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGTSpan>(this);
+  return new LayoutSVGTSpan(this);
 }
 
 bool SVGTSpanElement::LayoutObjectIsNeeded(const ComputedStyle& style) const {
diff --git a/third_party/blink/renderer/core/svg/svg_use_element.cc b/third_party/blink/renderer/core/svg/svg_use_element.cc
index c29d00c..3f15628f 100644
--- a/third_party/blink/renderer/core/svg/svg_use_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_use_element.cc
@@ -476,7 +476,7 @@
 
 LayoutObject* SVGUseElement::CreateLayoutObject(const ComputedStyle& style,
                                                 LegacyLayout) {
-  return MakeGarbageCollected<LayoutSVGTransformableContainer>(this);
+  return new LayoutSVGTransformableContainer(this);
 }
 
 static bool IsDirectReference(const SVGElement& element) {
diff --git a/third_party/blink/renderer/core/testing/page_test_base.cc b/third_party/blink/renderer/core/testing/page_test_base.cc
index c0cf4f3..58db5bd 100644
--- a/third_party/blink/renderer/core/testing/page_test_base.cc
+++ b/third_party/blink/renderer/core/testing/page_test_base.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_array_buffer_or_array_buffer_view.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_font_face_descriptors.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview_string.h"
 #include "third_party/blink/renderer/core/css/font_face_set_document.h"
 #include "third_party/blink/renderer/core/frame/csp/conversion_util.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -165,9 +166,15 @@
   Document& document = *frame.DomWindow()->document();
   scoped_refptr<SharedBuffer> shared_buffer =
       test::ReadFromFile(test::CoreTestDataPath("Ahem.ttf"));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* buffer =
+      MakeGarbageCollected<V8UnionArrayBufferOrArrayBufferViewOrString>(
+          DOMArrayBuffer::Create(shared_buffer));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrArrayBufferOrArrayBufferView buffer =
       StringOrArrayBufferOrArrayBufferView::FromArrayBuffer(
           DOMArrayBuffer::Create(shared_buffer));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   FontFace* ahem = FontFace::Create(frame.DomWindow(), "Ahem", buffer,
                                     FontFaceDescriptors::Create());
 
diff --git a/third_party/blink/renderer/core/testing/record_test.cc b/third_party/blink/renderer/core/testing/record_test.cc
index 12e57079..2b37a50 100644
--- a/third_party/blink/renderer/core/testing/record_test.cc
+++ b/third_party/blink/renderer/core/testing/record_test.cc
@@ -4,6 +4,8 @@
 
 #include "third_party/blink/renderer/core/testing/record_test.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_boolean_bytestringbytestringrecord.h"
+
 namespace blink {
 
 RecordTest::RecordTest() = default;
@@ -71,10 +73,17 @@
   return record;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+bool RecordTest::unionReceivedARecord(
+    const V8UnionBooleanOrByteStringByteStringRecord* arg) {
+  return arg->IsByteStringByteStringRecord();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 bool RecordTest::unionReceivedARecord(
     const BooleanOrByteStringByteStringRecord& arg) {
   return arg.IsByteStringByteStringRecord();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void RecordTest::Trace(Visitor* visitor) const {
   visitor->Trace(string_element_record_);
diff --git a/third_party/blink/renderer/core/testing/record_test.h b/third_party/blink/renderer/core/testing/record_test.h
index 068d648..f3703651 100644
--- a/third_party/blink/renderer/core/testing/record_test.h
+++ b/third_party/blink/renderer/core/testing/record_test.h
@@ -17,6 +17,9 @@
 
 namespace blink {
 
+class V8UnionBooleanOrByteStringByteStringRecord;
+class V8UnionFloatOrStringElementRecord;
+
 class RecordTest final : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
 
@@ -48,9 +51,19 @@
   Vector<std::pair<String, Vector<String>>>
   returnStringByteStringSequenceRecord();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  bool unionReceivedARecord(
+      const V8UnionBooleanOrByteStringByteStringRecord* arg);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool unionReceivedARecord(const BooleanOrByteStringByteStringRecord& arg);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void setFloatOrStringElementRecord(const V8UnionFloatOrStringElementRecord*) {
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void setFloatOrStringElementRecord(const FloatOrStringElementRecord&) {}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/core/testing/sequence_test.cc b/third_party/blink/renderer/core/testing/sequence_test.cc
index cd8d81ba..b35916ef 100644
--- a/third_party/blink/renderer/core/testing/sequence_test.cc
+++ b/third_party/blink/renderer/core/testing/sequence_test.cc
@@ -4,6 +4,8 @@
 
 #include "third_party/blink/renderer/core/testing/sequence_test.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_doublesequence.h"
+
 namespace blink {
 
 SequenceTest::SequenceTest() = default;
@@ -43,9 +45,16 @@
   element_sequence_ = arg;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+bool SequenceTest::unionReceivedSequence(
+    const V8UnionDoubleOrDoubleSequence* arg) {
+  return arg->IsDoubleSequence();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 bool SequenceTest::unionReceivedSequence(const DoubleOrDoubleSequence& arg) {
   return arg.IsDoubleSequence();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void SequenceTest::Trace(Visitor* visitor) const {
   visitor->Trace(element_sequence_);
diff --git a/third_party/blink/renderer/core/testing/sequence_test.h b/third_party/blink/renderer/core/testing/sequence_test.h
index 870953c..dc5c128 100644
--- a/third_party/blink/renderer/core/testing/sequence_test.h
+++ b/third_party/blink/renderer/core/testing/sequence_test.h
@@ -16,6 +16,8 @@
 
 namespace blink {
 
+class V8UnionDoubleOrDoubleSequence;
+
 class SequenceTest final : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
 
@@ -35,7 +37,11 @@
   HeapVector<Member<Element>> getElementSequence() const;
   void setElementSequence(const HeapVector<Member<Element>>& arg);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  bool unionReceivedSequence(const V8UnionDoubleOrDoubleSequence* arg);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool unionReceivedSequence(const DoubleOrDoubleSequence& arg);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/core/testing/union_types_test.cc b/third_party/blink/renderer/core/testing/union_types_test.cc
index 4e936b4a..487e7f2 100644
--- a/third_party/blink/renderer/core/testing/union_types_test.cc
+++ b/third_party/blink/renderer/core/testing/union_types_test.cc
@@ -4,10 +4,159 @@
 
 #include "third_party/blink/renderer/core/testing/union_types_test.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_internalenum.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_string.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_string_stringsequence.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_element_nodelist.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
 namespace blink {
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionDoubleOrStringOrStringSequence*
+UnionTypesTest::doubleOrStringOrStringSequenceAttribute() const {
+  switch (attribute_type_) {
+    case kSpecificTypeDouble:
+      return MakeGarbageCollected<V8UnionDoubleOrStringOrStringSequence>(
+          attribute_double_);
+    case kSpecificTypeString:
+      return MakeGarbageCollected<V8UnionDoubleOrStringOrStringSequence>(
+          attribute_string_);
+    case kSpecificTypeStringSequence:
+      return MakeGarbageCollected<V8UnionDoubleOrStringOrStringSequence>(
+          attribute_string_sequence_);
+  }
+  NOTREACHED();
+  return nullptr;
+}
+
+void UnionTypesTest::setDoubleOrStringOrStringSequenceAttribute(
+    const V8UnionDoubleOrStringOrStringSequence* value) {
+  DCHECK(value);
+
+  switch (value->GetContentType()) {
+    case V8UnionDoubleOrStringOrStringSequence::ContentType::kDouble:
+      attribute_double_ = value->GetAsDouble();
+      attribute_type_ = kSpecificTypeDouble;
+      break;
+    case V8UnionDoubleOrStringOrStringSequence::ContentType::kString:
+      attribute_string_ = value->GetAsString();
+      attribute_type_ = kSpecificTypeString;
+      break;
+    case V8UnionDoubleOrStringOrStringSequence::ContentType::kStringSequence:
+      attribute_string_sequence_ = value->GetAsStringSequence();
+      attribute_type_ = kSpecificTypeStringSequence;
+      break;
+  }
+}
+
+String UnionTypesTest::doubleOrStringArg(V8UnionDoubleOrString* arg) {
+  if (!arg)
+    return "null is passed";
+
+  switch (arg->GetContentType()) {
+    case V8UnionDoubleOrString::ContentType::kDouble:
+      return "double is passed: " +
+             String::NumberToStringECMAScript(arg->GetAsDouble());
+    case V8UnionDoubleOrString::ContentType::kString:
+      return "string is passed: " + arg->GetAsString();
+  }
+
+  NOTREACHED();
+  return String();
+}
+
+String UnionTypesTest::doubleOrInternalEnumArg(
+    V8UnionDoubleOrInternalEnum* arg) {
+  DCHECK(arg);
+
+  switch (arg->GetContentType()) {
+    case V8UnionDoubleOrInternalEnum::ContentType::kDouble:
+      return "double is passed: " +
+             String::NumberToStringECMAScript(arg->GetAsDouble());
+    case V8UnionDoubleOrInternalEnum::ContentType::kInternalEnum:
+      return "InternalEnum is passed: " + arg->GetAsInternalEnum().AsString();
+  }
+
+  NOTREACHED();
+  return String();
+}
+
+String UnionTypesTest::doubleOrStringSequenceArg(
+    HeapVector<Member<V8UnionDoubleOrString>>& sequence) {
+  StringBuilder builder;
+  for (auto& double_or_string : sequence) {
+    DCHECK(double_or_string);
+    if (!builder.IsEmpty())
+      builder.Append(", ");
+    switch (double_or_string->GetContentType()) {
+      case V8UnionDoubleOrString::ContentType::kDouble:
+        builder.Append("double: ");
+        builder.Append(
+            String::NumberToStringECMAScript(double_or_string->GetAsDouble()));
+        break;
+      case V8UnionDoubleOrString::ContentType::kString:
+        builder.Append("string: ");
+        builder.Append(double_or_string->GetAsString());
+        break;
+    }
+  }
+  return builder.ToString();
+}
+
+String UnionTypesTest::nodeListOrElementArg(
+    const V8UnionElementOrNodeList* arg) {
+  DCHECK(arg);
+  return nodeListOrElementOrNullArg(arg);
+}
+
+String UnionTypesTest::nodeListOrElementOrNullArg(
+    const V8UnionElementOrNodeList* arg) {
+  if (!arg)
+    return "null or undefined is passed";
+
+  switch (arg->GetContentType()) {
+    case V8UnionElementOrNodeList::ContentType::kElement:
+      return "element is passed";
+    case V8UnionElementOrNodeList::ContentType::kNodeList:
+      return "nodelist is passed";
+  }
+
+  NOTREACHED();
+  return String();
+}
+
+String UnionTypesTest::doubleOrStringOrStringSequenceArg(
+    const V8UnionDoubleOrStringOrStringSequence* arg) {
+  if (!arg)
+    return "null";
+
+  switch (arg->GetContentType()) {
+    case V8UnionDoubleOrStringOrStringSequence::ContentType::kDouble:
+      return "double: " + String::NumberToStringECMAScript(arg->GetAsDouble());
+    case V8UnionDoubleOrStringOrStringSequence::ContentType::kString:
+      return "string: " + arg->GetAsString();
+    case V8UnionDoubleOrStringOrStringSequence::ContentType::kStringSequence: {
+      StringBuilder builder;
+      builder.Append("sequence: [");
+      bool is_first = true;
+      for (const String& item : arg->GetAsStringSequence()) {
+        DCHECK(!item.IsNull());
+        if (is_first)
+          is_first = false;
+        else
+          builder.Append(", ");
+        builder.Append(item);
+      }
+      builder.Append("]");
+      return builder.ToString();
+    }
+  }
+
+  NOTREACHED();
+  return String();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void UnionTypesTest::doubleOrStringOrStringSequenceAttribute(
     DoubleOrStringOrStringSequence& double_or_string_or_string_sequence) {
   switch (attribute_type_) {
@@ -142,5 +291,6 @@
   }
   return builder.Substring(0, builder.length() - 2) + "]";
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/testing/union_types_test.h b/third_party/blink/renderer/core/testing/union_types_test.h
index 1ab8319..fa98653 100644
--- a/third_party/blink/renderer/core/testing/union_types_test.h
+++ b/third_party/blink/renderer/core/testing/union_types_test.h
@@ -13,13 +13,35 @@
 
 namespace blink {
 
+class V8UnionDoubleOrInternalEnum;
+class V8UnionDoubleOrString;
+class V8UnionDoubleOrStringOrStringSequence;
+class V8UnionElementOrNodeList;
+
 class UnionTypesTest final : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  UnionTypesTest() : attribute_type_(kSpecificTypeNone) {}
+  UnionTypesTest() = default;
   ~UnionTypesTest() override = default;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionDoubleOrStringOrStringSequence*
+  doubleOrStringOrStringSequenceAttribute() const;
+  void setDoubleOrStringOrStringSequenceAttribute(
+      const V8UnionDoubleOrStringOrStringSequence* value);
+
+  String doubleOrStringArg(V8UnionDoubleOrString* arg);
+  String doubleOrInternalEnumArg(V8UnionDoubleOrInternalEnum* arg);
+  String doubleOrStringSequenceArg(
+      HeapVector<Member<V8UnionDoubleOrString>>& sequence);
+
+  String nodeListOrElementArg(const V8UnionElementOrNodeList* arg);
+  String nodeListOrElementOrNullArg(const V8UnionElementOrNodeList* arg);
+
+  String doubleOrStringOrStringSequenceArg(
+      const V8UnionDoubleOrStringOrStringSequence* arg);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void doubleOrStringOrStringSequenceAttribute(DoubleOrStringOrStringSequence&);
   void setDoubleOrStringOrStringSequenceAttribute(
       const DoubleOrStringOrStringSequence&);
@@ -33,16 +55,19 @@
 
   String doubleOrStringOrStringSequenceArg(
       const DoubleOrStringOrStringSequence&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
  private:
   enum AttributeSpecificType {
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     kSpecificTypeNone,
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     kSpecificTypeDouble,
     kSpecificTypeString,
     kSpecificTypeStringSequence,
   };
-  AttributeSpecificType attribute_type_;
-  double attribute_double_;
+  AttributeSpecificType attribute_type_ = kSpecificTypeDouble;
+  double attribute_double_ = 0.;
   String attribute_string_;
   Vector<String> attribute_string_sequence_;
 };
diff --git a/third_party/blink/renderer/core/timing/performance.cc b/third_party/blink/renderer/core/timing/performance.cc
index 735e988..a8157ea 100644
--- a/third_party/blink/renderer/core/timing/performance.cc
+++ b/third_party/blink/renderer/core/timing/performance.cc
@@ -48,6 +48,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_performance_measure_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_profiler_init_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_string.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_performancemeasureoptions_string.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/document_timing.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -127,6 +129,32 @@
       .Record(execution_context->UkmRecorder());
 }
 
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionPerformanceMeasureOptionsOrString*
+StringOrPerformanceMeasureOptionsToNewV8Union(
+    const StringOrPerformanceMeasureOptions& value) {
+  if (value.IsString()) {
+    return MakeGarbageCollected<V8UnionPerformanceMeasureOptionsOrString>(
+        value.GetAsString());
+  }
+  if (value.IsPerformanceMeasureOptions()) {
+    return MakeGarbageCollected<V8UnionPerformanceMeasureOptionsOrString>(
+        value.GetAsPerformanceMeasureOptions());
+  }
+  return nullptr;
+}
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+// TODO(crbug.com/1181288): Remove the old IDL union version.
+V8UnionDoubleOrString* StringOrDoubleToV8UnionDoubleOrString(
+    const StringOrDouble& value) {
+  if (value.IsString())
+    return MakeGarbageCollected<V8UnionDoubleOrString>(value.GetAsString());
+  if (value.IsDouble())
+    return MakeGarbageCollected<V8UnionDoubleOrString>(value.GetAsDouble());
+  return nullptr;
+}
+
 }  // namespace
 
 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>;
@@ -818,31 +846,55 @@
                                          ExceptionState& exception_state) {
   // When |startOrOptions| is not provided, it's assumed to be an empty
   // dictionary.
-  return MeasureInternal(
-      script_state, measure_name,
-      StringOrPerformanceMeasureOptions::FromPerformanceMeasureOptions(
-          PerformanceMeasureOptions::Create()),
-      base::nullopt, exception_state);
+  return MeasureInternal(script_state, measure_name, nullptr, base::nullopt,
+                         exception_state);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+PerformanceMeasure* Performance::measure(
+    ScriptState* script_state,
+    const AtomicString& measure_name,
+    const V8UnionPerformanceMeasureOptionsOrString* start_or_options,
+    ExceptionState& exception_state) {
+  return MeasureInternal(script_state, measure_name, start_or_options,
+                         base::nullopt, exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 PerformanceMeasure* Performance::measure(
     ScriptState* script_state,
     const AtomicString& measure_name,
     const StringOrPerformanceMeasureOptions& start_or_options,
     ExceptionState& exception_state) {
-  return MeasureInternal(script_state, measure_name, start_or_options,
-                         base::nullopt, exception_state);
+  return MeasureInternal(
+      script_state, measure_name,
+      StringOrPerformanceMeasureOptionsToNewV8Union(start_or_options),
+      base::nullopt, exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+PerformanceMeasure* Performance::measure(
+    ScriptState* script_state,
+    const AtomicString& measure_name,
+    const V8UnionPerformanceMeasureOptionsOrString* start_or_options,
+    const String& end,
+    ExceptionState& exception_state) {
+  return MeasureInternal(script_state, measure_name, start_or_options,
+                         base::Optional<String>(end), exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 PerformanceMeasure* Performance::measure(
     ScriptState* script_state,
     const AtomicString& measure_name,
     const StringOrPerformanceMeasureOptions& start_or_options,
     const String& end,
     ExceptionState& exception_state) {
-  return MeasureInternal(script_state, measure_name, start_or_options,
-                         base::Optional<String>(end), exception_state);
+  return MeasureInternal(
+      script_state, measure_name,
+      StringOrPerformanceMeasureOptionsToNewV8Union(start_or_options),
+      base::Optional<String>(end), exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 // |MeasureInternal| exists to unify the arguments from different
 // `performance.measure()` overloads into a consistent form, then delegate to
@@ -863,14 +915,13 @@
 PerformanceMeasure* Performance::MeasureInternal(
     ScriptState* script_state,
     const AtomicString& measure_name,
-    const StringOrPerformanceMeasureOptions& start_or_options,
+    const V8UnionPerformanceMeasureOptionsOrString* start_or_options,
     base::Optional<String> end_mark,
     ExceptionState& exception_state) {
-  DCHECK(!start_or_options.IsNull());
   // An empty option is treated with no difference as null, undefined.
-  if (start_or_options.IsPerformanceMeasureOptions() &&
+  if (start_or_options && start_or_options->IsPerformanceMeasureOptions() &&
       !IsMeasureOptionsEmpty(
-          *start_or_options.GetAsPerformanceMeasureOptions())) {
+          *start_or_options->GetAsPerformanceMeasureOptions())) {
     UseCounter::Count(GetExecutionContext(), WebFeature::kUserTimingL3);
     // measure("name", { start, end }, *)
     if (end_mark) {
@@ -880,7 +931,7 @@
       return nullptr;
     }
     const PerformanceMeasureOptions* options =
-        start_or_options.GetAsPerformanceMeasureOptions();
+        start_or_options->GetAsPerformanceMeasureOptions();
     if (!options->hasStart() && !options->hasEnd()) {
       exception_state.ThrowTypeError(
           "If a non-empty PerformanceMeasureOptions object was passed, at "
@@ -896,17 +947,17 @@
       return nullptr;
     }
 
-    base::Optional<StringOrDouble> start;
+    V8UnionDoubleOrString* start = nullptr;
     if (options->hasStart()) {
-      start = options->start();
+      start = StringOrDoubleToV8UnionDoubleOrString(options->start());
     }
     base::Optional<double> duration;
     if (options->hasDuration()) {
       duration = options->duration();
     }
-    base::Optional<StringOrDouble> end;
+    V8UnionDoubleOrString* end = nullptr;
     if (options->hasEnd()) {
-      end = options->end();
+      end = StringOrDoubleToV8UnionDoubleOrString(options->end());
     }
 
     return MeasureWithDetail(
@@ -916,15 +967,16 @@
   }
 
   // measure("name", "mark1", *)
-  base::Optional<StringOrDouble> start;
-  if (start_or_options.IsString()) {
-    start = StringOrDouble::FromString(start_or_options.GetAsString());
+  V8UnionDoubleOrString* start = nullptr;
+  if (start_or_options && start_or_options->IsString()) {
+    start = MakeGarbageCollected<V8UnionDoubleOrString>(
+        start_or_options->GetAsString());
   }
   // We let |end_mark| behave the same whether it's empty, undefined or null
   // in JS, as long as |end_mark| is null in C++.
-  base::Optional<StringOrDouble> end;
+  V8UnionDoubleOrString* end = nullptr;
   if (end_mark) {
-    end = StringOrDouble::FromString(*end_mark);
+    end = MakeGarbageCollected<V8UnionDoubleOrString>(*end_mark);
   }
   return MeasureWithDetail(script_state, measure_name, start,
                            /* duration = */ base::nullopt, end,
@@ -935,9 +987,9 @@
 PerformanceMeasure* Performance::MeasureWithDetail(
     ScriptState* script_state,
     const AtomicString& measure_name,
-    const base::Optional<StringOrDouble>& start,
+    const V8UnionDoubleOrString* start,
     const base::Optional<double>& duration,
-    const base::Optional<StringOrDouble>& end,
+    const V8UnionDoubleOrString* end,
     const ScriptValue& detail,
     ExceptionState& exception_state) {
   PerformanceMeasure* performance_measure =
diff --git a/third_party/blink/renderer/core/timing/performance.h b/third_party/blink/renderer/core/timing/performance.h
index 54f3a7d..d25b193 100644
--- a/third_party/blink/renderer/core/timing/performance.h
+++ b/third_party/blink/renderer/core/timing/performance.h
@@ -83,6 +83,8 @@
 class StringOrPerformanceMeasureOptions;
 class UserTiming;
 class V8ObjectBuilder;
+class V8UnionDoubleOrString;
+class V8UnionPerformanceMeasureOptionsOrString;
 
 using PerformanceEntryVector = HeapVector<Member<PerformanceEntry>>;
 using PerformanceEntryDeque = HeapDeque<Member<PerformanceEntry>>;
@@ -266,18 +268,35 @@
                               const AtomicString& measure_name,
                               ExceptionState&);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  PerformanceMeasure* measure(
+      ScriptState* script_state,
+      const AtomicString& measure_name,
+      const V8UnionPerformanceMeasureOptionsOrString* start_or_options,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   PerformanceMeasure* measure(
       ScriptState*,
       const AtomicString& measure_name,
       const StringOrPerformanceMeasureOptions& start_or_options,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  PerformanceMeasure* measure(
+      ScriptState* script_state,
+      const AtomicString& measure_name,
+      const V8UnionPerformanceMeasureOptionsOrString* start_or_options,
+      const String& end,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   PerformanceMeasure* measure(
       ScriptState*,
       const AtomicString& measure_name,
       const StringOrPerformanceMeasureOptions& start_or_options,
       const String& end,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void clearMeasures(const AtomicString& measure_name);
   void clearMeasures() { return clearMeasures(AtomicString()); }
@@ -334,20 +353,19 @@
                       base::TimeTicks start_time);
 
   PerformanceMeasure* MeasureInternal(
-      ScriptState*,
+      ScriptState* script_state,
       const AtomicString& measure_name,
-      const StringOrPerformanceMeasureOptions& start,
+      const V8UnionPerformanceMeasureOptionsOrString* start_or_options,
       base::Optional<String> end_mark,
-      ExceptionState&);
+      ExceptionState& exception_state);
 
-  PerformanceMeasure* MeasureWithDetail(
-      ScriptState*,
-      const AtomicString& measure_name,
-      const base::Optional<StringOrDouble>& start,
-      const base::Optional<double>& duration,
-      const base::Optional<StringOrDouble>& end,
-      const ScriptValue& detail,
-      ExceptionState&);
+  PerformanceMeasure* MeasureWithDetail(ScriptState* script_state,
+                                        const AtomicString& measure_name,
+                                        const V8UnionDoubleOrString* start,
+                                        const base::Optional<double>& duration,
+                                        const V8UnionDoubleOrString* end,
+                                        const ScriptValue& detail,
+                                        ExceptionState& exception_state);
 
   void CopySecondaryBuffer();
   PerformanceEntryVector getEntriesByTypeInternal(
diff --git a/third_party/blink/renderer/core/timing/performance_user_timing.cc b/third_party/blink/renderer/core/timing/performance_user_timing.cc
index 4877fff1..31c49093 100644
--- a/third_party/blink/renderer/core/timing/performance_user_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_user_timing.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/core/timing/performance_user_timing.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_string.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/performance_entry_names.h"
 #include "third_party/blink/renderer/core/timing/performance_mark.h"
@@ -141,30 +142,38 @@
   return value - timing->navigationStart();
 }
 
-double UserTiming::GetTimeOrFindMarkTime(const AtomicString& measure_name,
-                                         const StringOrDouble& mark_or_time,
-                                         ExceptionState& exception_state) {
-  if (mark_or_time.IsString()) {
-    return FindExistingMarkStartTime(AtomicString(mark_or_time.GetAsString()),
-                                     exception_state);
+double UserTiming::GetTimeOrFindMarkTime(
+    const AtomicString& measure_name,
+    const V8UnionDoubleOrString* mark_or_time,
+    ExceptionState& exception_state) {
+  DCHECK(mark_or_time);
+
+  switch (mark_or_time->GetContentType()) {
+    case V8UnionDoubleOrString::ContentType::kDouble: {
+      const double time = mark_or_time->GetAsDouble();
+      if (time < 0.0) {
+        exception_state.ThrowTypeError("'" + measure_name +
+                                       "' cannot have a negative time stamp.");
+      }
+      return time;
+    }
+    case V8UnionDoubleOrString::ContentType::kString:
+      return FindExistingMarkStartTime(
+          AtomicString(mark_or_time->GetAsString()), exception_state);
   }
-  DCHECK(mark_or_time.IsDouble());
-  const double time = mark_or_time.GetAsDouble();
-  if (time < 0.0) {
-    exception_state.ThrowTypeError("'" + measure_name +
-                                   "' cannot have a negative time stamp.");
-  }
-  return time;
+
+  NOTREACHED();
+  return 0;
 }
 
 base::TimeTicks UserTiming::GetPerformanceMarkUnsafeTimeForTraces(
     double start_time,
-    const base::Optional<StringOrDouble>& maybe_mark_name) {
-  if (maybe_mark_name.has_value() && maybe_mark_name.value().IsString()) {
+    const V8UnionDoubleOrString* maybe_mark_name) {
+  if (maybe_mark_name && maybe_mark_name->IsString()) {
     const PerformanceMark* mark =
-        FindExistingMark(AtomicString(maybe_mark_name.value().GetAsString()));
+        FindExistingMark(AtomicString(maybe_mark_name->GetAsString()));
     if (mark) {
-      return (mark->UnsafeTimeForTraces());
+      return mark->UnsafeTimeForTraces();
     }
   }
 
@@ -178,24 +187,20 @@
                                        start_time_in_seconds);
 }
 
-PerformanceMeasure* UserTiming::Measure(
-    ScriptState* script_state,
-    const AtomicString& measure_name,
-    const base::Optional<StringOrDouble>& start,
-    const base::Optional<double>& duration,
-    const base::Optional<StringOrDouble>& end,
-    const ScriptValue& detail,
-    ExceptionState& exception_state) {
+PerformanceMeasure* UserTiming::Measure(ScriptState* script_state,
+                                        const AtomicString& measure_name,
+                                        const V8UnionDoubleOrString* start,
+                                        const base::Optional<double>& duration,
+                                        const V8UnionDoubleOrString* end,
+                                        const ScriptValue& detail,
+                                        ExceptionState& exception_state) {
   double start_time =
-      start.has_value()
-          ? GetTimeOrFindMarkTime(measure_name, start.value(), exception_state)
-          : 0;
+      start ? GetTimeOrFindMarkTime(measure_name, start, exception_state) : 0;
   if (exception_state.HadException())
     return nullptr;
 
   double end_time =
-      end.has_value()
-          ? GetTimeOrFindMarkTime(measure_name, end.value(), exception_state)
+      end ? GetTimeOrFindMarkTime(measure_name, end, exception_state)
           : performance_->now();
   if (exception_state.HadException())
     return nullptr;
diff --git a/third_party/blink/renderer/core/timing/performance_user_timing.h b/third_party/blink/renderer/core/timing/performance_user_timing.h
index 4dcd036..cb350c1 100644
--- a/third_party/blink/renderer/core/timing/performance_user_timing.h
+++ b/third_party/blink/renderer/core/timing/performance_user_timing.h
@@ -35,6 +35,7 @@
 
 class ExceptionState;
 class Performance;
+class V8UnionDoubleOrString;
 
 using PerformanceEntryMap =
     HeapHashMap<AtomicString, Member<PerformanceEntryVector>>;
@@ -47,9 +48,9 @@
 
   PerformanceMeasure* Measure(ScriptState*,
                               const AtomicString& measure_name,
-                              const base::Optional<StringOrDouble>& start,
+                              const V8UnionDoubleOrString* start,
                               const base::Optional<double>& duration,
-                              const base::Optional<StringOrDouble>& end,
+                              const V8UnionDoubleOrString* end,
                               const ScriptValue& detail,
                               ExceptionState&);
   void ClearMeasures(const AtomicString& measure_name);
@@ -67,11 +68,11 @@
   const PerformanceMark* FindExistingMark(const AtomicString& mark_name);
   base::TimeTicks GetPerformanceMarkUnsafeTimeForTraces(
       double start_time,
-      const base::Optional<StringOrDouble>& maybe_mark_name);
+      const V8UnionDoubleOrString* maybe_mark_name);
   double FindExistingMarkStartTime(const AtomicString& mark_name,
                                    ExceptionState&);
   double GetTimeOrFindMarkTime(const AtomicString& measure_name,
-                               const StringOrDouble& mark_or_time,
+                               const V8UnionDoubleOrString* mark_or_time,
                                ExceptionState&);
 
   Member<Performance> performance_;
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
index 1cd7ca8..3d5b850 100644
--- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
@@ -10,7 +10,11 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html_or_trusted_script_or_trusted_script_url.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
+#include "third_party/blink/renderer/bindings/core/v8/string_treat_null_as_empty_string_or_trusted_script.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_trustedhtml_trustedscript_trustedscripturl.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_trustedscript.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_stringtreatnullasemptystring_trustedscript.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
@@ -452,6 +456,42 @@
   return result->toString();
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+String TrustedTypesCheckFor(SpecificTrustedType type,
+                            const V8TrustedString* trusted,
+                            const ExecutionContext* execution_context,
+                            ExceptionState& exception_state) {
+  DCHECK(trusted);
+
+  // Whatever happens below, we will need the string value:
+  String value;
+  bool does_type_match = false;
+  switch (trusted->GetContentType()) {
+    case V8TrustedString::ContentType::kString:
+      value = trusted->GetAsString();
+      break;
+    case V8TrustedString::ContentType::kTrustedHTML:
+      value = trusted->GetAsTrustedHTML()->toString();
+      does_type_match = type == SpecificTrustedType::kHTML;
+      break;
+    case V8TrustedString::ContentType::kTrustedScript:
+      value = trusted->GetAsTrustedScript()->toString();
+      does_type_match = type == SpecificTrustedType::kScript;
+      break;
+    case V8TrustedString::ContentType::kTrustedScriptURL:
+      value = trusted->GetAsTrustedScriptURL()->toString();
+      does_type_match = type == SpecificTrustedType::kScriptURL;
+      break;
+  }
+
+  if (type == SpecificTrustedType::kNone || does_type_match)
+    return value;
+
+  // In all other cases: run the full check against the string value.
+  return TrustedTypesCheckFor(type, std::move(value), execution_context,
+                              exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 String TrustedTypesCheckFor(
     SpecificTrustedType type,
     const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL& trusted,
@@ -482,8 +522,65 @@
   return TrustedTypesCheckFor(type, std::move(value), execution_context,
                               exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
-String TrustedTypesCheckForScript(StringOrTrustedScript trusted,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+String TrustedTypesCheckForScript(const V8UnionStringOrTrustedScript* value,
+                                  const ExecutionContext* execution_context,
+                                  ExceptionState& exception_state) {
+  // To remain compatible with legacy behaviour, HTMLElement uses extended IDL
+  // attributes to allow for nullable union of (DOMString or TrustedScript).
+  // Thus, this method is required to handle the case where |!value|, unlike
+  // the various similar methods in this file.
+  if (!value) {
+    return TrustedTypesCheckForScript(g_empty_string, execution_context,
+                                      exception_state);
+  }
+
+  switch (value->GetContentType()) {
+    case V8UnionStringOrTrustedScript::ContentType::kString:
+      return TrustedTypesCheckForScript(value->GetAsString(), execution_context,
+                                        exception_state);
+    case V8UnionStringOrTrustedScript::ContentType::kTrustedScript:
+      return value->GetAsTrustedScript()->toString();
+  }
+
+  NOTREACHED();
+  return String();
+}
+
+String TrustedTypesCheckForScript(
+    const V8UnionStringTreatNullAsEmptyStringOrTrustedScript* value,
+    const ExecutionContext* execution_context,
+    ExceptionState& exception_state) {
+  // To remain compatible with legacy behaviour, HTMLElement uses extended IDL
+  // attributes to allow for nullable union of (DOMString or TrustedScript).
+  // Thus, this method is required to handle the case where |!value|, unlike
+  // the various similar methods in this file.
+  if (!value) {
+    return TrustedTypesCheckForScript(g_empty_string, execution_context,
+                                      exception_state);
+  }
+
+  switch (value->GetContentType()) {
+    case V8UnionStringTreatNullAsEmptyStringOrTrustedScript::ContentType::
+        kStringTreatNullAsEmptyString:
+      return TrustedTypesCheckForScript(
+          value->GetAsStringTreatNullAsEmptyString(), execution_context,
+          exception_state);
+    case V8UnionStringTreatNullAsEmptyStringOrTrustedScript::ContentType::
+        kTrustedScript:
+      return value->GetAsTrustedScript()->toString();
+  }
+
+  NOTREACHED();
+  return String();
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+String TrustedTypesCheckForScript(const StringOrTrustedScript& trusted,
                                   const ExecutionContext* execution_context,
                                   ExceptionState& exception_state) {
   // To remain compatible with legacy behaviour, HTMLElement uses extended IDL
@@ -495,12 +592,35 @@
     return trusted.GetAsTrustedScript()->toString();
   }
   if (trusted.IsNull()) {
-    trusted = StringOrTrustedScript::FromString(g_empty_string);
+    return TrustedTypesCheckForScript(g_empty_string, execution_context,
+                                      exception_state);
   }
   return TrustedTypesCheckForScript(trusted.GetAsString(), execution_context,
                                     exception_state);
 }
 
+String TrustedTypesCheckForScript(
+    const StringTreatNullAsEmptyStringOrTrustedScript& trusted,
+    const ExecutionContext* execution_context,
+    ExceptionState& exception_state) {
+  // To remain compatible with legacy behaviour, HTMLElement uses extended IDL
+  // attributes to allow for nullable union of (DOMString or TrustedScript).
+  // Thus, this method is required to handle the case where
+  // string_or_trusted_script.IsNull(), unlike the various similar methods in
+  // this file.
+  if (trusted.IsTrustedScript()) {
+    return trusted.GetAsTrustedScript()->toString();
+  }
+  if (trusted.IsNull()) {
+    return TrustedTypesCheckForScript(g_empty_string, execution_context,
+                                      exception_state);
+  }
+  return TrustedTypesCheckForScript(trusted.GetAsString(), execution_context,
+                                    exception_state);
+}
+
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 String TrustedTypesCheckFor(SpecificTrustedType type,
                             String trusted,
                             const ExecutionContext* execution_context,
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h
index 8b07373a..9082c38 100644
--- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h
@@ -5,16 +5,20 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPES_UTIL_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPES_UTIL_H_
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/script/script_element_base.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
 
-class ExecutionContext;
 class ExceptionState;
+class ExecutionContext;
 class StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL;
 class StringOrTrustedScript;
+class StringTreatNullAsEmptyStringOrTrustedScript;
+class V8UnionStringOrTrustedScript;
+class V8UnionStringTreatNullAsEmptyStringOrTrustedScript;
 
 enum class SpecificTrustedType {
   kNone,
@@ -25,15 +29,38 @@
 
 // Perform Trusted Type checks, with the IDL union types as input. All of these
 // will call String& versions below to do the heavy lifting.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CORE_EXPORT String
+TrustedTypesCheckFor(SpecificTrustedType type,
+                     const V8TrustedString* trusted,
+                     const ExecutionContext* execution_context,
+                     ExceptionState& exception_state) WARN_UNUSED_RESULT;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CORE_EXPORT String TrustedTypesCheckFor(
     SpecificTrustedType,
     const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&,
     const ExecutionContext*,
     ExceptionState&) WARN_UNUSED_RESULT;
-CORE_EXPORT String TrustedTypesCheckForScript(StringOrTrustedScript,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CORE_EXPORT String
+TrustedTypesCheckForScript(const V8UnionStringOrTrustedScript* value,
+                           const ExecutionContext* execution_context,
+                           ExceptionState& exception_state) WARN_UNUSED_RESULT;
+CORE_EXPORT String TrustedTypesCheckForScript(
+    const V8UnionStringTreatNullAsEmptyStringOrTrustedScript* value,
+    const ExecutionContext* execution_context,
+    ExceptionState& exception_state) WARN_UNUSED_RESULT;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CORE_EXPORT String TrustedTypesCheckForScript(const StringOrTrustedScript&,
                                               const ExecutionContext*,
                                               ExceptionState&)
     WARN_UNUSED_RESULT;
+CORE_EXPORT String
+TrustedTypesCheckForScript(const StringTreatNullAsEmptyStringOrTrustedScript&,
+                           const ExecutionContext*,
+                           ExceptionState&) WARN_UNUSED_RESULT;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 // Perform Trusted Type checks, for a dynamically or statically determined
 // type.
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc b/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc
index 7c98944..86bfe28f 100644
--- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html_or_trusted_script_or_trusted_script_url.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_trustedscript.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -85,7 +86,11 @@
 }
 
 void TrustedTypesCheckForScriptWorks(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionStringOrTrustedScript* string_or_trusted_script,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const StringOrTrustedScript& string_or_trusted_script,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     String expected) {
   auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
   LocalDOMWindow* window = dummy_page_holder->GetFrame().DomWindow();
@@ -104,8 +109,13 @@
 // TrustedTypesCheckForScript tests
 TEST(TrustedTypesUtilTest, TrustedTypesCheckForScript_TrustedScript) {
   auto* script = MakeGarbageCollected<TrustedScript>("A string");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* trusted_value =
+      MakeGarbageCollected<V8UnionStringOrTrustedScript>(script);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrTrustedScript trusted_value =
       StringOrTrustedScript::FromTrustedScript(script);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   TrustedTypesCheckForScriptWorks(trusted_value, "A string");
 }
 
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc b/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc
index e8cc31c..1fac3b1 100644
--- a/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc
+++ b/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc
@@ -5,21 +5,10 @@
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h"
 
 namespace blink {
 
-DOMArrayPiece::DOMArrayPiece(
-    const ArrayBufferOrArrayBufferView& array_buffer_or_view) {
-  if (array_buffer_or_view.IsArrayBuffer()) {
-    DOMArrayBuffer* array_buffer = array_buffer_or_view.GetAsArrayBuffer();
-    InitWithArrayBuffer(array_buffer);
-  } else if (array_buffer_or_view.IsArrayBufferView()) {
-    DOMArrayBufferView* array_buffer_view =
-        array_buffer_or_view.GetAsArrayBufferView().Get();
-    InitWithArrayBufferView(array_buffer_view);
-  }
-}
-///////////////////////////////////////////////////////
 DOMArrayPiece::DOMArrayPiece() {
   InitNull();
 }
@@ -32,6 +21,39 @@
   InitWithArrayBufferView(buffer);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+DOMArrayPiece::DOMArrayPiece(
+    const V8UnionArrayBufferOrArrayBufferView* array_buffer_or_view) {
+  DCHECK(array_buffer_or_view);
+
+  switch (array_buffer_or_view->GetContentType()) {
+    case V8UnionArrayBufferOrArrayBufferView::ContentType::kArrayBuffer:
+      InitWithArrayBuffer(array_buffer_or_view->GetAsArrayBuffer());
+      return;
+    case V8UnionArrayBufferOrArrayBufferView::ContentType::kArrayBufferView:
+      InitWithArrayBufferView(
+          array_buffer_or_view->GetAsArrayBufferView().Get());
+      return;
+  }
+
+  NOTREACHED();
+  InitNull();
+}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+// TODO(crbug.com/1181288): Remove the old IDL union version.
+DOMArrayPiece::DOMArrayPiece(
+    const ArrayBufferOrArrayBufferView& array_buffer_or_view) {
+  if (array_buffer_or_view.IsArrayBuffer()) {
+    DOMArrayBuffer* array_buffer = array_buffer_or_view.GetAsArrayBuffer();
+    InitWithArrayBuffer(array_buffer);
+  } else if (array_buffer_or_view.IsArrayBufferView()) {
+    DOMArrayBufferView* array_buffer_view =
+        array_buffer_or_view.GetAsArrayBufferView().Get();
+    InitWithArrayBufferView(array_buffer_view);
+  }
+}
+
 bool DOMArrayPiece::IsNull() const {
   return is_null_;
 }
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h b/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h
index e3960871..1b42500 100644
--- a/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h
+++ b/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h
@@ -12,6 +12,7 @@
 
 class ArrayBufferOrArrayBufferView;
 class DOMArrayBufferView;
+class V8UnionArrayBufferOrArrayBufferView;
 
 // This class is for passing around un-owned bytes as a pointer + length.
 // It supports implicit conversion from several other data types.
@@ -29,6 +30,11 @@
   DOMArrayPiece();
   DOMArrayPiece(DOMArrayBuffer* buffer);
   DOMArrayPiece(DOMArrayBufferView* view);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DOMArrayPiece(
+      const V8UnionArrayBufferOrArrayBufferView* array_buffer_or_view);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  // TODO(crbug.com/1181288): Remove the old IDL union version.
   DOMArrayPiece(const ArrayBufferOrArrayBufferView&);
 
   bool operator==(const DOMArrayBuffer& other) const {
diff --git a/third_party/blink/renderer/core/url/url_search_params.cc b/third_party/blink/renderer/core/url/url_search_params.cc
index 25d1cd3..bb45d24 100644
--- a/third_party/blink/renderer/core/url/url_search_params.cc
+++ b/third_party/blink/renderer/core/url/url_search_params.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <utility>
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_usvstring_usvstringsequencesequence_usvstringusvstringrecord.h"
 #include "third_party/blink/renderer/core/url/dom_url.h"
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/network/form_data_encoder.h"
@@ -53,6 +54,28 @@
 
 }  // namespace
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+URLSearchParams* URLSearchParams::Create(const URLSearchParamsInit* init,
+                                         ExceptionState& exception_state) {
+  DCHECK(init);
+  switch (init->GetContentType()) {
+    case URLSearchParamsInit::ContentType::kUSVString: {
+      const String& query_string = init->GetAsUSVString();
+      if (query_string.StartsWith('?'))
+        return MakeGarbageCollected<URLSearchParams>(query_string.Substring(1));
+      return MakeGarbageCollected<URLSearchParams>(query_string);
+    }
+    case URLSearchParamsInit::ContentType::kUSVStringSequenceSequence:
+      return URLSearchParams::Create(init->GetAsUSVStringSequenceSequence(),
+                                     exception_state);
+    case URLSearchParamsInit::ContentType::kUSVStringUSVStringRecord:
+      return URLSearchParams::Create(init->GetAsUSVStringUSVStringRecord(),
+                                     exception_state);
+  }
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 URLSearchParams* URLSearchParams::Create(const URLSearchParamsInit& init,
                                          ExceptionState& exception_state) {
   if (init.IsUSVString()) {
@@ -73,6 +96,7 @@
   DCHECK(init.IsNull());
   return MakeGarbageCollected<URLSearchParams>(String());
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 URLSearchParams* URLSearchParams::Create(const Vector<Vector<String>>& init,
                                          ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/core/url/url_search_params.h b/third_party/blink/renderer/core/url/url_search_params.h
index 7856603..7a12e95f 100644
--- a/third_party/blink/renderer/core/url/url_search_params.h
+++ b/third_party/blink/renderer/core/url/url_search_params.h
@@ -19,18 +19,29 @@
 
 namespace blink {
 
-class ExceptionState;
 class DOMURL;
+class ExceptionState;
+class V8UnionUSVStringOrUSVStringSequenceSequenceOrUSVStringUSVStringRecord;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+using URLSearchParamsInit =
+    V8UnionUSVStringOrUSVStringSequenceSequenceOrUSVStringUSVStringRecord;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 typedef USVStringSequenceSequenceOrUSVStringUSVStringRecordOrUSVString
     URLSearchParamsInit;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 class CORE_EXPORT URLSearchParams final : public ScriptWrappable,
                                           public PairIterable<String, String> {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static URLSearchParams* Create(const URLSearchParamsInit* init,
+                                 ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static URLSearchParams* Create(const URLSearchParamsInit&, ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static URLSearchParams* Create(const Vector<std::pair<String, String>>&,
                                  ExceptionState&);
   static URLSearchParams* Create(const Vector<Vector<String>>&,
diff --git a/third_party/blink/renderer/core/workers/shared_worker.cc b/third_party/blink/renderer/core/workers/shared_worker.cc
index 0c79349f..0379e22 100644
--- a/third_party/blink/renderer/core/workers/shared_worker.cc
+++ b/third_party/blink/renderer/core/workers/shared_worker.cc
@@ -36,6 +36,7 @@
 #include "third_party/blink/public/common/blob/blob_utils.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
 #include "third_party/blink/public/mojom/worker/shared_worker_info.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_workeroptions.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_worker_options.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/fetch/request.h"
@@ -71,10 +72,15 @@
           SchedulingPolicy::Feature::kSharedWorker,
           {SchedulingPolicy::DisableBackForwardCache()})) {}
 
-SharedWorker* SharedWorker::Create(ExecutionContext* context,
-                                   const String& url,
-                                   const StringOrWorkerOptions& name_or_options,
-                                   ExceptionState& exception_state) {
+SharedWorker* SharedWorker::Create(
+    ExecutionContext* context,
+    const String& url,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionStringOrWorkerOptions* name_or_options,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const StringOrWorkerOptions& name_or_options,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   DCHECK(IsMainThread());
 
   // We don't currently support nested workers, so workers can only be created
@@ -110,6 +116,26 @@
   }
 
   auto options = mojom::blink::WorkerOptions::New();
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (name_or_options->GetContentType()) {
+    case V8UnionStringOrWorkerOptions::ContentType::kString:
+      options->name = name_or_options->GetAsString();
+      break;
+    case V8UnionStringOrWorkerOptions::ContentType::kWorkerOptions: {
+      WorkerOptions* worker_options = name_or_options->GetAsWorkerOptions();
+      options->name = worker_options->name();
+      base::Optional<mojom::blink::ScriptType> type_result =
+          Script::ParseScriptType(worker_options->type());
+      DCHECK(type_result);
+      options->type = type_result.value();
+      base::Optional<network::mojom::CredentialsMode> credentials_result =
+          Request::ParseCredentialsMode(worker_options->credentials());
+      DCHECK(credentials_result);
+      options->credentials = credentials_result.value();
+      break;
+    }
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (name_or_options.IsString()) {
     options->name = name_or_options.GetAsString();
   } else if (name_or_options.IsWorkerOptions()) {
@@ -126,6 +152,7 @@
   } else {
     NOTREACHED();
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DCHECK(!options->name.IsNull());
   if (options->type == mojom::blink::ScriptType::kClassic)
     UseCounter::Count(window, WebFeature::kClassicSharedWorker);
diff --git a/third_party/blink/renderer/core/workers/shared_worker.h b/third_party/blink/renderer/core/workers/shared_worker.h
index 972cb68..319ca5e 100644
--- a/third_party/blink/renderer/core/workers/shared_worker.h
+++ b/third_party/blink/renderer/core/workers/shared_worker.h
@@ -43,6 +43,7 @@
 namespace blink {
 
 class ExceptionState;
+class V8UnionStringOrWorkerOptions;
 
 class CORE_EXPORT SharedWorker final
     : public AbstractWorker,
@@ -51,10 +52,18 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static SharedWorker* Create(
+      ExecutionContext* context,
+      const String& url,
+      const V8UnionStringOrWorkerOptions* name_or_options,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static SharedWorker* Create(ExecutionContext*,
                               const String& url,
                               const StringOrWorkerOptions&,
                               ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   explicit SharedWorker(ExecutionContext*);
   ~SharedWorker() override;
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
index 6c83920..df79edc 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -39,6 +39,7 @@
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view_or_blob_or_usv_string.h"
 #include "third_party/blink/renderer/bindings/core/v8/document_or_xml_http_request_body_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview_blob_document_formdata_urlsearchparams_usvstring.h"
 #include "third_party/blink/renderer/core/dom/document_init.h"
 #include "third_party/blink/renderer/core/dom/document_parser.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -762,6 +763,34 @@
   return true;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void XMLHttpRequest::send(const V8UnionDocumentOrXMLHttpRequestBodyInit* body,
+                          ExceptionState& exception_state) {
+  probe::WillSendXMLHttpOrFetchNetworkRequest(GetExecutionContext(), Url());
+
+  if (!body)
+    return send(String(), exception_state);
+
+  switch (body->GetContentType()) {
+    case V8UnionDocumentOrXMLHttpRequestBodyInit::ContentType::kArrayBuffer:
+      return send(body->GetAsArrayBuffer(), exception_state);
+    case V8UnionDocumentOrXMLHttpRequestBodyInit::ContentType::kArrayBufferView:
+      return send(body->GetAsArrayBufferView().Get(), exception_state);
+    case V8UnionDocumentOrXMLHttpRequestBodyInit::ContentType::kBlob:
+      return send(body->GetAsBlob(), exception_state);
+    case V8UnionDocumentOrXMLHttpRequestBodyInit::ContentType::kDocument:
+      return send(body->GetAsDocument(), exception_state);
+    case V8UnionDocumentOrXMLHttpRequestBodyInit::ContentType::kFormData:
+      return send(body->GetAsFormData(), exception_state);
+    case V8UnionDocumentOrXMLHttpRequestBodyInit::ContentType::kURLSearchParams:
+      return send(body->GetAsURLSearchParams(), exception_state);
+    case V8UnionDocumentOrXMLHttpRequestBodyInit::ContentType::kUSVString:
+      return send(body->GetAsUSVString(), exception_state);
+  }
+
+  NOTREACHED();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void XMLHttpRequest::send(
     const DocumentOrBlobOrArrayBufferOrArrayBufferViewOrFormDataOrURLSearchParamsOrUSVString&
         body,
@@ -806,6 +835,7 @@
   DCHECK(body.IsUSVString());
   send(body.GetAsUSVString(), exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 bool XMLHttpRequest::AreMethodAndURLValidForSend() {
   return method_ != http_names::kGET && method_ != http_names::kHEAD &&
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
index e75442e..024a823 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
@@ -31,6 +31,7 @@
 #include "services/network/public/mojom/url_loader_factory.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_trust_token.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/dom/document_parser_client.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
@@ -134,9 +135,14 @@
             const KURL&,
             bool async,
             ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void send(const V8UnionDocumentOrXMLHttpRequestBodyInit* body,
+            ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void send(
       const DocumentOrBlobOrArrayBufferOrArrayBufferViewOrFormDataOrURLSearchParamsOrUSVString&,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void abort();
   void Dispose();
   void setRequestHeader(const AtomicString& name,
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
index 16ee8af..1512680 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -114,11 +114,6 @@
   DCHECK(IsDetached());
 }
 
-void AXLayoutObject::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_object_);
-  AXNodeObject::Trace(visitor);
-}
-
 LayoutObject* AXLayoutObject::GetLayoutObject() const {
   return layout_object_;
 }
@@ -139,7 +134,7 @@
   if (!layout_object_ || !layout_object_->IsBox())
     return nullptr;
 
-  auto* box = To<LayoutBox>(layout_object_.Get());
+  auto* box = To<LayoutBox>(layout_object_);
 
   // This should possibly use box->CanBeScrolledAndHasScrollableArea() as it
   // used to; however, accessibility must consider any kind of non-visible
@@ -239,7 +234,7 @@
   if (IsA<HTMLCanvasElement>(node))
     return ax::mojom::blink::Role::kCanvas;
 
-  if (IsA<LayoutView>(*layout_object_))
+  if (IsA<LayoutView>(layout_object_))
     return ax::mojom::blink::Role::kRootWebArea;
 
   if (layout_object_->IsSVGImage())
@@ -1010,7 +1005,7 @@
       found_text_alternative = true;
     } else if (layout_object_->IsText() &&
                (!recursive || !layout_object_->IsCounter())) {
-      auto* layout_text = To<LayoutText>(layout_object_.Get());
+      auto* layout_text = To<LayoutText>(layout_object_);
       String visible_text = layout_text->PlainText();  // Actual rendered text.
       // If no text boxes we assume this is unrendered end-of-line whitespace.
       // TODO find robust way to deterministically detect end-of-line space.
@@ -1031,7 +1026,7 @@
       found_text_alternative = true;
     } else if (layout_object_->IsListMarkerForNormalContent() && !recursive) {
       text_alternative =
-          To<LayoutListMarker>(layout_object_.Get())->TextAlternative();
+          To<LayoutListMarker>(layout_object_)->TextAlternative();
       found_text_alternative = true;
     } else if (!recursive) {
       if (ListMarker* marker = ListMarker::Get(layout_object_)) {
@@ -1071,7 +1066,7 @@
             DocumentLifecycle::kPrePaintClean);
 #endif
 
-  PaintLayer* layer = To<LayoutBox>(layout_object_.Get())->Layer();
+  PaintLayer* layer = To<LayoutBox>(layout_object_)->Layer();
 
   HitTestRequest request(HitTestRequest::kReadOnly | HitTestRequest::kActive |
                          HitTestRequest::kRetargetForInert);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.h b/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
index dd39e53..9b376d4 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
@@ -46,7 +46,6 @@
  public:
   AXLayoutObject(LayoutObject*, AXObjectCacheImpl&);
   ~AXLayoutObject() override;
-  void Trace(Visitor*) const override;
 
   // AXObject overrides:
   LayoutObject* GetLayoutObject() const final;
@@ -61,7 +60,7 @@
   Element* AnchorElement() const override;
 
  protected:
-  Member<LayoutObject> layout_object_;
+  LayoutObject* layout_object_;
 
   //
   // Overridden from AXObject.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index c2a25114..3ed1c24f 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -495,12 +495,15 @@
 bool AXObjectCacheImpl::use_ax_menu_list_ = false;
 
 // static
-AXObjectCache* AXObjectCacheImpl::Create(Document& document) {
-  return MakeGarbageCollected<AXObjectCacheImpl>(document);
+AXObjectCache* AXObjectCacheImpl::Create(Document& document,
+                                         const ui::AXMode& ax_mode) {
+  return MakeGarbageCollected<AXObjectCacheImpl>(document, ax_mode);
 }
 
-AXObjectCacheImpl::AXObjectCacheImpl(Document& document)
+AXObjectCacheImpl::AXObjectCacheImpl(Document& document,
+                                     const ui::AXMode& ax_mode)
     : document_(document),
+      ax_mode_(ax_mode),
       modification_count_(0),
       validation_message_axid_(0),
       active_aria_modal_dialog_(nullptr),
@@ -596,11 +599,18 @@
   return obj;
 }
 
-
 AXObject* AXObjectCacheImpl::FocusedObject() {
   return GetOrCreateFocusedObjectFromNode(FocusedElement());
 }
 
+const ui::AXMode& AXObjectCacheImpl::GetAXMode() {
+  return ax_mode_;
+}
+
+void AXObjectCacheImpl::SetAXMode(const ui::AXMode& ax_mode) {
+  ax_mode_ = ax_mode;
+}
+
 AXObject* AXObjectCacheImpl::Get(const LayoutObject* layout_object) {
   if (!layout_object)
     return nullptr;
@@ -3514,7 +3524,6 @@
 void AXObjectCacheImpl::Trace(Visitor* visitor) const {
   visitor->Trace(document_);
   visitor->Trace(accessible_node_mapping_);
-  visitor->Trace(layout_object_mapping_);
   visitor->Trace(node_object_mapping_);
   visitor->Trace(active_aria_modal_dialog_);
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index 320c821..3514f09 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -52,6 +52,7 @@
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 #include "ui/accessibility/ax_enums.mojom-blink-forward.h"
+#include "ui/accessibility/ax_mode.h"
 
 namespace blink {
 
@@ -65,15 +66,18 @@
     : public AXObjectCacheBase,
       public mojom::blink::PermissionObserver {
  public:
-  static AXObjectCache* Create(Document&);
+  static AXObjectCache* Create(Document&, const ui::AXMode&);
 
-  explicit AXObjectCacheImpl(Document&);
+  AXObjectCacheImpl(Document&, const ui::AXMode&);
   ~AXObjectCacheImpl() override;
   void Trace(Visitor*) const override;
 
   Document& GetDocument() { return *document_; }
   AXObject* FocusedObject();
 
+  const ui::AXMode& GetAXMode() override;
+  void SetAXMode(const ui::AXMode&) override;
+
   void Dispose() override;
 
   void Freeze() override { is_frozen_ = true; }
@@ -437,11 +441,12 @@
   void MarkElementDirtyWithCleanLayout(const Node*, bool subtree);
 
   Member<Document> document_;
+  ui::AXMode ax_mode_;
   HeapHashMap<AXID, Member<AXObject>> objects_;
   // LayoutObject and AbstractInlineTextBox are not on the Oilpan heap so we
   // do not use HeapHashMap for those mappings.
   HeapHashMap<Member<AccessibleNode>, AXID> accessible_node_mapping_;
-  HeapHashMap<Member<const LayoutObject>, AXID> layout_object_mapping_;
+  HashMap<const LayoutObject*, AXID> layout_object_mapping_;
   HeapHashMap<Member<const Node>, AXID> node_object_mapping_;
   HashMap<AbstractInlineTextBox*, AXID> inline_text_box_object_mapping_;
   int modification_count_;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.cc b/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.cc
index 427ae182..0f0408a 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_progress_indicator.cc
@@ -79,7 +79,7 @@
 }
 
 HTMLProgressElement* AXProgressIndicator::GetProgressElement() const {
-  return To<LayoutProgress>(layout_object_.Get())->ProgressElement();
+  return To<LayoutProgress>(layout_object_)->ProgressElement();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/animationworklet/animator.cc b/third_party/blink/renderer/modules/animationworklet/animator.cc
index cd278764..522dee1 100644
--- a/third_party/blink/renderer/modules/animationworklet/animator.cc
+++ b/third_party/blink/renderer/modules/animationworklet/animator.cc
@@ -7,6 +7,7 @@
 #include "base/stl_util.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_animate_callback.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_state_callback.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_workletanimationeffect_workletgroupeffect.h"
 #include "third_party/blink/renderer/bindings/modules/v8/worklet_animation_effect_or_worklet_group_effect.h"
 #include "third_party/blink/renderer/modules/animationworklet/animator_definition.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -48,12 +49,25 @@
   if (IsUndefinedOrNull(instance))
     return false;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionWorkletAnimationEffectOrWorkletGroupEffect* effect = nullptr;
+  if (group_effect_->getChildren().size() == 1) {
+    effect =
+        MakeGarbageCollected<V8UnionWorkletAnimationEffectOrWorkletGroupEffect>(
+            group_effect_->getChildren()[0]);
+  } else {
+    effect =
+        MakeGarbageCollected<V8UnionWorkletAnimationEffectOrWorkletGroupEffect>(
+            group_effect_);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   WorkletAnimationEffectOrWorkletGroupEffect effect;
   if (group_effect_->getChildren().size() == 1) {
     effect.SetWorkletAnimationEffect(group_effect_->getChildren()[0]);
   } else {
     effect.SetWorkletGroupEffect(group_effect_);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   v8::TryCatch try_catch(isolate);
   try_catch.SetVerbose(true);
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
index ce436fa..80aa1e89 100644
--- a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
+++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -8,6 +8,9 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_animationeffect_animationeffectsequence.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_documenttimeline_scrolltimeline.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_scrolltimelineautokeyword.h"
 #include "third_party/blink/renderer/bindings/modules/v8/animation_effect_or_animation_effect_sequence.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
 #include "third_party/blink/renderer/core/animation/element_animations.h"
@@ -34,12 +37,50 @@
 namespace {
 
 bool ConvertAnimationEffects(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionAnimationEffectOrAnimationEffectSequence* effects,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const AnimationEffectOrAnimationEffectSequence& effects,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     HeapVector<Member<KeyframeEffect>>& keyframe_effects,
     String& error_string) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DCHECK(effects);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DCHECK(keyframe_effects.IsEmpty());
 
   // Currently we only support KeyframeEffect.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (effects->GetContentType()) {
+    case V8UnionAnimationEffectOrAnimationEffectSequence::ContentType::
+        kAnimationEffect: {
+      AnimationEffect* effect = effects->GetAsAnimationEffect();
+      KeyframeEffect* keyframe_effect = DynamicTo<KeyframeEffect>(effect);
+      if (!keyframe_effect) {
+        error_string = "Effect must be a KeyframeEffect object";
+        return false;
+      }
+      keyframe_effects.push_back(keyframe_effect);
+      break;
+    }
+    case V8UnionAnimationEffectOrAnimationEffectSequence::ContentType::
+        kAnimationEffectSequence: {
+      const HeapVector<Member<AnimationEffect>>& effect_sequence =
+          effects->GetAsAnimationEffectSequence();
+      keyframe_effects.ReserveInitialCapacity(effect_sequence.size());
+      for (const auto& effect : effect_sequence) {
+        KeyframeEffect* keyframe_effect =
+            DynamicTo<KeyframeEffect>(effect.Get());
+        if (!keyframe_effect) {
+          error_string = "Effects must all be KeyframeEffect objects";
+          return false;
+        }
+        keyframe_effects.push_back(keyframe_effect);
+      }
+      break;
+    }
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (effects.IsAnimationEffect()) {
     auto* const effect = effects.GetAsAnimationEffect();
     auto* key_frame = DynamicTo<KeyframeEffect>(effect);
@@ -61,6 +102,7 @@
       keyframe_effects.push_back(key_frame);
     }
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   if (keyframe_effects.IsEmpty()) {
     error_string = "Effects array must be non-empty";
@@ -91,6 +133,22 @@
   }
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+bool ValidateTimeline(const V8UnionDocumentTimelineOrScrollTimeline* timeline,
+                      String& error_string) {
+  if (!timeline)
+    return true;
+  if (timeline->IsScrollTimeline()) {
+    V8UnionDoubleOrScrollTimelineAutoKeyword* time_range =
+        timeline->GetAsScrollTimeline()->timeRange();
+    if (time_range->IsScrollTimelineAutoKeyword()) {
+      error_string = "ScrollTimeline timeRange must have non-auto value";
+      return false;
+    }
+  }
+  return true;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 bool ValidateTimeline(const DocumentTimelineOrScrollTimeline& timeline,
                       String& error_string) {
   if (timeline.IsScrollTimeline()) {
@@ -103,7 +161,25 @@
   }
   return true;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+AnimationTimeline* ConvertAnimationTimeline(
+    const Document& document,
+    const V8UnionDocumentTimelineOrScrollTimeline* timeline) {
+  if (!timeline)
+    return &document.Timeline();
+  switch (timeline->GetContentType()) {
+    case V8UnionDocumentTimelineOrScrollTimeline::ContentType::
+        kDocumentTimeline:
+      return timeline->GetAsDocumentTimeline();
+    case V8UnionDocumentTimelineOrScrollTimeline::ContentType::kScrollTimeline:
+      return timeline->GetAsScrollTimeline();
+  }
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 AnimationTimeline* ConvertAnimationTimeline(
     const Document& document,
     const DocumentTimelineOrScrollTimeline& timeline) {
@@ -115,6 +191,7 @@
 
   return &document.Timeline();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 bool CheckElementComposited(const Node& target) {
   return target.GetLayoutObject() &&
@@ -181,6 +258,16 @@
 }
 }  // namespace
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+WorkletAnimation* WorkletAnimation::Create(
+    ScriptState* script_state,
+    const String& animator_name,
+    const V8UnionAnimationEffectOrAnimationEffectSequence* effects,
+    ExceptionState& exception_state) {
+  return Create(script_state, animator_name, effects, nullptr, ScriptValue(),
+                exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 WorkletAnimation* WorkletAnimation::Create(
     ScriptState* script_state,
     String animator_name,
@@ -190,7 +277,19 @@
                 DocumentTimelineOrScrollTimeline(), ScriptValue(),
                 exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+WorkletAnimation* WorkletAnimation::Create(
+    ScriptState* script_state,
+    const String& animator_name,
+    const V8UnionAnimationEffectOrAnimationEffectSequence* effects,
+    const V8UnionDocumentTimelineOrScrollTimeline* timeline,
+    ExceptionState& exception_state) {
+  return Create(script_state, animator_name, effects, timeline, ScriptValue(),
+                exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 WorkletAnimation* WorkletAnimation::Create(
     ScriptState* script_state,
     String animator_name,
@@ -200,11 +299,19 @@
   return Create(script_state, animator_name, effects, timeline, ScriptValue(),
                 exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 WorkletAnimation* WorkletAnimation::Create(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const String& animator_name,
+    const V8UnionAnimationEffectOrAnimationEffectSequence* effects,
+    const V8UnionDocumentTimelineOrScrollTimeline* timeline,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     String animator_name,
     const AnimationEffectOrAnimationEffectSequence& effects,
     DocumentTimelineOrScrollTimeline timeline,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const ScriptValue& options,
     ExceptionState& exception_state) {
   DCHECK(IsMainThread());
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation.h b/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
index c2d5493..3559ab9 100644
--- a/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
+++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
@@ -24,6 +24,8 @@
 class AnimationEffectOrAnimationEffectSequence;
 class ScriptValue;
 class SerializedScriptValue;
+class V8UnionAnimationEffectOrAnimationEffectSequence;
+class V8UnionDocumentTimelineOrScrollTimeline;
 
 // The main-thread controller for a single AnimationWorklet animator instance.
 //
@@ -44,6 +46,26 @@
   USING_PRE_FINALIZER(WorkletAnimation, Dispose);
 
  public:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static WorkletAnimation* Create(
+      ScriptState* script_state,
+      const String& animator_name,
+      const V8UnionAnimationEffectOrAnimationEffectSequence* effects,
+      ExceptionState& exception_state);
+  static WorkletAnimation* Create(
+      ScriptState* script_state,
+      const String& animator_name,
+      const V8UnionAnimationEffectOrAnimationEffectSequence* effects,
+      const V8UnionDocumentTimelineOrScrollTimeline* timeline,
+      ExceptionState& exception_state);
+  static WorkletAnimation* Create(
+      ScriptState* script_state,
+      const String& animator_name,
+      const V8UnionAnimationEffectOrAnimationEffectSequence* effects,
+      const V8UnionDocumentTimelineOrScrollTimeline* timeline,
+      const ScriptValue& options,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static WorkletAnimation* Create(
       ScriptState*,
       String animator_name,
@@ -62,6 +84,7 @@
       DocumentTimelineOrScrollTimeline,
       const ScriptValue& options,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   WorkletAnimation(WorkletAnimationId id,
                    const String& animator_name,
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
index 5ce7764..cc5f412 100644
--- a/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
+++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
@@ -11,6 +11,8 @@
 #include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_animationeffect_animationeffectsequence.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_documenttimeline_scrolltimeline.h"
 #include "third_party/blink/renderer/bindings/modules/v8/animation_effect_or_animation_effect_sequence.h"
 #include "third_party/blink/renderer/core/animation/document_timeline.h"
 #include "third_party/blink/renderer/core/animation/element_animations.h"
@@ -64,12 +66,23 @@
     Element* element,
     const String& animator_name,
     ScrollTimeline* scroll_timeline = nullptr) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* effects =
+      MakeGarbageCollected<V8UnionAnimationEffectOrAnimationEffectSequence>(
+          CreateKeyframeEffect(element));
+  V8UnionDocumentTimelineOrScrollTimeline* timeline = nullptr;
+  if (scroll_timeline) {
+    timeline = MakeGarbageCollected<V8UnionDocumentTimelineOrScrollTimeline>(
+        scroll_timeline);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   AnimationEffectOrAnimationEffectSequence effects;
   AnimationEffect* effect = CreateKeyframeEffect(element);
   effects.SetAnimationEffect(effect);
   DocumentTimelineOrScrollTimeline timeline;
   if (scroll_timeline)
     timeline.SetScrollTimeline(scroll_timeline);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptValue options;
 
   ScriptState::Scope scope(script_state);
@@ -143,8 +156,11 @@
 }
 
 TEST_F(WorkletAnimationTest, StyleHasCurrentAnimation) {
-  ComputedStyle* style = GetDocument().GetStyleResolver().ResolveStyle(
-      element_, StyleRecalcContext());
+  scoped_refptr<ComputedStyle> style =
+      GetDocument()
+          .GetStyleResolver()
+          .ResolveStyle(element_, StyleRecalcContext())
+          .get();
   EXPECT_EQ(false, style->HasCurrentOpacityAnimation());
   worklet_animation_->play(ASSERT_NO_EXCEPTION);
   element_->EnsureElementAnimations().UpdateAnimationFlags(*style);
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
index 4553e5e..ee5afec 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
@@ -11,6 +11,7 @@
 #include "services/network/public/mojom/ip_address_space.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_request_requestorusvstringsequence_usvstring.h"
 #include "third_party/blink/renderer/bindings/modules/v8/request_or_usv_string_or_request_or_usv_string_sequence.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.h"
@@ -50,8 +51,10 @@
 const char kEmptyRequestSequenceErrorMessage[] =
     "At least one request must be given.";
 
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 // Message for the TypeError thrown when a null request is seen.
 const char kNullRequestErrorMessage[] = "Requests must not be null.";
+#endif  // !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 ScriptPromise RejectWithTypeError(ScriptState* script_state,
                                   const KURL& request_url,
@@ -161,7 +164,11 @@
 ScriptPromise BackgroundFetchManager::fetch(
     ScriptState* script_state,
     const String& id,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionRequestInfoOrRequestOrUSVStringSequence* requests,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const RequestOrUSVStringOrRequestOrUSVStringSequence& requests,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const BackgroundFetchOptions* options,
     ExceptionState& exception_state) {
   if (!registration_->active()) {
@@ -380,6 +387,83 @@
   return promise;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// static
+Vector<mojom::blink::FetchAPIRequestPtr>
+BackgroundFetchManager::CreateFetchAPIRequestVector(
+    ScriptState* script_state,
+    const V8UnionRequestInfoOrRequestOrUSVStringSequence* requests,
+    ExceptionState& exception_state,
+    bool* has_requests_with_body) {
+  DCHECK(requests);
+  DCHECK(has_requests_with_body);
+
+  Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests;
+  *has_requests_with_body = false;
+
+  switch (requests->GetContentType()) {
+    case V8UnionRequestInfoOrRequestOrUSVStringSequence::ContentType::
+        kRequestOrUSVStringSequence: {
+      const HeapVector<Member<V8RequestInfo>>& request_vector =
+          requests->GetAsRequestOrUSVStringSequence();
+
+      // Throw a TypeError when the developer has passed an empty sequence.
+      if (request_vector.IsEmpty()) {
+        exception_state.ThrowTypeError(kEmptyRequestSequenceErrorMessage);
+        return {};
+      }
+
+      fetch_api_requests.ReserveCapacity(request_vector.size());
+      for (const auto& request_info : request_vector) {
+        Request* request = nullptr;
+        switch (request_info->GetContentType()) {
+          case V8RequestInfo::ContentType::kRequest:
+            request = request_info->GetAsRequest();
+            break;
+          case V8RequestInfo::ContentType::kUSVString:
+            request = Request::Create(
+                script_state, request_info->GetAsUSVString(), exception_state);
+            if (exception_state.HadException())
+              return {};
+            break;
+        }
+        *has_requests_with_body |= request->HasBody();
+        fetch_api_requests.push_back(request->CreateFetchAPIRequest());
+        fetch_api_requests.back()->blob =
+            ExtractBlobHandle(request, exception_state);
+        if (exception_state.HadException())
+          return {};
+      }
+      break;
+    }
+    case V8UnionRequestInfoOrRequestOrUSVStringSequence::ContentType::
+        kRequest: {
+      Request* request = requests->GetAsRequest();
+      *has_requests_with_body = request->HasBody();
+      fetch_api_requests.push_back(request->CreateFetchAPIRequest());
+      fetch_api_requests.back()->blob =
+          ExtractBlobHandle(request, exception_state);
+      if (exception_state.HadException())
+        return {};
+      break;
+    }
+    case V8UnionRequestInfoOrRequestOrUSVStringSequence::ContentType::
+        kUSVString: {
+      Request* request = Request::Create(
+          script_state, requests->GetAsUSVString(), exception_state);
+      if (exception_state.HadException())
+        return {};
+      *has_requests_with_body = request->HasBody();
+      fetch_api_requests.push_back(request->CreateFetchAPIRequest());
+      fetch_api_requests.back()->blob =
+          ExtractBlobHandle(request, exception_state);
+      break;
+    }
+  }
+
+  return fetch_api_requests;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 // static
 Vector<mojom::blink::FetchAPIRequestPtr>
 BackgroundFetchManager::CreateFetchAPIRequestVector(
@@ -455,6 +539,7 @@
 
   return fetch_api_requests;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void BackgroundFetchManager::DidGetRegistration(
     ScriptPromiseResolver* resolver,
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h
index 12488e9..abe70781 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h
@@ -8,6 +8,7 @@
 #include "base/time/time.h"
 #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -43,7 +44,11 @@
   ScriptPromise fetch(
       ScriptState* script_state,
       const String& id,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const V8UnionRequestInfoOrRequestOrUSVStringSequence* requests,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const RequestOrUSVStringOrRequestOrUSVStringSequence& requests,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const BackgroundFetchOptions* options,
       ExceptionState& exception_state);
   ScriptPromise get(ScriptState* script_state,
@@ -64,7 +69,11 @@
   // |has_requests_with_body| will be set if any of the |requests| has a body.
   static Vector<mojom::blink::FetchAPIRequestPtr> CreateFetchAPIRequestVector(
       ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const V8UnionRequestInfoOrRequestOrUSVStringSequence* requests,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const RequestOrUSVStringOrRequestOrUSVStringSequence& requests,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       ExceptionState& exception_state,
       bool* has_requests_with_body);
 
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc
index e3ef1be..a0daf6ce 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_request_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_request_requestorusvstringsequence_usvstring.h"
 #include "third_party/blink/renderer/bindings/modules/v8/request_or_usv_string_or_request_or_usv_string_sequence.h"
 #include "third_party/blink/renderer/core/fetch/request.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -24,7 +25,12 @@
   // declarations necessary in the BackgroundFetchManager.
   Vector<mojom::blink::FetchAPIRequestPtr> CreateFetchAPIRequestVector(
       V8TestingScope& scope,
-      const RequestOrUSVStringOrRequestOrUSVStringSequence& requests) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const V8UnionRequestInfoOrRequestOrUSVStringSequence* requests
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const RequestOrUSVStringOrRequestOrUSVStringSequence& requests
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ) {
     bool has_requests_with_body;
     return BackgroundFetchManager::CreateFetchAPIRequestVector(
         scope.GetScriptState(), requests, scope.GetExceptionState(),
@@ -32,10 +38,19 @@
   }
 };
 
-TEST_F(BackgroundFetchManagerTest, NullValue) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#define MAYBE_NullValue DISABLED_NullValue
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#define MAYBE_NullValue NullValue
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+TEST_F(BackgroundFetchManagerTest, MAYBE_NullValue) {
   V8TestingScope scope;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionRequestInfoOrRequestOrUSVStringSequence* requests = nullptr;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RequestOrUSVStringOrRequestOrUSVStringSequence requests;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
       CreateFetchAPIRequestVector(scope, requests);
@@ -49,9 +64,15 @@
 
   KURL image_url("https://www.example.com/my_image.png");
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* requests =
+      MakeGarbageCollected<V8UnionRequestInfoOrRequestOrUSVStringSequence>(
+          image_url.GetString());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RequestOrUSVStringOrRequestOrUSVStringSequence requests =
       RequestOrUSVStringOrRequestOrUSVStringSequence::FromUSVString(
           image_url.GetString());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
       CreateFetchAPIRequestVector(scope, requests);
@@ -75,8 +96,14 @@
   ASSERT_FALSE(scope.GetExceptionState().HadException());
   ASSERT_TRUE(request);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* requests =
+      MakeGarbageCollected<V8UnionRequestInfoOrRequestOrUSVStringSequence>(
+          request);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RequestOrUSVStringOrRequestOrUSVStringSequence requests =
       RequestOrUSVStringOrRequestOrUSVStringSequence::FromRequest(request);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
       CreateFetchAPIRequestVector(scope, requests);
@@ -94,10 +121,17 @@
   KURL icon_url("https://www.example.com/my_icon.jpg");
   KURL cat_video_url("https://www.example.com/my_cat_video.avi");
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* image_request =
+      MakeGarbageCollected<V8UnionRequestOrUSVString>(image_url.GetString());
+  auto* icon_request =
+      MakeGarbageCollected<V8UnionRequestOrUSVString>(icon_url.GetString());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RequestOrUSVString image_request =
       RequestOrUSVString::FromUSVString(image_url.GetString());
   RequestOrUSVString icon_request =
       RequestOrUSVString::FromUSVString(icon_url.GetString());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   RequestInit* request_init = RequestInit::Create();
   request_init->setMethod("DELETE");
@@ -107,17 +141,32 @@
   ASSERT_FALSE(scope.GetExceptionState().HadException());
   ASSERT_TRUE(request);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* cat_video_request =
+      MakeGarbageCollected<V8UnionRequestOrUSVString>(request);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RequestOrUSVString cat_video_request =
       RequestOrUSVString::FromRequest(request);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8UnionRequestOrUSVString>> request_sequence;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<RequestOrUSVString> request_sequence;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   request_sequence.push_back(image_request);
   request_sequence.push_back(icon_request);
   request_sequence.push_back(cat_video_request);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* requests =
+      MakeGarbageCollected<V8UnionRequestInfoOrRequestOrUSVStringSequence>(
+          request_sequence);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RequestOrUSVStringOrRequestOrUSVStringSequence requests =
       RequestOrUSVStringOrRequestOrUSVStringSequence::
           FromRequestOrUSVStringSequence(request_sequence);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
       CreateFetchAPIRequestVector(scope, requests);
@@ -137,10 +186,17 @@
 TEST_F(BackgroundFetchManagerTest, SequenceEmpty) {
   V8TestingScope scope;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8UnionRequestOrUSVString>> request_sequence;
+  auto* requests =
+      MakeGarbageCollected<V8UnionRequestInfoOrRequestOrUSVStringSequence>(
+          request_sequence);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<RequestOrUSVString> request_sequence;
   RequestOrUSVStringOrRequestOrUSVStringSequence requests =
       RequestOrUSVStringOrRequestOrUSVStringSequence::
           FromRequestOrUSVStringSequence(request_sequence);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
       CreateFetchAPIRequestVector(scope, requests);
@@ -149,22 +205,44 @@
             ESErrorType::kTypeError);
 }
 
-TEST_F(BackgroundFetchManagerTest, SequenceWithNullValue) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#define MAYBE_SequenceWithNullValue DISABLED_SequenceWithNullValue
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#define MAYBE_SequenceWithNullValue SequenceWithNullValue
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+TEST_F(BackgroundFetchManagerTest, MAYBE_SequenceWithNullValue) {
   V8TestingScope scope;
 
   KURL image_url("https://www.example.com/my_image.png");
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* image_request =
+      MakeGarbageCollected<V8UnionRequestOrUSVString>(image_url.GetString());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RequestOrUSVString null_request;
   RequestOrUSVString image_request =
       RequestOrUSVString::FromUSVString(image_url.GetString());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8UnionRequestOrUSVString>> request_sequence;
+  request_sequence.push_back(image_request);
+  request_sequence.push_back(nullptr);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<RequestOrUSVString> request_sequence;
   request_sequence.push_back(image_request);
   request_sequence.push_back(null_request);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* requests =
+      MakeGarbageCollected<V8UnionRequestInfoOrRequestOrUSVStringSequence>(
+          request_sequence);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RequestOrUSVStringOrRequestOrUSVStringSequence requests =
       RequestOrUSVStringOrRequestOrUSVStringSequence::
           FromRequestOrUSVStringSequence(request_sequence);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
       CreateFetchAPIRequestVector(scope, requests);
@@ -193,17 +271,35 @@
   ASSERT_TRUE(image_request->HasBody());
 
   // Create second request without a body.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* icon_request =
+      MakeGarbageCollected<V8UnionRequestOrUSVString>(icon_url.GetString());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RequestOrUSVString icon_request =
       RequestOrUSVString::FromUSVString(icon_url.GetString());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Create a request sequence with both requests.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8UnionRequestOrUSVString>> request_sequence;
+  request_sequence.push_back(
+      MakeGarbageCollected<V8UnionRequestOrUSVString>(image_request));
+  request_sequence.push_back(icon_request);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<RequestOrUSVString> request_sequence;
   request_sequence.push_back(RequestOrUSVString::FromRequest(image_request));
   request_sequence.push_back(icon_request);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* requests =
+      MakeGarbageCollected<V8UnionRequestInfoOrRequestOrUSVStringSequence>(
+          request_sequence);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RequestOrUSVStringOrRequestOrUSVStringSequence requests =
       RequestOrUSVStringOrRequestOrUSVStringSequence::
           FromRequestOrUSVStringSequence(request_sequence);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Extract the blobs.
   Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests =
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
index 613f69d6..011c95e 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
 #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_request_usvstring.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_cache_query_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -147,37 +148,69 @@
 
 ScriptPromise BackgroundFetchRegistration::match(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8RequestInfo* request,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const RequestOrUSVString& request,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const CacheQueryOptions* options,
     ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  return MatchImpl(script_state, request,
+                   mojom::blink::CacheQueryOptions::From(options),
+                   exception_state,
+                   /* match_all = */ false);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   return MatchImpl(
       script_state, base::make_optional<RequestOrUSVString>(request),
       mojom::blink::CacheQueryOptions::From(options), exception_state,
       /* match_all = */ false);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 ScriptPromise BackgroundFetchRegistration::matchAll(
     ScriptState* script_state,
     ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  return MatchImpl(script_state, /* request = */ nullptr,
+                   /* cache_query_options = */ nullptr, exception_state,
+                   /* match_all = */ true);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   return MatchImpl(script_state, /* request = */ base::nullopt,
                    /* cache_query_options = */ nullptr, exception_state,
                    /* match_all = */ true);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 ScriptPromise BackgroundFetchRegistration::matchAll(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8RequestInfo* request,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const RequestOrUSVString& request,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const CacheQueryOptions* options,
     ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  return MatchImpl(script_state, request,
+                   mojom::blink::CacheQueryOptions::From(options),
+                   exception_state,
+                   /* match_all = */ true);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   return MatchImpl(
       script_state, base::make_optional<RequestOrUSVString>(request),
       mojom::blink::CacheQueryOptions::From(options), exception_state,
       /* match_all = */ true);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 ScriptPromise BackgroundFetchRegistration::MatchImpl(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8RequestInfo* request,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     base::Optional<RequestOrUSVString> request,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     mojom::blink::CacheQueryOptionsPtr cache_query_options,
     ExceptionState& exception_state,
     bool match_all) {
@@ -200,6 +233,23 @@
 
   // Convert |request| to mojom::blink::FetchAPIRequestPtr.
   mojom::blink::FetchAPIRequestPtr request_to_match;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  if (request) {
+    switch (request->GetContentType()) {
+      case V8RequestInfo::ContentType::kRequest:
+        request_to_match = request->GetAsRequest()->CreateFetchAPIRequest();
+        break;
+      case V8RequestInfo::ContentType::kUSVString: {
+        Request* new_request = Request::Create(
+            script_state, request->GetAsUSVString(), exception_state);
+        if (exception_state.HadException())
+          return ScriptPromise();
+        request_to_match = new_request->CreateFetchAPIRequest();
+        break;
+      }
+    }
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (request.has_value()) {
     if (request->IsRequest()) {
       request_to_match = request->GetAsRequest()->CreateFetchAPIRequest();
@@ -211,6 +261,7 @@
       request_to_match = new_request->CreateFetchAPIRequest();
     }
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   DCHECK(registration_);
   DCHECK(registration_service_);
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
index 35f0c798..b2eb09f 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h
@@ -9,6 +9,7 @@
 #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/dom/events/event_target.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
@@ -59,16 +60,30 @@
   // Web Exposed attribute defined in the IDL file. Corresponds to the
   // |developer_id| used elsewhere in the codebase.
   String id() const;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise match(ScriptState* script_state,
+                      const V8RequestInfo* request,
+                      const CacheQueryOptions* options,
+                      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise match(ScriptState* script_state,
                       const RequestOrUSVString& request,
                       const CacheQueryOptions* options,
                       ExceptionState& exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise matchAll(ScriptState* scrip_state,
                          ExceptionState& exception_state);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise matchAll(ScriptState* script_state,
+                         const V8RequestInfo* request,
+                         const CacheQueryOptions* options,
+                         ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise matchAll(ScriptState* script_state,
                          const RequestOrUSVString& request,
                          const CacheQueryOptions* options,
                          ExceptionState& exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   uint64_t uploadTotal() const;
   uint64_t uploaded() const;
@@ -100,12 +115,21 @@
  private:
   void DidAbort(ScriptPromiseResolver* resolver,
                 mojom::blink::BackgroundFetchError error);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise MatchImpl(
+      ScriptState* script_state,
+      const V8RequestInfo* request,
+      mojom::blink::CacheQueryOptionsPtr cache_query_options,
+      ExceptionState& exception_state,
+      bool match_all);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise MatchImpl(
       ScriptState* script_state,
       base::Optional<RequestOrUSVString> request,
       mojom::blink::CacheQueryOptionsPtr cache_query_options,
       ExceptionState& exception_state,
       bool match_all);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void DidGetMatchingRequests(
       ScriptPromiseResolver* resolver,
       bool return_all,
diff --git a/third_party/blink/renderer/modules/beacon/navigator_beacon.cc b/third_party/blink/renderer/modules/beacon/navigator_beacon.cc
index c95048d..f28cb0f 100644
--- a/third_party/blink/renderer/modules/beacon/navigator_beacon.cc
+++ b/third_party/blink/renderer/modules/beacon/navigator_beacon.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/beacon/navigator_beacon.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview_blob_formdata_readablestream_urlsearchparams_usvstring.h"
 #include "third_party/blink/renderer/bindings/modules/v8/readable_stream_or_xml_http_request_body_init.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/fileapi/blob.h"
@@ -60,6 +61,17 @@
   return GetSupplementable()->DomWindow();
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+bool NavigatorBeacon::sendBeacon(
+    ScriptState* script_state,
+    Navigator& navigator,
+    const String& url_string,
+    const V8UnionReadableStreamOrXMLHttpRequestBodyInit* data,
+    ExceptionState& exception_state) {
+  return NavigatorBeacon::From(navigator).SendBeaconImpl(
+      script_state, url_string, data, exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 bool NavigatorBeacon::sendBeacon(
     ScriptState* script_state,
     Navigator& navigator,
@@ -70,7 +82,98 @@
   return NavigatorBeacon::From(navigator).SendBeaconImpl(
       script_state, urlstring, data, exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+bool NavigatorBeacon::SendBeaconImpl(
+    ScriptState* script_state,
+    const String& url_string,
+    const V8UnionReadableStreamOrXMLHttpRequestBodyInit* data,
+    ExceptionState& exception_state) {
+  ExecutionContext* execution_context = ExecutionContext::From(script_state);
+  KURL url = execution_context->CompleteURL(url_string);
+  if (!CanSendBeacon(execution_context, url, exception_state)) {
+    // TODO(crbug.com/1161996): Remove this VLOG once the investigation is done.
+    VLOG(1) << "Cannot send a beacon to " << url.ElidedString()
+            << ", initiator = " << execution_context->Url();
+    return false;
+  }
+
+  // TODO(crbug.com/1161996): Remove this VLOG once the investigation is done.
+  VLOG(1) << "Send a beacon to " << url.ElidedString()
+          << ", initiator = " << execution_context->Url();
+
+  bool allowed;
+  LocalFrame* frame = GetSupplementable()->DomWindow()->GetFrame();
+  if (data) {
+    switch (data->GetContentType()) {
+      case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::
+          kArrayBuffer: {
+        auto* data_buffer = data->GetAsArrayBuffer();
+        if (!base::CheckedNumeric<wtf_size_t>(data_buffer->ByteLength())
+                 .IsValid()) {
+          // At the moment the PingLoader::SendBeacon implementation cannot deal
+          // with huge ArrayBuffers.
+          exception_state.ThrowRangeError(
+              "The data provided to sendBeacon() exceeds the maximally "
+              "possible length, which is 4294967295.");
+          return false;
+        }
+        allowed =
+            PingLoader::SendBeacon(*script_state, frame, url, data_buffer);
+        break;
+      }
+      case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::
+          kArrayBufferView: {
+        auto* data_view = data->GetAsArrayBufferView().Get();
+        if (!base::CheckedNumeric<wtf_size_t>(data_view->byteLength())
+                 .IsValid()) {
+          // At the moment the PingLoader::SendBeacon implementation cannot deal
+          // with huge ArrayBuffers.
+          exception_state.ThrowRangeError(
+              "The data provided to sendBeacon() exceeds the maximally "
+              "possible length, which is 4294967295.");
+          return false;
+        }
+        allowed = PingLoader::SendBeacon(*script_state, frame, url, data_view);
+        break;
+      }
+      case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::kBlob:
+        allowed = PingLoader::SendBeacon(*script_state, frame, url,
+                                         data->GetAsBlob());
+        break;
+      case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::
+          kFormData:
+        allowed = PingLoader::SendBeacon(*script_state, frame, url,
+                                         data->GetAsFormData());
+        break;
+      case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::
+          kReadableStream:
+        exception_state.ThrowTypeError(
+            "sendBeacon cannot have a ReadableStream body.");
+        return false;
+      case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::
+          kURLSearchParams:
+        allowed = PingLoader::SendBeacon(*script_state, frame, url,
+                                         data->GetAsURLSearchParams());
+        break;
+      case V8UnionReadableStreamOrXMLHttpRequestBodyInit::ContentType::
+          kUSVString:
+        allowed = PingLoader::SendBeacon(*script_state, frame, url,
+                                         data->GetAsUSVString());
+        break;
+    }
+  } else {
+    allowed = PingLoader::SendBeacon(*script_state, frame, url, String());
+  }
+
+  if (!allowed) {
+    UseCounter::Count(execution_context, WebFeature::kSendBeaconQuotaExceeded);
+  }
+
+  return allowed;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 bool NavigatorBeacon::SendBeaconImpl(
     ScriptState* script_state,
     const String& urlstring,
@@ -142,5 +245,6 @@
 
   return true;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/beacon/navigator_beacon.h b/third_party/blink/renderer/modules/beacon/navigator_beacon.h
index 7931ac02..600e4b7 100644
--- a/third_party/blink/renderer/modules/beacon/navigator_beacon.h
+++ b/third_party/blink/renderer/modules/beacon/navigator_beacon.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BEACON_NAVIGATOR_BEACON_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_BEACON_NAVIGATOR_BEACON_H_
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/frame/navigator.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/supplementable.h"
@@ -27,21 +28,37 @@
   explicit NavigatorBeacon(Navigator&);
   virtual ~NavigatorBeacon();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static bool sendBeacon(
+      ScriptState* script_state,
+      Navigator& navigator,
+      const String& url_string,
+      const V8UnionReadableStreamOrXMLHttpRequestBodyInit* data,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static bool sendBeacon(
       ScriptState*,
       Navigator&,
       const String&,
       const ReadableStreamOrBlobOrArrayBufferOrArrayBufferViewOrFormDataOrURLSearchParamsOrUSVString&,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor*) const override;
 
  private:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  bool SendBeaconImpl(ScriptState* script_state,
+                      const String& url_string,
+                      const V8UnionReadableStreamOrXMLHttpRequestBodyInit* data,
+                      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool SendBeaconImpl(
       ScriptState*,
       const String&,
       const ReadableStreamOrBlobOrArrayBufferOrArrayBufferViewOrFormDataOrURLSearchParamsOrUSVString&,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool CanSendBeacon(ExecutionContext*, const KURL&, ExceptionState&);
 };
 
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
index b6fb0f1..dc23f839 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -16,11 +16,13 @@
 #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unsignedlong.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_advertising_event_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_data_filter_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_le_scan_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_manufacturer_data_filter_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_request_device_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -44,7 +46,6 @@
 
 namespace blink {
 
-namespace {
 // Per the Bluetooth Spec: The name is a user-friendly name associated with the
 // device and consists of a maximum of 248 bytes coded according to the UTF-8
 // standard.
@@ -54,6 +55,24 @@
 const char kInactiveDocumentError[] = "Document not active";
 const char kHandleGestureForPermissionRequest[] =
     "Must be handling a user gesture to show a permission request.";
+
+namespace {
+
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// TODO(crbug.com/1181288): Remove the old IDL union version.
+V8BluetoothServiceUUID* ToV8BluetoothServiceUUID(
+    const StringOrUnsignedLong& uuid) {
+  if (uuid.IsString()) {
+    return MakeGarbageCollected<V8BluetoothServiceUUID>(uuid.GetAsString());
+  } else if (uuid.IsUnsignedLong()) {
+    return MakeGarbageCollected<V8BluetoothServiceUUID>(
+        uuid.GetAsUnsignedLong());
+  }
+  NOTREACHED();
+  return nullptr;
+}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 }  // namespace
 
 // Remind developers when they are using Web Bluetooth on unsupported platforms.
@@ -90,8 +109,13 @@
     }
     canonicalized_filter->services.emplace();
     for (const StringOrUnsignedLong& service : filter->services()) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const String& validated_service = BluetoothUUID::getService(
+          ToV8BluetoothServiceUUID(service), exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const String& validated_service =
           BluetoothUUID::getService(service, exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       if (exception_state.HadException())
         return;
       canonicalized_filter->services->push_back(validated_service);
@@ -232,8 +256,13 @@
   if (options->hasOptionalServices()) {
     for (const StringOrUnsignedLong& optional_service :
          options->optionalServices()) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const String& validated_optional_service = BluetoothUUID::getService(
+          ToV8BluetoothServiceUUID(optional_service), exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const String& validated_optional_service =
           BluetoothUUID::getService(optional_service, exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       if (exception_state.HadException())
         return;
       result->optional_services.push_back(validated_optional_service);
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc
index e26586d..74a9578 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unsignedlong.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_unsigned_long.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_advertising_event_init.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -20,12 +21,28 @@
     : Event(event_type, initializer),
       device_(initializer->device()),
       name_(initializer->name()),
+#if !defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       uuids_(initializer->uuids()),
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       appearance_(initializer->hasAppearance() ? initializer->appearance() : 0),
       txPower_(initializer->hasTxPower() ? initializer->txPower() : 0),
       rssi_(initializer->hasRssi() ? initializer->rssi() : 0),
       manufacturer_data_map_(initializer->manufacturerData()),
-      service_data_map_(initializer->serviceData()) {}
+      service_data_map_(initializer->serviceData()) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  for (const auto& uuid : initializer->uuids()) {
+    if (uuid.IsString()) {
+      uuids_.push_back(
+          MakeGarbageCollected<V8UnionUUIDOrUnsignedLong>(uuid.GetAsString()));
+    } else if (uuid.IsUnsignedLong()) {
+      uuids_.push_back(MakeGarbageCollected<V8UnionUUIDOrUnsignedLong>(
+          uuid.GetAsUnsignedLong()));
+    } else {
+      NOTREACHED();
+    }
+  }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+}
 
 BluetoothAdvertisingEvent::BluetoothAdvertisingEvent(
     const AtomicString& event_type,
@@ -42,9 +59,13 @@
       service_data_map_(MakeGarbageCollected<BluetoothServiceDataMap>(
           advertising_event->service_data)) {
   for (const String& uuid : advertising_event->uuids) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    uuids_.push_back(MakeGarbageCollected<V8UnionUUIDOrUnsignedLong>(uuid));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     StringOrUnsignedLong value;
     value.SetString(uuid);
     uuids_.push_back(value);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   }
 }  // namespace blink
 
@@ -70,10 +91,17 @@
   return name_;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+const HeapVector<Member<V8UnionUUIDOrUnsignedLong>>&
+BluetoothAdvertisingEvent::uuids() const {
+  return uuids_;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 const HeapVector<StringOrUnsignedLong>& BluetoothAdvertisingEvent::uuids()
     const {
   return uuids_;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 BluetoothManufacturerDataMap* BluetoothAdvertisingEvent::manufacturerData()
     const {
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h
index 6a74852f..2af6344 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_ADVERTISING_EVENT_H_
 
 #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
 
 namespace blink {
@@ -36,7 +37,11 @@
 
   BluetoothDevice* device() const;
   const String& name() const;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const HeapVector<Member<V8UnionUUIDOrUnsignedLong>>& uuids() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   const HeapVector<StringOrUnsignedLong>& uuids() const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   base::Optional<uint16_t> appearance() const { return appearance_; }
   base::Optional<int8_t> txPower() const { return txPower_; }
   base::Optional<int8_t> rssi() const { return rssi_; }
@@ -46,7 +51,11 @@
  private:
   Member<BluetoothDevice> device_;
   String name_;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8UnionUUIDOrUnsignedLong>> uuids_;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<StringOrUnsignedLong> uuids_;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   base::Optional<uint16_t> appearance_;
   base::Optional<int8_t> txPower_;
   base::Optional<int8_t> rssi_;
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
index c9703c8..675920b3 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
@@ -346,7 +346,11 @@
 
 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptor(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BluetoothDescriptorUUID* descriptor_uuid,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const StringOrUnsignedLong& descriptor_uuid,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   String descriptor =
       BluetoothUUID::getDescriptor(descriptor_uuid, exception_state);
@@ -368,7 +372,11 @@
 
 ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BluetoothDescriptorUUID* descriptor_uuid,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const StringOrUnsignedLong& descriptor_uuid,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   String descriptor =
       BluetoothUUID::getDescriptor(descriptor_uuid, exception_state);
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
index 53bec76..3b5b4678 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h"
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h"
@@ -73,13 +74,21 @@
   String uuid() { return characteristic_->uuid; }
   BluetoothCharacteristicProperties* properties() { return properties_; }
   DOMDataView* value() const { return value_; }
-  ScriptPromise getDescriptor(ScriptState*,
-                              const StringOrUnsignedLong& descriptor,
-                              ExceptionState&);
+  ScriptPromise getDescriptor(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                              const V8BluetoothDescriptorUUID* descriptor_uuid,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                              const StringOrUnsignedLong& descriptor_uuid,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                              ExceptionState& exception_state);
   ScriptPromise getDescriptors(ScriptState*, ExceptionState&);
-  ScriptPromise getDescriptors(ScriptState*,
-                               const StringOrUnsignedLong& descriptor,
-                               ExceptionState&);
+  ScriptPromise getDescriptors(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                               const V8BluetoothDescriptorUUID* descriptor_uuid,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                               const StringOrUnsignedLong& descriptor_uuid,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                               ExceptionState& exception_state);
   ScriptPromise readValue(ScriptState*, ExceptionState&);
   ScriptPromise writeValue(ScriptState*, const DOMArrayPiece&, ExceptionState&);
   ScriptPromise writeValueWithResponse(ScriptState*,
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
index 1eecb8d..3dba1c4b 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
@@ -167,7 +167,11 @@
 
 ScriptPromise BluetoothRemoteGATTServer::getPrimaryService(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BluetoothServiceUUID* service,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const StringOrUnsignedLong& service,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   String service_uuid = BluetoothUUID::getService(service, exception_state);
   if (exception_state.HadException())
@@ -180,7 +184,11 @@
 
 ScriptPromise BluetoothRemoteGATTServer::getPrimaryServices(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BluetoothServiceUUID* service,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const StringOrUnsignedLong& service,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   String service_uuid = BluetoothUUID::getService(service, exception_state);
   if (exception_state.HadException())
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h
index ecb63dc..025d767b 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_unsigned_long.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
 #include "third_party/blink/renderer/modules/bluetooth/bluetooth_device.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -68,12 +69,21 @@
   bool connected() { return connected_; }
   ScriptPromise connect(ScriptState*);
   void disconnect(ScriptState*);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise getPrimaryService(ScriptState* script_state,
+                                  const V8BluetoothServiceUUID* service,
+                                  ExceptionState& exception_state);
+  ScriptPromise getPrimaryServices(ScriptState* script_state,
+                                   const V8BluetoothServiceUUID* service,
+                                   ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise getPrimaryService(ScriptState*,
                                   const StringOrUnsignedLong& service,
                                   ExceptionState&);
   ScriptPromise getPrimaryServices(ScriptState*,
                                    const StringOrUnsignedLong& service,
                                    ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise getPrimaryServices(ScriptState*, ExceptionState&);
 
  private:
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
index 54f4a41e..826be91 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h"
 
 #include <utility>
+
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -89,7 +90,11 @@
 
 ScriptPromise BluetoothRemoteGATTService::getCharacteristic(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BluetoothCharacteristicUUID* characteristic,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const StringOrUnsignedLong& characteristic,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   String characteristic_uuid =
       BluetoothUUID::getCharacteristic(characteristic, exception_state);
@@ -103,7 +108,11 @@
 
 ScriptPromise BluetoothRemoteGATTService::getCharacteristics(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BluetoothCharacteristicUUID* characteristic,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const StringOrUnsignedLong& characteristic,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   String characteristic_uuid =
       BluetoothUUID::getCharacteristic(characteristic, exception_state);
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h
index 246ddfa..edf2dc1 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_unsigned_long.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/modules/bluetooth/bluetooth_device.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -43,12 +44,23 @@
   String uuid() { return service_->uuid; }
   bool isPrimary() { return is_primary_; }
   BluetoothDevice* device() { return device_; }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise getCharacteristic(
+      ScriptState* script_state,
+      const V8BluetoothCharacteristicUUID* characteristic,
+      ExceptionState& exception_state);
+  ScriptPromise getCharacteristics(
+      ScriptState* script_state,
+      const V8BluetoothCharacteristicUUID* characteristic,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise getCharacteristic(ScriptState*,
                                   const StringOrUnsignedLong& characteristic,
                                   ExceptionState&);
   ScriptPromise getCharacteristics(ScriptState*,
                                    const StringOrUnsignedLong& characteristic,
                                    ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise getCharacteristics(ScriptState*, ExceptionState&);
 
  private:
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.cc
index 2fb29d7..d3f4f27 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_unsignedlong.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -317,8 +318,16 @@
 }
 
 String GetUUIDForGATTAttribute(GATTAttribute attribute,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                               const V8UnionStringOrUnsignedLong* name_arg,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                StringOrUnsignedLong name,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DCHECK(name_arg);
+  const V8UnionStringOrUnsignedLong& name = *name_arg;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // Implementation of BluetoothUUID.getService, BluetoothUUID.getCharacteristic
   // and BluetoothUUID.getDescriptor algorithms:
   // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-getservice
@@ -393,22 +402,37 @@
 }  // namespace
 
 // static
-String BluetoothUUID::getService(StringOrUnsignedLong name,
-                                 ExceptionState& exception_state) {
+String BluetoothUUID::getService(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BluetoothServiceUUID* name,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    StringOrUnsignedLong name,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   return GetUUIDForGATTAttribute(GATTAttribute::kService, name,
                                  exception_state);
 }
 
 // static
-String BluetoothUUID::getCharacteristic(StringOrUnsignedLong name,
-                                        ExceptionState& exception_state) {
+String BluetoothUUID::getCharacteristic(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BluetoothCharacteristicUUID* name,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    StringOrUnsignedLong name,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   return GetUUIDForGATTAttribute(GATTAttribute::kCharacteristic, name,
                                  exception_state);
 }
 
 // static
-String BluetoothUUID::getDescriptor(StringOrUnsignedLong name,
-                                    ExceptionState& exception_state) {
+String BluetoothUUID::getDescriptor(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BluetoothDescriptorUUID* name,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    StringOrUnsignedLong name,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   return GetUUIDForGATTAttribute(GATTAttribute::kDescriptor, name,
                                  exception_state);
 }
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h
index 60e9328..0fd2d1b 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_UUID_H_
 
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_unsigned_long.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 
@@ -20,9 +21,18 @@
 
  public:
   // IDL exposed interface:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static String getService(const V8BluetoothServiceUUID* name,
+                           ExceptionState& exception_state);
+  static String getCharacteristic(const V8BluetoothCharacteristicUUID* name,
+                                  ExceptionState& exception_state);
+  static String getDescriptor(const V8BluetoothDescriptorUUID* name,
+                              ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static String getService(StringOrUnsignedLong name, ExceptionState&);
   static String getCharacteristic(StringOrUnsignedLong name, ExceptionState&);
   static String getDescriptor(StringOrUnsignedLong name, ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static String canonicalUUID(unsigned alias);
 };
 
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc
index 5482ce9..fae4122f 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_request_init.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_response.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_request_usvstring.h"
 #include "third_party/blink/renderer/core/dom/abort_controller.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -742,6 +743,27 @@
   mojom::blink::FetchAPIResponsePtr fetch_api_response_;
 };
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+ScriptPromise Cache::match(ScriptState* script_state,
+                           const V8RequestInfo* request,
+                           const CacheQueryOptions* options,
+                           ExceptionState& exception_state) {
+  DCHECK(request);
+  Request* request_object = nullptr;
+  switch (request->GetContentType()) {
+    case V8RequestInfo::ContentType::kRequest:
+      request_object = request->GetAsRequest();
+      break;
+    case V8RequestInfo::ContentType::kUSVString:
+      request_object = Request::Create(script_state, request->GetAsUSVString(),
+                                       exception_state);
+      if (exception_state.HadException())
+        return ScriptPromise();
+      break;
+  }
+  return MatchImpl(script_state, request_object, options);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 ScriptPromise Cache::match(ScriptState* script_state,
                            const RequestInfo& request,
                            const CacheQueryOptions* options,
@@ -755,12 +777,34 @@
     return ScriptPromise();
   return MatchImpl(script_state, new_request, options);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 ScriptPromise Cache::matchAll(ScriptState* script_state,
                               ExceptionState& exception_state) {
   return MatchAllImpl(script_state, nullptr, CacheQueryOptions::Create());
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+ScriptPromise Cache::matchAll(ScriptState* script_state,
+                              const V8RequestInfo* request,
+                              const CacheQueryOptions* options,
+                              ExceptionState& exception_state) {
+  DCHECK(request);
+  Request* request_object = nullptr;
+  switch (request->GetContentType()) {
+    case V8RequestInfo::ContentType::kRequest:
+      request_object = request->GetAsRequest();
+      break;
+    case V8RequestInfo::ContentType::kUSVString:
+      request_object = Request::Create(script_state, request->GetAsUSVString(),
+                                       exception_state);
+      if (exception_state.HadException())
+        return ScriptPromise();
+      break;
+  }
+  return MatchAllImpl(script_state, request_object, options);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 ScriptPromise Cache::matchAll(ScriptState* script_state,
                               const RequestInfo& request,
                               const CacheQueryOptions* options,
@@ -774,7 +818,28 @@
     return ScriptPromise();
   return MatchAllImpl(script_state, new_request, options);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+ScriptPromise Cache::add(ScriptState* script_state,
+                         const V8RequestInfo* request,
+                         ExceptionState& exception_state) {
+  DCHECK(request);
+  HeapVector<Member<Request>> requests;
+  switch (request->GetContentType()) {
+    case V8RequestInfo::ContentType::kRequest:
+      requests.push_back(request->GetAsRequest());
+      break;
+    case V8RequestInfo::ContentType::kUSVString:
+      requests.push_back(Request::Create(
+          script_state, request->GetAsUSVString(), exception_state));
+      if (exception_state.HadException())
+        return ScriptPromise();
+      break;
+  }
+  return AddAllImpl(script_state, "Cache.add()", requests, exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 ScriptPromise Cache::add(ScriptState* script_state,
                          const RequestInfo& request,
                          ExceptionState& exception_state) {
@@ -791,7 +856,30 @@
 
   return AddAllImpl(script_state, "Cache.add()", requests, exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+ScriptPromise Cache::addAll(ScriptState* script_state,
+                            const HeapVector<Member<V8RequestInfo>>& requests,
+                            ExceptionState& exception_state) {
+  HeapVector<Member<Request>> request_objects;
+  for (const V8RequestInfo* request : requests) {
+    switch (request->GetContentType()) {
+      case V8RequestInfo::ContentType::kRequest:
+        request_objects.push_back(request->GetAsRequest());
+        break;
+      case V8RequestInfo::ContentType::kUSVString:
+        request_objects.push_back(Request::Create(
+            script_state, request->GetAsUSVString(), exception_state));
+        if (exception_state.HadException())
+          return ScriptPromise();
+        break;
+    }
+  }
+  return AddAllImpl(script_state, "Cache.addAll()", request_objects,
+                    exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 ScriptPromise Cache::addAll(ScriptState* script_state,
                             const HeapVector<RequestInfo>& raw_requests,
                             ExceptionState& exception_state) {
@@ -809,7 +897,29 @@
 
   return AddAllImpl(script_state, "Cache.addAll()", requests, exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+ScriptPromise Cache::Delete(ScriptState* script_state,
+                            const V8RequestInfo* request,
+                            const CacheQueryOptions* options,
+                            ExceptionState& exception_state) {
+  DCHECK(request);
+  Request* request_object = nullptr;
+  switch (request->GetContentType()) {
+    case V8RequestInfo::ContentType::kRequest:
+      request_object = request->GetAsRequest();
+      break;
+    case V8RequestInfo::ContentType::kUSVString:
+      request_object = Request::Create(script_state, request->GetAsUSVString(),
+                                       exception_state);
+      if (exception_state.HadException())
+        return ScriptPromise();
+      break;
+  }
+  return DeleteImpl(script_state, request_object, options);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 ScriptPromise Cache::Delete(ScriptState* script_state,
                             const RequestInfo& request,
                             const CacheQueryOptions* options,
@@ -823,15 +933,38 @@
     return ScriptPromise();
   return DeleteImpl(script_state, new_request, options);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 ScriptPromise Cache::put(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                         const V8RequestInfo* request_info,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                          const RequestInfo& request_info,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                          Response* response,
                          ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DCHECK(request_info);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DCHECK(!request_info.IsNull());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   int64_t trace_id = blink::cache_storage::CreateTraceId();
   TRACE_EVENT_WITH_FLOW0("CacheStorage", "Cache::put",
                          TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Request* request = nullptr;
+  switch (request_info->GetContentType()) {
+    case V8RequestInfo::ContentType::kRequest:
+      request = request_info->GetAsRequest();
+      break;
+    case V8RequestInfo::ContentType::kUSVString:
+      request = Request::Create(script_state, request_info->GetAsUSVString(),
+                                exception_state);
+      if (exception_state.HadException())
+        return ScriptPromise();
+      break;
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Request* request =
       request_info.IsRequest()
           ? request_info.GetAsRequest()
@@ -839,6 +972,7 @@
                             exception_state);
   if (exception_state.HadException())
     return ScriptPromise();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   ValidateRequestForPut(request, exception_state);
   if (exception_state.HadException())
@@ -863,6 +997,27 @@
   return KeysImpl(script_state, nullptr, CacheQueryOptions::Create());
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+ScriptPromise Cache::keys(ScriptState* script_state,
+                          const V8RequestInfo* request,
+                          const CacheQueryOptions* options,
+                          ExceptionState& exception_state) {
+  DCHECK(request);
+  Request* request_object = nullptr;
+  switch (request->GetContentType()) {
+    case V8RequestInfo::ContentType::kRequest:
+      request_object = request->GetAsRequest();
+      break;
+    case V8RequestInfo::ContentType::kUSVString:
+      request_object = Request::Create(script_state, request->GetAsUSVString(),
+                                       exception_state);
+      if (exception_state.HadException())
+        return ScriptPromise();
+      break;
+  }
+  return KeysImpl(script_state, request_object, options);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 ScriptPromise Cache::keys(ScriptState* script_state,
                           const RequestInfo& request,
                           const CacheQueryOptions* options,
@@ -876,6 +1031,7 @@
     return ScriptPromise();
   return KeysImpl(script_state, new_request, options);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 Cache::Cache(GlobalFetch::ScopedFetcher* fetcher,
              CacheStorageBlobClientList* blob_client_list,
@@ -1088,8 +1244,12 @@
     if (barrier_callback->Signal())
       request_list[i]->signal()->Follow(barrier_callback->Signal());
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    V8RequestInfo* info = MakeGarbageCollected<V8RequestInfo>(request_list[i]);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     RequestInfo info;
     info.SetRequest(request_list[i]);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
     auto* response_loader = MakeGarbageCollected<ResponseBodyLoader>(
         script_state, barrier_callback, i, /*require_ok_response=*/true,
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.h b/third_party/blink/renderer/modules/cache_storage/cache.h
index 6c33b661..7bec6588 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache.h
+++ b/third_party/blink/renderer/modules/cache_storage/cache.h
@@ -10,6 +10,7 @@
 #include "mojo/public/cpp/bindings/pending_associated_remote.h"
 #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_cache_query_options.h"
 #include "third_party/blink/renderer/core/fetch/global_fetch.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
@@ -58,15 +59,45 @@
         scoped_refptr<base::SingleThreadTaskRunner>);
 
   // From Cache.idl:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise match(ScriptState* script_state,
+                      const V8RequestInfo* request,
+                      const CacheQueryOptions* options,
+                      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise match(ScriptState*,
                       const RequestInfo&,
                       const CacheQueryOptions*,
                       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise matchAll(ScriptState*, ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise matchAll(ScriptState* script_state,
+                         const V8RequestInfo* request,
+                         const CacheQueryOptions* options,
+                         ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise matchAll(ScriptState*,
                          const RequestInfo&,
                          const CacheQueryOptions*,
                          ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise add(ScriptState* script_state,
+                    const V8RequestInfo* request,
+                    ExceptionState& exception_state);
+  ScriptPromise addAll(ScriptState* script_state,
+                       const HeapVector<Member<V8RequestInfo>>& requests,
+                       ExceptionState& exception_state);
+  ScriptPromise Delete(ScriptState* script_state,
+                       const V8RequestInfo* request,
+                       const CacheQueryOptions* options,
+                       ExceptionState& exception_state);
+  ScriptPromise put(ScriptState* script_state,
+                    const V8RequestInfo* request,
+                    Response* response,
+                    ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise add(ScriptState*, const RequestInfo&, ExceptionState&);
   ScriptPromise addAll(ScriptState*,
                        const HeapVector<RequestInfo>&,
@@ -79,11 +110,19 @@
                     const RequestInfo&,
                     Response*,
                     ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise keys(ScriptState*, ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise keys(ScriptState* script_state,
+                     const V8RequestInfo* request,
+                     const CacheQueryOptions* options,
+                     ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise keys(ScriptState*,
                      const RequestInfo&,
                      const CacheQueryOptions*,
                      ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_storage.cc b/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
index 38dbb33c..ba19d0c4 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
@@ -13,6 +13,7 @@
 #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
 #include "third_party/blink/public/platform/web_content_settings_client.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_request_usvstring.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_multi_cache_query_options.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -330,6 +331,27 @@
   return promise;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+ScriptPromise CacheStorage::match(ScriptState* script_state,
+                                  const V8RequestInfo* request,
+                                  const MultiCacheQueryOptions* options,
+                                  ExceptionState& exception_state) {
+  DCHECK(request);
+  Request* request_object = nullptr;
+  switch (request->GetContentType()) {
+    case V8RequestInfo::ContentType::kRequest:
+      request_object = request->GetAsRequest();
+      break;
+    case V8RequestInfo::ContentType::kUSVString:
+      request_object = Request::Create(script_state, request->GetAsUSVString(),
+                                       exception_state);
+      if (exception_state.HadException())
+        return ScriptPromise();
+      break;
+  }
+  return MatchImpl(script_state, request_object, options);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 ScriptPromise CacheStorage::match(ScriptState* script_state,
                                   const RequestInfo& request,
                                   const MultiCacheQueryOptions* options,
@@ -344,6 +366,7 @@
     return ScriptPromise();
   return MatchImpl(script_state, new_request, options);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state,
                                       const Request* request,
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_storage.h b/third_party/blink/renderer/modules/cache_storage/cache_storage.h
index 84fbfbb3..b42b65d3d 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache_storage.h
+++ b/third_party/blink/renderer/modules/cache_storage/cache_storage.h
@@ -10,6 +10,7 @@
 #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink-forward.h"
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
 #include "third_party/blink/renderer/core/fetch/global_fetch.h"
 #include "third_party/blink/renderer/modules/cache_storage/cache.h"
@@ -37,10 +38,17 @@
   ScriptPromise has(ScriptState*, const String& cache_name);
   ScriptPromise Delete(ScriptState*, const String& cache_name);
   ScriptPromise keys(ScriptState*);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise match(ScriptState* script_state,
+                      const V8RequestInfo* request,
+                      const MultiCacheQueryOptions* options,
+                      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise match(ScriptState*,
                       const RequestInfo&,
                       const MultiCacheQueryOptions*,
                       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   bool HasPendingActivity() const override;
   void Trace(Visitor*) const override;
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_test.cc b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
index 6bebd1beba..d5e9478 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache_test.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
@@ -29,6 +29,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_request_init.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_response.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_response_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_request_usvstring.h"
 #include "third_party/blink/renderer/core/dom/abort_controller.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -60,16 +61,30 @@
   ScopedFetcherForTests() = default;
 
   ScriptPromise Fetch(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                      const V8RequestInfo* request_info,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                       const RequestInfo& request_info,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                       const RequestInit*,
                       ExceptionState& exception_state) override {
     ++fetch_count_;
     if (expected_url_) {
-      String fetched_url;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      switch (request_info->GetContentType()) {
+        case V8RequestInfo::ContentType::kRequest:
+          EXPECT_EQ(*expected_url_, request_info->GetAsRequest()->url());
+          break;
+        case V8RequestInfo::ContentType::kUSVString:
+          EXPECT_EQ(*expected_url_, request_info->GetAsUSVString());
+          break;
+      }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       if (request_info.IsRequest())
         EXPECT_EQ(*expected_url_, request_info.GetAsRequest()->url());
       else
         EXPECT_EQ(*expected_url_, request_info.GetAsUSVString());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     }
 
     if (response_) {
@@ -374,6 +389,15 @@
       receiver_;
 };
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8RequestInfo* RequestToRequestInfo(Request* value) {
+  return MakeGarbageCollected<V8RequestInfo>(value);
+}
+
+V8RequestInfo* StringToRequestInfo(const String& value) {
+  return MakeGarbageCollected<V8RequestInfo>(value);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 RequestInfo StringToRequestInfo(const String& value) {
   RequestInfo info;
   info.SetUSVString(value);
@@ -385,6 +409,7 @@
   info.SetRequest(value);
   return info;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 TEST_F(CacheStorageTest, Basics) {
   ScriptState::Scope scope(GetScriptState());
@@ -820,7 +845,11 @@
   Response* response = Response::error(GetScriptState());
   fetcher->SetResponse(response);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8RequestInfo>> info_list;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<RequestInfo> info_list;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   info_list.push_back(RequestToRequestInfo(request));
 
   ScriptPromise promise =
@@ -849,7 +878,11 @@
   Response* response = Response::error(GetScriptState());
   fetcher->SetResponse(response);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8RequestInfo>> info_list;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<RequestInfo> info_list;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   info_list.push_back(RequestToRequestInfo(request));
   info_list.push_back(RequestToRequestInfo(request));
 
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index e5eb187..d4c16171 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -12,6 +12,8 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/numerics/checked_math.h"
 #include "third_party/blink/public/common/features.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_canvasfilter_string.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_csscolorvalue_canvasgradient_canvaspattern_string.h"
 #include "third_party/blink/renderer/core/css/cssom/css_color_value.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser.h"
 #include "third_party/blink/renderer/core/html/canvas/text_metrics.h"
@@ -170,6 +172,22 @@
   origin_tainted_by_content_ = false;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+static V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString*
+ConvertCanvasStyleToUnionType(CanvasStyle* style) {
+  if (CanvasGradient* gradient = style->GetCanvasGradient()) {
+    return MakeGarbageCollected<
+        V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>(gradient);
+  }
+  if (CanvasPattern* pattern = style->GetCanvasPattern()) {
+    return MakeGarbageCollected<
+        V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>(pattern);
+  }
+  return MakeGarbageCollected<
+      V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>(
+      style->GetColorAsString());
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 static inline void ConvertCanvasStyleToUnionType(
     CanvasStyle* style,
     StringOrCanvasGradientOrCanvasPatternOrCSSColorValue& return_value) {
@@ -183,7 +201,33 @@
   }
   return_value.SetString(style->GetColorAsString());
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void BaseRenderingContext2D::IdentifiabilityMaybeUpdateForStyleUnion(
+    const V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString* style) {
+  switch (style->GetContentType()) {
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kCSSColorValue:
+      break;
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kCanvasGradient:
+      identifiability_study_helper_.MaybeUpdateBuilder(
+          style->GetAsCanvasGradient()->GetIdentifiableToken());
+      break;
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kCanvasPattern:
+      identifiability_study_helper_.MaybeUpdateBuilder(
+          style->GetAsCanvasPattern()->GetIdentifiableToken());
+      break;
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kString:
+      identifiability_study_helper_.MaybeUpdateBuilder(
+          IdentifiabilityBenignStringToken(style->GetAsString()));
+      break;
+  }
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void BaseRenderingContext2D::IdentifiabilityMaybeUpdateForStyleUnion(
     const StringOrCanvasGradientOrCanvasPatternOrCSSColorValue& style) {
   if (style.IsString()) {
@@ -197,6 +241,7 @@
         style.GetAsCanvasGradient()->GetIdentifiableToken());
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 RespectImageOrientationEnum
 BaseRenderingContext2D::RespectImageOrientationInternal(
@@ -207,6 +252,68 @@
   return RespectImageOrientation();
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString*
+BaseRenderingContext2D::strokeStyle() const {
+  return ConvertCanvasStyleToUnionType(GetState().StrokeStyle());
+}
+
+void BaseRenderingContext2D::setStrokeStyle(
+    const V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString* style) {
+  DCHECK(style);
+
+  identifiability_study_helper_.MaybeUpdateBuilder(CanvasOps::kSetStrokeStyle);
+  IdentifiabilityMaybeUpdateForStyleUnion(style);
+
+  String color_string;
+  CanvasStyle* canvas_style = nullptr;
+  switch (style->GetContentType()) {
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kCSSColorValue:
+      if (!RuntimeEnabledFeatures::NewCanvas2DAPIEnabled())
+        return;
+      canvas_style = MakeGarbageCollected<CanvasStyle>(
+          style->GetAsCSSColorValue()->ToColor().Rgb());
+      break;
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kCanvasGradient:
+      canvas_style =
+          MakeGarbageCollected<CanvasStyle>(style->GetAsCanvasGradient());
+      break;
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kCanvasPattern: {
+      CanvasPattern* canvas_pattern = style->GetAsCanvasPattern();
+      if (!origin_tainted_by_content_ && !canvas_pattern->OriginClean())
+        SetOriginTaintedByContent();
+      canvas_style = MakeGarbageCollected<CanvasStyle>(canvas_pattern);
+      break;
+    }
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kString: {
+      color_string = style->GetAsString();
+      if (color_string == GetState().UnparsedStrokeColor())
+        return;
+      Color parsed_color = 0;
+      if (!ParseColorOrCurrentColor(parsed_color, color_string))
+        return;
+      if (GetState().StrokeStyle()->IsEquivalentRGBA(parsed_color.Rgb())) {
+        GetState().SetUnparsedStrokeColor(color_string);
+        return;
+      }
+      canvas_style = MakeGarbageCollected<CanvasStyle>(parsed_color.Rgb());
+      break;
+    }
+  }
+
+  DCHECK(canvas_style);
+  GetState().SetStrokeStyle(canvas_style);
+  GetState().SetUnparsedStrokeColor(color_string);
+  GetState().ClearResolvedFilter();
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void BaseRenderingContext2D::strokeStyle(
     StringOrCanvasGradientOrCanvasPatternOrCSSColorValue& return_value) const {
   ConvertCanvasStyleToUnionType(GetState().StrokeStyle(), return_value);
@@ -257,6 +364,71 @@
   GetState().ClearResolvedFilter();
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString*
+BaseRenderingContext2D::fillStyle() const {
+  return ConvertCanvasStyleToUnionType(GetState().FillStyle());
+}
+
+void BaseRenderingContext2D::setFillStyle(
+    const V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString* style) {
+  DCHECK(style);
+
+  ValidateStateStack();
+  identifiability_study_helper_.MaybeUpdateBuilder(CanvasOps::kSetFillStyle);
+  IdentifiabilityMaybeUpdateForStyleUnion(style);
+
+  String color_string;
+  CanvasStyle* canvas_style = nullptr;
+  switch (style->GetContentType()) {
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kCSSColorValue:
+      if (!RuntimeEnabledFeatures::NewCanvas2DAPIEnabled())
+        return;
+      canvas_style = MakeGarbageCollected<CanvasStyle>(
+          style->GetAsCSSColorValue()->ToColor().Rgb());
+      break;
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kCanvasGradient:
+      canvas_style =
+          MakeGarbageCollected<CanvasStyle>(style->GetAsCanvasGradient());
+      break;
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kCanvasPattern: {
+      CanvasPattern* canvas_pattern = style->GetAsCanvasPattern();
+      if (!origin_tainted_by_content_ && !canvas_pattern->OriginClean())
+        SetOriginTaintedByContent();
+      canvas_style = MakeGarbageCollected<CanvasStyle>(canvas_pattern);
+      break;
+    }
+    case V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString::
+        ContentType::kString: {
+      color_string = style->GetAsString();
+      if (color_string == GetState().UnparsedFillColor())
+        return;
+      Color parsed_color = 0;
+      if (!ParseColorOrCurrentColor(parsed_color, color_string))
+        return;
+      if (GetState().FillStyle()->IsEquivalentRGBA(parsed_color.Rgb())) {
+        GetState().SetUnparsedFillColor(color_string);
+        return;
+      }
+      canvas_style = MakeGarbageCollected<CanvasStyle>(parsed_color.Rgb());
+      break;
+    }
+  }
+
+  DCHECK(canvas_style);
+  GetState().SetFillStyle(canvas_style);
+  GetState().SetUnparsedFillColor(color_string);
+  GetState().ClearResolvedFilter();
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void BaseRenderingContext2D::fillStyle(
     StringOrCanvasGradientOrCanvasPatternOrCSSColorValue& return_value) const {
   ConvertCanvasStyleToUnionType(GetState().FillStyle(), return_value);
@@ -307,6 +479,8 @@
   GetState().ClearResolvedFilter();
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 double BaseRenderingContext2D::lineWidth() const {
   return GetState().LineWidth();
 }
@@ -461,6 +635,51 @@
   GetState().SetGlobalComposite(sk_blend_mode);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+const V8UnionCanvasFilterOrString* BaseRenderingContext2D::filter() const {
+  if (CanvasFilter* filter = GetState().GetCanvasFilter()) {
+    return MakeGarbageCollected<V8UnionCanvasFilterOrString>(filter);
+  }
+  return MakeGarbageCollected<V8UnionCanvasFilterOrString>(
+      GetState().UnparsedCSSFilter());
+}
+
+void BaseRenderingContext2D::setFilter(
+    const ExecutionContext* execution_context,
+    const V8UnionCanvasFilterOrString* input) {
+  if (!input)
+    return;
+
+  switch (input->GetContentType()) {
+    case V8UnionCanvasFilterOrString::ContentType::kCanvasFilter:
+      if (RuntimeEnabledFeatures::NewCanvas2DAPIEnabled()) {
+        GetState().SetCanvasFilter(input->GetAsCanvasFilter());
+        SnapshotStateForFilter();
+      }
+      break;
+    case V8UnionCanvasFilterOrString::ContentType::kString: {
+      const String& filter_string = input->GetAsString();
+      if (!GetState().GetCanvasFilter() &&
+          filter_string == GetState().UnparsedCSSFilter()) {
+        return;
+      }
+      const CSSValue* css_value = CSSParser::ParseSingleValue(
+          CSSPropertyID::kFilter, filter_string,
+          MakeGarbageCollected<CSSParserContext>(
+              kHTMLStandardMode, execution_context->GetSecureContextMode()));
+      if (!css_value || css_value->IsCSSWideKeyword())
+        return;
+      GetState().SetUnparsedCSSFilter(filter_string);
+      GetState().SetCSSFilter(css_value);
+      SnapshotStateForFilter();
+      break;
+    }
+  }
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void BaseRenderingContext2D::filter(StringOrCanvasFilter& filter) const {
   if (GetState().GetCanvasFilter())
     filter.SetCanvasFilter(GetState().GetCanvasFilter());
@@ -496,6 +715,8 @@
   }
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void BaseRenderingContext2D::scale(double sx, double sy) {
   // TODO(crbug.com/1140535): Investigate the performance impact of simply
   // calling the 3d version of this function
@@ -1263,12 +1484,16 @@
   dst_rect->Move(offset);
 }
 
-void BaseRenderingContext2D::drawImage(
-    ScriptState* script_state,
-    const CanvasImageSourceUnion& image_source,
-    double x,
-    double y,
-    ExceptionState& exception_state) {
+void BaseRenderingContext2D::drawImage(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                       const V8CanvasImageSource* image_source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                       const CanvasImageSourceUnion&
+                                           image_source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                       double x,
+                                       double y,
+                                       ExceptionState& exception_state) {
   CanvasImageSource* image_source_internal =
       ToCanvasImageSource(image_source, exception_state);
   if (!image_source_internal)
@@ -1285,14 +1510,18 @@
             dest_rect_size.Height(), exception_state);
 }
 
-void BaseRenderingContext2D::drawImage(
-    ScriptState* script_state,
-    const CanvasImageSourceUnion& image_source,
-    double x,
-    double y,
-    double width,
-    double height,
-    ExceptionState& exception_state) {
+void BaseRenderingContext2D::drawImage(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                       const V8CanvasImageSource* image_source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                       const CanvasImageSourceUnion&
+                                           image_source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                       double x,
+                                       double y,
+                                       double width,
+                                       double height,
+                                       ExceptionState& exception_state) {
   CanvasImageSource* image_source_internal =
       ToCanvasImageSource(image_source, exception_state);
   if (!image_source_internal)
@@ -1305,18 +1534,22 @@
             source_rect_size.Height(), x, y, width, height, exception_state);
 }
 
-void BaseRenderingContext2D::drawImage(
-    ScriptState* script_state,
-    const CanvasImageSourceUnion& image_source,
-    double sx,
-    double sy,
-    double sw,
-    double sh,
-    double dx,
-    double dy,
-    double dw,
-    double dh,
-    ExceptionState& exception_state) {
+void BaseRenderingContext2D::drawImage(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                       const V8CanvasImageSource* image_source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                       const CanvasImageSourceUnion&
+                                           image_source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                       double sx,
+                                       double sy,
+                                       double sw,
+                                       double sh,
+                                       double dx,
+                                       double dy,
+                                       double dw,
+                                       double dh,
+                                       ExceptionState& exception_state) {
   CanvasImageSource* image_source_internal =
       ToCanvasImageSource(image_source, exception_state);
   if (!image_source_internal)
@@ -1674,6 +1907,22 @@
   return gradient;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CanvasPattern* BaseRenderingContext2D::createPattern(
+    ScriptState* script_state,
+    const V8CanvasImageSource* image_source,
+    const String& repetition_type,
+    ExceptionState& exception_state) {
+  CanvasImageSource* image_source_internal =
+      ToCanvasImageSource(image_source, exception_state);
+  if (!image_source_internal) {
+    return nullptr;
+  }
+
+  return createPattern(script_state, image_source_internal, repetition_type,
+                       exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CanvasPattern* BaseRenderingContext2D::createPattern(
     ScriptState* script_state,
     const CanvasImageSourceUnion& image_source,
@@ -1688,6 +1937,7 @@
   return createPattern(script_state, image_source_internal, repetition_type,
                        exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 CanvasPattern* BaseRenderingContext2D::createPattern(
     ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
index 7dff419..f2d9413a 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/canvas_image_source.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_canvas_filter.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_canvas_gradient_or_canvas_pattern_or_css_color_value.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/geometry/dom_matrix.h"
 #include "third_party/blink/renderer/core/html/canvas/image_data.h"
 #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.h"
@@ -22,23 +23,40 @@
 #include "third_party/blink/renderer/platform/graphics/image_orientation.h"
 
 namespace blink {
+
 class CanvasImageSource;
 class Color;
 class Image;
 class Path2D;
+class V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString;
+class V8UnionCanvasFilterOrString;
 
 class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
                                               public CanvasPath {
  public:
   ~BaseRenderingContext2D() override;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString* strokeStyle()
+      const;
+  void setStrokeStyle(
+      const V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString* style);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void strokeStyle(StringOrCanvasGradientOrCanvasPatternOrCSSColorValue&) const;
   void setStrokeStyle(
       const StringOrCanvasGradientOrCanvasPatternOrCSSColorValue&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString* fillStyle()
+      const;
+  void setFillStyle(
+      const V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString* style);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void fillStyle(StringOrCanvasGradientOrCanvasPatternOrCSSColorValue&) const;
   void setFillStyle(
       const StringOrCanvasGradientOrCanvasPatternOrCSSColorValue&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   double lineWidth() const;
   void setLineWidth(double);
@@ -76,8 +94,14 @@
   String globalCompositeOperation() const;
   void setGlobalCompositeOperation(const String&);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const V8UnionCanvasFilterOrString* filter() const;
+  void setFilter(const ExecutionContext* execution_context,
+                 const V8UnionCanvasFilterOrString* input);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void filter(StringOrCanvasFilter&) const;
   void setFilter(const ExecutionContext*, StringOrCanvasFilter input);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void save();
   void restore();
@@ -165,6 +189,31 @@
   void fillRect(double x, double y, double width, double height);
   void strokeRect(double x, double y, double width, double height);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void drawImage(ScriptState* script_state,
+                 const V8CanvasImageSource* image_source,
+                 double x,
+                 double y,
+                 ExceptionState& exception_state);
+  void drawImage(ScriptState* script_state,
+                 const V8CanvasImageSource* image_source,
+                 double x,
+                 double y,
+                 double width,
+                 double height,
+                 ExceptionState& exception_state);
+  void drawImage(ScriptState* script_state,
+                 const V8CanvasImageSource* image_source,
+                 double sx,
+                 double sy,
+                 double sw,
+                 double sh,
+                 double dx,
+                 double dy,
+                 double dw,
+                 double dh,
+                 ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void drawImage(ScriptState*,
                  const CanvasImageSourceUnion&,
                  double x,
@@ -188,6 +237,7 @@
                  double dw,
                  double dh,
                  ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void drawImage(ScriptState*,
                  CanvasImageSource*,
                  double sx,
@@ -214,10 +264,17 @@
   CanvasGradient* createConicGradient(double startAngle,
                                       double centerX,
                                       double centerY);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  CanvasPattern* createPattern(ScriptState* script_state,
+                               const V8CanvasImageSource* image_source,
+                               const String& repetition_type,
+                               ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CanvasPattern* createPattern(ScriptState*,
                                const CanvasImageSourceUnion&,
                                const String& repetition_type,
                                ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CanvasPattern* createPattern(ScriptState*,
                                CanvasImageSource*,
                                const String& repetition_type,
@@ -542,8 +599,13 @@
                            float height,
                            base::TimeTicks start_time);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void IdentifiabilityMaybeUpdateForStyleUnion(
+      const V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString* style);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void IdentifiabilityMaybeUpdateForStyleUnion(
       const StringOrCanvasGradientOrCanvasPatternOrCSSColorValue& style);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   RespectImageOrientationEnum RespectImageOrientationInternal(
       CanvasImageSource*);
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter.cc
index f28cad9..c12f023 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter.cc
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter.h"
+
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_canvasfilterdictionary_canvasfilterdictionaryarray.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser.h"
 #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter_operation_resolver.h"
 
@@ -13,14 +15,31 @@
 
 CanvasFilter* CanvasFilter::Create(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionCanvasFilterDictionaryOrCanvasFilterDictionaryArray* init,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     CanvasFilterDictionaryOrCanvasFilterDictionaryArray& init,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   HeapVector<Member<CanvasFilterDictionary>> filter_array;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (init->GetContentType()) {
+    case V8UnionCanvasFilterDictionaryOrCanvasFilterDictionaryArray::
+        ContentType::kCanvasFilterDictionary:
+      filter_array.push_back(init->GetAsCanvasFilterDictionary());
+      break;
+    case V8UnionCanvasFilterDictionaryOrCanvasFilterDictionaryArray::
+        ContentType::kCanvasFilterDictionaryArray:
+      filter_array = init->GetAsCanvasFilterDictionaryArray();
+      break;
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (init.IsCanvasFilterDictionary())
     filter_array.push_back(init.GetAsCanvasFilterDictionary());
   else
     filter_array = init.GetAsCanvasFilterDictionaryArray();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   FilterOperations filter_operations =
       CanvasFilterOperationResolver::CreateFilterOperations(
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter.h
index 70f93d3c..3e269f2 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter.h
@@ -13,6 +13,7 @@
 namespace blink {
 
 class ExceptionState;
+class V8UnionCanvasFilterDictionaryOrCanvasFilterDictionaryArray;
 
 // This class stores an unresolved filter on CanvasRenderingContext2DState that
 // has been created from the CanvasFilter javascript object. It will be parsed
@@ -21,10 +22,17 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static CanvasFilter* Create(
+      ScriptState* script_state,
+      const V8UnionCanvasFilterDictionaryOrCanvasFilterDictionaryArray* init,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static CanvasFilter* Create(
       ScriptState*,
       CanvasFilterDictionaryOrCanvasFilterDictionaryArray&,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   explicit CanvasFilter(FilterOperations filter_operations);
 
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc
index b1c046e..34ce2d74 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc
@@ -21,7 +21,6 @@
 
 void CanvasFormattedText::Trace(Visitor* visitor) const {
   visitor->Trace(text_runs_);
-  visitor->Trace(block_);
   ScriptWrappable::Trace(visitor);
 }
 
@@ -42,7 +41,8 @@
   // block flow. In the future we should handle execution_context's from worker
   // threads that do not have a document.
   auto* document = To<LocalDOMWindow>(execution_context)->document();
-  ComputedStyle* style = document->GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style =
+      document->GetStyleResolver().CreateComputedStyle();
   style->SetDisplay(EDisplay::kBlock);
   block_ =
       LayoutBlockFlow::CreateAnonymous(document, style, LegacyLayout::kAuto);
@@ -64,7 +64,8 @@
 LayoutBlockFlow* CanvasFormattedText::GetLayoutBlock(
     Document& document,
     const FontDescription& defaultFont) {
-  ComputedStyle* style = document.GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style =
+      document.GetStyleResolver().CreateComputedStyle();
   style->SetDisplay(EDisplay::kBlock);
   style->SetFontDescription(defaultFont);
   block_->SetStyle(style);
@@ -159,7 +160,8 @@
   LogicalSize available_size = {available_logical_width, kIndefiniteSize};
   builder.SetAvailableSize(available_size);
   NGConstraintSpace space = builder.ToConstraintSpace();
-  const NGLayoutResult* block_results = block_node.Layout(space, nullptr);
+  scoped_refptr<const NGLayoutResult> block_results =
+      block_node.Layout(space, nullptr);
   const auto& fragment =
       To<NGPhysicalBoxFragment>(block_results->PhysicalFragment());
   block->RecalcFragmentsVisualOverflow();
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.h
index 98d7e00..f3284c1e 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.h
@@ -121,7 +121,7 @@
 
  private:
   HeapVector<Member<CanvasFormattedTextRun>> text_runs_;
-  Member<LayoutBlockFlow> block_;
+  LayoutBlockFlow* block_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.cc
index 7f93e60f..9e9054c 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.cc
@@ -16,7 +16,8 @@
   // text. In the future we should handle execution_context's from worker
   // threads that do not have a document.
   auto* document = To<LocalDOMWindow>(execution_context)->document();
-  ComputedStyle* style = document->GetStyleResolver().CreateComputedStyle();
+  scoped_refptr<ComputedStyle> style =
+      document->GetStyleResolver().CreateComputedStyle();
   style->SetDisplay(EDisplay::kInline);
   layout_text_ = LayoutText::CreateAnonymous(*document, std::move(style),
                                              text.Impl(), LegacyLayout::kAuto);
@@ -30,7 +31,6 @@
 }
 
 void CanvasFormattedTextRun::Trace(Visitor* visitor) const {
-  visitor->Trace(layout_text_);
   ScriptWrappable::Trace(visitor);
 }
 
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.h
index 76d22e4..5818ae82 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.h
@@ -42,7 +42,7 @@
  private:
   String text_;
 
-  Member<LayoutText> layout_text_;
+  LayoutText* layout_text_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.cc
index b388139d..12b4b15a 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h"
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_cssimagevalue_htmlcanvaselement_htmlimageelement_htmlvideoelement_imagebitmap_offscreencanvas_svgimageelement_videoframe.h"
 #include "third_party/blink/renderer/core/css/cssom/css_url_image_value.h"
 #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
 #include "third_party/blink/renderer/core/html/html_image_element.h"
@@ -15,6 +16,69 @@
 
 namespace blink {
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+CanvasImageSource* ToCanvasImageSource(const V8CanvasImageSource* value,
+                                       ExceptionState& exception_state) {
+  DCHECK(value);
+
+  switch (value->GetContentType()) {
+    case V8CanvasImageSource::ContentType::kCSSImageValue:
+      return value->GetAsCSSImageValue();
+    case V8CanvasImageSource::ContentType::kHTMLCanvasElement: {
+      if (value->GetAsHTMLCanvasElement()->Size().IsEmpty()) {
+        exception_state.ThrowDOMException(
+            DOMExceptionCode::kInvalidStateError,
+            "The image argument is a canvas element with a width "
+            "or height of 0.");
+        return nullptr;
+      }
+      return value->GetAsHTMLCanvasElement();
+    }
+    case V8CanvasImageSource::ContentType::kHTMLImageElement:
+      return value->GetAsHTMLImageElement();
+    case V8CanvasImageSource::ContentType::kHTMLVideoElement: {
+      HTMLVideoElement* video = value->GetAsHTMLVideoElement();
+      video->VideoWillBeDrawnToCanvas();
+      return video;
+    }
+    case V8CanvasImageSource::ContentType::kImageBitmap:
+      if (value->GetAsImageBitmap()->IsNeutered()) {
+        exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+                                          "The image source is detached");
+        return nullptr;
+      }
+      return value->GetAsImageBitmap();
+    case V8CanvasImageSource::ContentType::kOffscreenCanvas:
+      if (value->GetAsOffscreenCanvas()->IsNeutered()) {
+        exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+                                          "The image source is detached");
+        return nullptr;
+      }
+      if (value->GetAsOffscreenCanvas()->Size().IsEmpty()) {
+        exception_state.ThrowDOMException(
+            DOMExceptionCode::kInvalidStateError,
+            "The image argument is an OffscreenCanvas element "
+            "with a width or height of 0.");
+        return nullptr;
+      }
+      return value->GetAsOffscreenCanvas();
+    case V8CanvasImageSource::ContentType::kSVGImageElement:
+      return value->GetAsSVGImageElement();
+    case V8CanvasImageSource::ContentType::kVideoFrame: {
+      VideoFrame* video_frame = value->GetAsVideoFrame();
+      if (!video_frame->frame()) {
+        exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+                                          "The VideoFrame has been closed");
+        return nullptr;
+      }
+      return video_frame;
+    }
+  }
+
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 CanvasImageSource* ToCanvasImageSource(const CanvasImageSourceUnion& value,
                                        ExceptionState& exception_state) {
   if (value.IsCSSImageValue())
@@ -78,5 +142,6 @@
   NOTREACHED();
   return nullptr;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h
index f003578..ddc55b3 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h
@@ -6,18 +6,26 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_IMAGE_SOURCE_UTIL_H_
 
 #include "third_party/blink/renderer/bindings/modules/v8/canvas_image_source.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 
 namespace blink {
+
 class CanvasImageSource;
 
 using CanvasImageSourceUnion =
     CSSImageValueOrHTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrImageBitmapOrOffscreenCanvasOrVideoFrame;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+MODULES_EXPORT CanvasImageSource* ToCanvasImageSource(
+    const V8CanvasImageSource* value,
+    ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 MODULES_EXPORT CanvasImageSource* ToCanvasImageSource(
     const CanvasImageSourceUnion& value,
     ExceptionState& exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
index 1ce421b..4c470190 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
@@ -36,6 +36,7 @@
 #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h"
 
 #include "base/numerics/safe_conversions.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_dompoint_unrestricteddouble.h"
 #include "third_party/blink/renderer/core/geometry/dom_point.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/geometry/float_rect.h"
@@ -452,7 +453,11 @@
     double double_y,
     double double_width,
     double double_height,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const HeapVector<Member<V8UnionDOMPointOrUnrestrictedDouble>>& radii,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const HeapVector<UnrestrictedDoubleOrDOMPoint, 0> radii,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   const int num_radii = radii.size();
   if (num_radii < 1 || num_radii > 4) {
@@ -475,6 +480,44 @@
 
   FloatSize r[num_radii];
   for (int i = 0; i < num_radii; ++i) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    switch (radii[i]->GetContentType()) {
+      case V8UnionDOMPointOrUnrestrictedDouble::ContentType::kDOMPoint: {
+        DOMPoint* p = radii[i]->GetAsDOMPoint();
+        float r_x = base::saturated_cast<float>(p->x());
+        float r_y = base::saturated_cast<float>(p->y());
+        if (UNLIKELY(!std::isfinite(r_x)) || UNLIKELY(!std::isfinite(r_y)))
+          return;
+        if (UNLIKELY(r_x < 0.0f)) {
+          exception_state.ThrowDOMException(
+              DOMExceptionCode::kIndexSizeError,
+              "X-radius value " + String::Number(r_x) + " is negative.");
+        }
+        if (UNLIKELY(r_y < 0.0f)) {
+          exception_state.ThrowDOMException(
+              DOMExceptionCode::kIndexSizeError,
+              "Y-radius value " + String::Number(r_y) + " is negative.");
+        }
+        r[i] = FloatSize(base::saturated_cast<float>(p->x()),
+                         base::saturated_cast<float>(p->y()));
+        break;
+      }
+      case V8UnionDOMPointOrUnrestrictedDouble::ContentType::
+          kUnrestrictedDouble: {
+        float a =
+            base::saturated_cast<float>(radii[i]->GetAsUnrestrictedDouble());
+        if (UNLIKELY(!std::isfinite(a)))
+          return;
+        if (UNLIKELY(a < 0.0f)) {
+          exception_state.ThrowDOMException(
+              DOMExceptionCode::kIndexSizeError,
+              "Radius value " + String::Number(a) + " is negative.");
+        }
+        r[i] = FloatSize(a, a);
+        break;
+      }
+    }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     if (radii[i].IsUnrestrictedDouble()) {
       float a = base::saturated_cast<float>(radii[i].GetAsUnrestrictedDouble());
       if (UNLIKELY(!std::isfinite(a)))
@@ -504,6 +547,7 @@
       r[i] = FloatSize(base::saturated_cast<float>(p->x()),
                        base::saturated_cast<float>(p->y()));
     }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   }
 
   if (UNLIKELY(width == 0) || UNLIKELY(height == 0)) {
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h
index 740a3e6..954e99e 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h
@@ -40,6 +40,7 @@
 namespace blink {
 
 class ExceptionState;
+class V8UnionDOMPointOrUnrestrictedDouble;
 
 class MODULES_EXPORT CanvasPath : public NoAllocDirectCallHost {
   DISALLOW_NEW();
@@ -86,12 +87,22 @@
             double double_y,
             double double_width,
             double double_height);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void roundRect(
+      double double_x,
+      double double_y,
+      double double_width,
+      double double_height,
+      const HeapVector<Member<V8UnionDOMPointOrUnrestrictedDouble>>& radii,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void roundRect(double double_x,
                  double double_y,
                  double double_width,
                  double double_height,
                  const HeapVector<UnrestrictedDoubleOrDOMPoint, 0> radii,
                  ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   virtual bool IsTransformInvertible() const { return true; }
   virtual TransformationMatrix GetTransform() const {
@@ -104,6 +115,7 @@
   CanvasPath(const Path& path) : path_(path) { path_.SetIsVolatile(true); }
   Path path_;
 };
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_PATH_H_
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
index a010c9f2..78fe811a 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -41,6 +41,7 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/bindings/modules/v8/rendering_context.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_canvasrenderingcontext2d_gpucanvascontext_imagebitmaprenderingcontext_webgl2renderingcontext_webglrenderingcontext.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/css/css_font_selector.h"
 #include "third_party/blink/renderer/core/css/css_property_names.h"
@@ -155,11 +156,21 @@
   ValidateStateStack();
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8RenderingContext* CanvasRenderingContext2D::AsV8RenderingContext() {
+  return MakeGarbageCollected<V8RenderingContext>(this);
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void CanvasRenderingContext2D::SetCanvasGetContextResult(
     RenderingContext& result) {
   result.SetCanvasRenderingContext2D(this);
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 CanvasRenderingContext2D::~CanvasRenderingContext2D() = default;
 
 void CanvasRenderingContext2D::ValidateStateStackWithCanvas(
@@ -537,7 +548,7 @@
 
   // Map the <canvas> font into the text style. If the font uses keywords like
   // larger/smaller, these will work relative to the canvas.
-  ComputedStyle* font_style;
+  scoped_refptr<ComputedStyle> font_style;
   const ComputedStyle* computed_style = canvas()->EnsureComputedStyle();
   if (computed_style) {
     auto i = fonts_resolved_using_current_style_.find(new_font);
@@ -563,7 +574,7 @@
 
       font_style->SetFontDescription(element_font_description);
       canvas()->GetDocument().GetStyleEngine().ComputeFont(
-          *canvas(), font_style, *parsed_style);
+          *canvas(), font_style.get(), *parsed_style);
 
       // We need to reset Computed and Adjusted size so we skip zoom and
       // minimum font size.
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
index fa98fae0..40abded 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
@@ -104,7 +104,11 @@
     DCHECK(!Host() || !Host()->IsOffscreenCanvas());
     return static_cast<HTMLCanvasElement*>(Host());
   }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8RenderingContext* AsV8RenderingContext() final;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void SetCanvasGetContextResult(RenderingContext&) final;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   bool isContextLost() const override;
 
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc
index 6e191f6..113e333 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc
@@ -5,12 +5,15 @@
 #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h"
 
 #include <memory>
+
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
 #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings_provider.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_float32array_uint16array_uint8clampedarray.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_canvas_gradient_or_canvas_pattern_or_css_color_value.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_hit_region_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_csscolorvalue_canvasgradient_canvaspattern_string.h"
 #include "third_party/blink/renderer/core/accessibility/ax_context.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -137,6 +140,17 @@
 
 String TrySettingStrokeStyle(CanvasRenderingContext2D* ctx,
                              const String& value) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ctx->setStrokeStyle(
+      MakeGarbageCollected<
+          V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>("#666"));
+  ctx->setStrokeStyle(
+      MakeGarbageCollected<
+          V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>(value));
+  auto* style = ctx->strokeStyle();
+  EXPECT_TRUE(style->IsString());
+  return style->GetAsString();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrCanvasGradientOrCanvasPatternOrCSSColorValue arg1, arg2, arg3;
   arg1.SetString("#666");
   ctx->setStrokeStyle(arg1);
@@ -145,9 +159,21 @@
   ctx->strokeStyle(arg3);
   EXPECT_TRUE(arg3.IsString());
   return arg3.GetAsString();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 String TrySettingFillStyle(CanvasRenderingContext2D* ctx, const String& value) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ctx->setFillStyle(
+      MakeGarbageCollected<
+          V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>("#666"));
+  ctx->setFillStyle(
+      MakeGarbageCollected<
+          V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>(value));
+  auto* style = ctx->fillStyle();
+  EXPECT_TRUE(style->IsString());
+  return style->GetAsString();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrCanvasGradientOrCanvasPatternOrCSSColorValue arg1, arg2, arg3;
   arg1.SetString("#666");
   ctx->setFillStyle(arg1);
@@ -156,6 +182,7 @@
   ctx->fillStyle(arg3);
   EXPECT_TRUE(arg3.IsString());
   return arg3.GetAsString();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 String TrySettingShadowColor(CanvasRenderingContext2D* ctx,
@@ -191,17 +218,29 @@
   CreateContext(kNonOpaque);
 
   {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* style = Context2D()->strokeStyle();
+    EXPECT_TRUE(style->IsString());
+    EXPECT_EQ(String("#000000"), style->GetAsString());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     StringOrCanvasGradientOrCanvasPatternOrCSSColorValue value;
     Context2D()->strokeStyle(value);
     EXPECT_TRUE(value.IsString());
     EXPECT_EQ(String("#000000"), value.GetAsString());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   }
 
   {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* style = Context2D()->fillStyle();
+    EXPECT_TRUE(style->IsString());
+    EXPECT_EQ(String("#000000"), style->GetAsString());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     StringOrCanvasGradientOrCanvasPatternOrCSSColorValue value;
     Context2D()->fillStyle(value);
     EXPECT_TRUE(value.IsString());
     EXPECT_EQ(String("#000000"), value.GetAsString());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   }
 
   EXPECT_EQ(String("rgba(0, 0, 0, 0)"), Context2D()->shadowColor());
@@ -237,12 +276,21 @@
   EXPECT_EQ(100, image_data->width());
   EXPECT_EQ(50, image_data->height());
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  for (size_t i = 0; i < image_data->data()->GetAsUint8ClampedArray()->length();
+       ++i) {
+    image_data->data()->GetAsUint8ClampedArray()->Data()[i] = 255;
+  }
+
+  EXPECT_EQ(255, image_data->data()->GetAsUint8ClampedArray()->Data()[32]);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   for (size_t i = 0; i < image_data->data().GetAsUint8ClampedArray()->length();
        ++i) {
     image_data->data().GetAsUint8ClampedArray()->Data()[i] = 255;
   }
 
   EXPECT_EQ(255, image_data->data().GetAsUint8ClampedArray()->Data()[32]);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // createImageData(imageData) should create a new ImageData of the same size
   // as 'imageData' but filled with transparent black
@@ -252,8 +300,13 @@
   EXPECT_FALSE(exception_state.HadException());
   EXPECT_EQ(100, same_size_image_data->width());
   EXPECT_EQ(50, same_size_image_data->height());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  EXPECT_EQ(0,
+            same_size_image_data->data()->GetAsUint8ClampedArray()->Data()[32]);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ(0,
             same_size_image_data->data().GetAsUint8ClampedArray()->Data()[32]);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // createImageData(width, height) takes the absolute magnitude of the size
   // arguments
@@ -271,10 +324,17 @@
       Context2D()->createImageData(-10, -20, settings, exception_state);
   EXPECT_FALSE(exception_state.HadException());
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  EXPECT_EQ(800u, imgdata1->data()->GetAsUint8ClampedArray()->length());
+  EXPECT_EQ(800u, imgdata2->data()->GetAsUint8ClampedArray()->length());
+  EXPECT_EQ(800u, imgdata3->data()->GetAsUint8ClampedArray()->length());
+  EXPECT_EQ(800u, imgdata4->data()->GetAsUint8ClampedArray()->length());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   EXPECT_EQ(800u, imgdata1->data().GetAsUint8ClampedArray()->length());
   EXPECT_EQ(800u, imgdata2->data().GetAsUint8ClampedArray()->length());
   EXPECT_EQ(800u, imgdata3->data().GetAsUint8ClampedArray()->length());
   EXPECT_EQ(800u, imgdata4->data().GetAsUint8ClampedArray()->length());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 TEST_F(CanvasRenderingContext2DAPITest, CreateImageDataTooBig) {
@@ -509,8 +569,13 @@
   StudyParticipationRaii study_participation_raii;
   CreateContext(kNonOpaque);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* style = MakeGarbageCollected<
+      V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>("blue");
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrCanvasGradientOrCanvasPatternOrCSSColorValue style;
   style.SetString("blue");
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Context2D()->setStrokeStyle(style);
   EXPECT_EQ(INT64_C(2059186787917525779),
             Context2D()->IdentifiableTextToken().ToUkmMetricValue());
@@ -523,8 +588,13 @@
   StudyParticipationRaii study_participation_raii;
   CreateContext(kNonOpaque);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* style = MakeGarbageCollected<
+      V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>("blue");
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrCanvasGradientOrCanvasPatternOrCSSColorValue style;
   style.SetString("blue");
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Context2D()->setFillStyle(style);
   EXPECT_EQ(INT64_C(-6322980727372024031),
             Context2D()->IdentifiableTextToken().ToUkmMetricValue());
@@ -543,8 +613,13 @@
   Context2D()->setFont("Helvetica");
   Context2D()->setTextBaseline("bottom");
   Context2D()->setTextAlign("right");
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* style = MakeGarbageCollected<
+      V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>("red");
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrCanvasGradientOrCanvasPatternOrCSSColorValue style;
   style.SetString("red");
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Context2D()->setFillStyle(style);
   Context2D()->fillText("Bye", 4.0, 3.0);
   EXPECT_EQ(INT64_C(2368400155273386771),
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
index 7840eb9c..d0effcb1 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
@@ -425,9 +425,10 @@
       css_filter_value_->ReResolveUrl(style_resolution_host->GetDocument());
     }
 
-    ComputedStyle* filter_style = style_resolution_host->GetDocument()
-                                      .GetStyleResolver()
-                                      .CreateComputedStyle();
+    scoped_refptr<ComputedStyle> filter_style =
+        style_resolution_host->GetDocument()
+            .GetStyleResolver()
+            .CreateComputedStyle();
     // Must set font in case the filter uses any font-relative units (em, ex)
     // If font_for_filter_ was never set (ie frame-less documents) use base font
     if (LIKELY(font_for_filter_.GetFontSelector())) {
@@ -443,7 +444,7 @@
     }
     StyleResolverState resolver_state(style_resolution_host->GetDocument(),
                                       *style_resolution_host,
-                                      StyleRequest(filter_style));
+                                      StyleRequest(filter_style.get()));
     resolver_state.SetStyle(filter_style);
 
     StyleBuilder::ApplyProperty(
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
index 765fbdd..8847b45 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
@@ -17,7 +17,10 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_float32array_uint16array_uint8clampedarray.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_canvas_gradient_or_canvas_pattern_or_css_color_value.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_csscolorvalue_canvasgradient_canvaspattern_string.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_cssimagevalue_htmlcanvaselement_htmlimageelement_htmlvideoelement_imagebitmap_offscreencanvas_svgimageelement_videoframe.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -172,8 +175,15 @@
       visitor->Trace(alpha_gradient_);
     }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    Member<V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>
+        opaque_gradient_;
+    Member<V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>
+        alpha_gradient_;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     StringOrCanvasGradientOrCanvasPatternOrCSSColorValue opaque_gradient_;
     StringOrCanvasGradientOrCanvasPatternOrCSSColorValue alpha_gradient_;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   };
 
   // TODO(Oilpan): avoid tedious part-object wrapper by supporting on-heap
@@ -188,12 +198,23 @@
   FakeImageSource alpha_bitmap_;
   scoped_refptr<viz::TestContextProvider> test_context_provider_;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Member<V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>&
+  OpaqueGradient() {
+    return wrap_gradients_->opaque_gradient_;
+  }
+  Member<V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>&
+  AlphaGradient() {
+    return wrap_gradients_->alpha_gradient_;
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrCanvasGradientOrCanvasPatternOrCSSColorValue& OpaqueGradient() {
     return wrap_gradients_->opaque_gradient_;
   }
   StringOrCanvasGradientOrCanvasPatternOrCSSColorValue& AlphaGradient() {
     return wrap_gradients_->alpha_gradient_;
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 };
 
 CanvasRenderingContext2DTest::CanvasRenderingContext2DTest()
@@ -243,7 +264,13 @@
   EXPECT_FALSE(exception_state.HadException());
   opaque_gradient->addColorStop(1, String("blue"), exception_state);
   EXPECT_FALSE(exception_state.HadException());
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  OpaqueGradient() = MakeGarbageCollected<
+      V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>(
+      opaque_gradient);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   OpaqueGradient().SetCanvasGradient(opaque_gradient);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   auto* alpha_gradient =
       MakeGarbageCollected<CanvasGradient>(FloatPoint(0, 0), FloatPoint(10, 0));
@@ -253,7 +280,13 @@
                                exception_state);
   EXPECT_FALSE(exception_state.HadException());
   StringOrCanvasGradientOrCanvasPatternOrCSSColorValue wrapped_alpha_gradient;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  AlphaGradient() = MakeGarbageCollected<
+      V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>(
+      alpha_gradient);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   AlphaGradient().SetCanvasGradient(alpha_gradient);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   global_memory_cache_ =
       ReplaceMemoryCacheForTesting(MakeGarbageCollected<MemoryCache>(
@@ -600,8 +633,13 @@
   CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>(
       canvas->GetCanvasRenderingContext("2d", attributes));
   DummyExceptionStateForTesting exception_state;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* image_source =
+      MakeGarbageCollected<V8CanvasImageSource>(image_bitmap_derived);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CanvasImageSourceUnion image_source;
   image_source.SetImageBitmap(image_bitmap_derived);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   context->drawImage(GetScriptState(), image_source, 0, 0, exception_state);
 }
 
@@ -781,15 +819,25 @@
 
   context->clearRect(0, 0, 2, 2);
   NonThrowableExceptionState exception_state;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* image_union = MakeGarbageCollected<V8CanvasImageSource>(image_element);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CanvasImageSourceUnion image_union;
   image_union.SetHTMLImageElement(image_element);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   context->drawImage(script_state, image_union, 0, 0, exception_state);
 
   ImageData* image_data =
       context->getImageData(0, 0, 2, 2, color_setting, exception_state);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const V8ImageDataArray* data_array = image_data->data();
+  ASSERT_TRUE(data_array->IsFloat32Array());
+  DOMArrayBufferView* buffer_view = data_array->GetAsFloat32Array().Get();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ImageDataArray data_array = image_data->data();
   ASSERT_TRUE(data_array.IsFloat32Array());
   DOMArrayBufferView* buffer_view = data_array.GetAsFloat32Array().Get();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ASSERT_EQ(16u, buffer_view->byteLength() / buffer_view->TypeSize());
   float* actual_pixels = static_cast<float*>(buffer_view->BaseAddress());
 
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h
index e5905ff..8489507 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h
@@ -31,6 +31,7 @@
 #include "base/macros.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_2d_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/path_2d_or_string.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_path2d_string.h"
 #include "third_party/blink/renderer/core/geometry/dom_matrix.h"
 #include "third_party/blink/renderer/core/svg/svg_path_utilities.h"
 #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h"
@@ -46,6 +47,19 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static Path2D* Create(const V8UnionPath2DOrString* path) {
+    DCHECK(path);
+    switch (path->GetContentType()) {
+      case V8UnionPath2DOrString::ContentType::kPath2D:
+        return MakeGarbageCollected<Path2D>(path->GetAsPath2D());
+      case V8UnionPath2DOrString::ContentType::kString:
+        return MakeGarbageCollected<Path2D>(path->GetAsString());
+    }
+    NOTREACHED();
+    return nullptr;
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static Path2D* Create(Path2DOrString pathorstring) {
     DCHECK(!pathorstring.IsNull());
     if (pathorstring.IsPath2D())
@@ -55,6 +69,7 @@
     NOTREACHED();
     return nullptr;
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static Path2D* Create() { return MakeGarbageCollected<Path2D>(); }
   static Path2D* Create(const Path& path) {
     return MakeGarbageCollected<Path2D>(path);
diff --git a/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc b/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc
index db3ea06..6f771825 100644
--- a/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc
+++ b/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc
@@ -1,12 +1,13 @@
 // 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/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.h"
-#include "third_party/blink/renderer/core/html/canvas/predefined_color_space.h"
 
 #include "build/build_config.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_context_creation_attributes_module.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
+#include "third_party/blink/renderer/core/html/canvas/predefined_color_space.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc b/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc
index 1dce412d..a1757aa 100644
--- a/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc
+++ b/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc
@@ -13,6 +13,34 @@
 
 namespace blink {
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8RenderingContext* HTMLCanvasElementModule::getContext(
+    HTMLCanvasElement& canvas,
+    const String& context_id,
+    const CanvasContextCreationAttributesModule* attributes,
+    ExceptionState& exception_state) {
+  if (canvas.SurfaceLayerBridge() && !canvas.LowLatencyEnabled()) {
+    // The existence of canvas surfaceLayerBridge indicates that
+    // HTMLCanvasElement.transferControlToOffscreen() has been called.
+    exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+                                      "Cannot get context from a canvas that "
+                                      "has transferred its control to "
+                                      "offscreen.");
+    return nullptr;
+  }
+
+  CanvasContextCreationAttributesCore canvas_context_creation_attributes;
+  if (!ToCanvasContextCreationAttributes(
+          attributes, canvas_context_creation_attributes, exception_state)) {
+    return nullptr;
+  }
+  CanvasRenderingContext* context = canvas.GetCanvasRenderingContext(
+      context_id, canvas_context_creation_attributes);
+  if (!context)
+    return nullptr;
+  return context->AsV8RenderingContext();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void HTMLCanvasElementModule::getContext(
     HTMLCanvasElement& canvas,
     const String& type,
@@ -39,6 +67,7 @@
   if (context)
     context->SetCanvasGetContextResult(result);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 OffscreenCanvas* HTMLCanvasElementModule::transferControlToOffscreen(
     ExecutionContext* execution_context,
diff --git a/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h b/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h
index 0d081116..f094cc0 100644
--- a/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h
+++ b/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_HTMLCANVAS_HTML_CANVAS_ELEMENT_MODULE_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_HTMLCANVAS_HTML_CANVAS_ELEMENT_MODULE_H_
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -21,11 +22,19 @@
   friend class HTMLCanvasElementModuleTest;
 
  public:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static V8RenderingContext* getContext(
+      HTMLCanvasElement& canvas,
+      const String& context_id,
+      const CanvasContextCreationAttributesModule* attributes,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static void getContext(HTMLCanvasElement&,
                          const String&,
                          const CanvasContextCreationAttributesModule*,
                          RenderingContext&,
                          ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static OffscreenCanvas* transferControlToOffscreen(ExecutionContext*,
                                                      HTMLCanvasElement&,
                                                      ExceptionState&);
diff --git a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc
index 289c1d3..0188281 100644
--- a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc
+++ b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc
@@ -36,6 +36,7 @@
 #include "base/location.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_blob_htmlcanvaselement_htmlimageelement_htmlvideoelement_imagebitmap_imagedata_offscreencanvas_svgimageelement_videoframe.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/fileapi/blob.h"
@@ -79,6 +80,56 @@
 
 }  // namespace
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+inline ImageBitmapSource* ToImageBitmapSourceInternal(
+    const V8ImageBitmapSource* value,
+    const ImageBitmapOptions* options,
+    bool has_crop_rect) {
+  DCHECK(value);
+
+  switch (value->GetContentType()) {
+    case V8ImageBitmapSource::ContentType::kBlob:
+      UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+                                kCreateImageBitmapSourceBlob);
+      return value->GetAsBlob();
+    case V8ImageBitmapSource::ContentType::kHTMLCanvasElement:
+      UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+                                kCreateImageBitmapSourceHTMLCanvasElement);
+      return value->GetAsHTMLCanvasElement();
+    case V8ImageBitmapSource::ContentType::kHTMLImageElement:
+      UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+                                kCreateImageBitmapSourceHTMLImageElement);
+      return value->GetAsHTMLImageElement();
+    case V8ImageBitmapSource::ContentType::kHTMLVideoElement:
+      UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+                                kCreateImageBitmapSourceHTMLVideoElement);
+      return value->GetAsHTMLVideoElement();
+    case V8ImageBitmapSource::ContentType::kImageBitmap:
+      UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+                                kCreateImageBitmapSourceImageBitmap);
+      return value->GetAsImageBitmap();
+    case V8ImageBitmapSource::ContentType::kImageData:
+      UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+                                kCreateImageBitmapSourceImageData);
+      return value->GetAsImageData();
+    case V8ImageBitmapSource::ContentType::kOffscreenCanvas:
+      UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+                                kCreateImageBitmapSourceOffscreenCanvas);
+      return value->GetAsOffscreenCanvas();
+    case V8ImageBitmapSource::ContentType::kSVGImageElement:
+      UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+                                kCreateImageBitmapSourceSVGImageElement);
+      return value->GetAsSVGImageElement();
+    case V8ImageBitmapSource::ContentType::kVideoFrame:
+      UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+                                kCreateImageBitmapSourceVideoFrame);
+      return value->GetAsVideoFrame();
+  }
+
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 static inline ImageBitmapSource* ToImageBitmapSourceInternal(
     const ImageBitmapSourceUnion& value,
     const ImageBitmapOptions* options,
@@ -131,6 +182,7 @@
   NOTREACHED();
   return nullptr;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 ScriptPromise ImageBitmapFactories::CreateImageBitmapFromBlob(
     ScriptState* script_state,
@@ -148,7 +200,11 @@
 
 ScriptPromise ImageBitmapFactories::CreateImageBitmap(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8ImageBitmapSource* bitmap_source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const ImageBitmapSourceUnion& bitmap_source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const ImageBitmapOptions* options,
     ExceptionState& exception_state) {
   WebFeature feature = WebFeature::kCreateImageBitmap;
@@ -163,7 +219,11 @@
 
 ScriptPromise ImageBitmapFactories::CreateImageBitmap(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8ImageBitmapSource* bitmap_source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const ImageBitmapSourceUnion& bitmap_source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     int sx,
     int sy,
     int sw,
diff --git a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.h b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.h
index 1bb5bdb..29c5f63 100644
--- a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.h
+++ b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.h
@@ -38,6 +38,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/image_bitmap_source.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
 #include "third_party/blink/renderer/core/fileapi/file_reader_loader.h"
 #include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h"
@@ -70,11 +71,19 @@
   ImageBitmapFactories();
 
   static ScriptPromise CreateImageBitmap(ScriptState*,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                         const V8ImageBitmapSource*,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                          const ImageBitmapSourceUnion&,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                          const ImageBitmapOptions*,
                                          ExceptionState&);
   static ScriptPromise CreateImageBitmap(ScriptState*,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                         const V8ImageBitmapSource*,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                          const ImageBitmapSourceUnion&,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                          int sx,
                                          int sy,
                                          int sw,
@@ -91,7 +100,11 @@
   static ScriptPromise createImageBitmap(
       ScriptState* script_state,
       LocalDOMWindow&,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const V8ImageBitmapSource* bitmap_source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const ImageBitmapSourceUnion& bitmap_source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const ImageBitmapOptions* options,
       ExceptionState& exception_state) {
     return CreateImageBitmap(script_state, bitmap_source, options,
@@ -100,7 +113,11 @@
   static ScriptPromise createImageBitmap(
       ScriptState* script_state,
       LocalDOMWindow&,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const V8ImageBitmapSource* bitmap_source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const ImageBitmapSourceUnion& bitmap_source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       int sx,
       int sy,
       int sw,
@@ -115,7 +132,11 @@
   static ScriptPromise createImageBitmap(
       ScriptState* script_state,
       WorkerGlobalScope&,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const V8ImageBitmapSource* bitmap_source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const ImageBitmapSourceUnion& bitmap_source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const ImageBitmapOptions* options,
       ExceptionState& exception_state) {
     return CreateImageBitmap(script_state, bitmap_source, options,
@@ -124,7 +145,11 @@
   static ScriptPromise createImageBitmap(
       ScriptState* script_state,
       WorkerGlobalScope&,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      const V8ImageBitmapSource* bitmap_source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       const ImageBitmapSourceUnion& bitmap_source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       int sx,
       int sy,
       int sw,
diff --git a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc
index 50c64c42..86abf5b 100644
--- a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc
+++ b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc
@@ -5,8 +5,11 @@
 #include "third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h"
 
 #include <utility>
+
 #include "third_party/blink/renderer/bindings/modules/v8/offscreen_rendering_context.h"
 #include "third_party/blink/renderer/bindings/modules/v8/rendering_context.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_canvasrenderingcontext2d_gpucanvascontext_imagebitmaprenderingcontext_webgl2renderingcontext_webglrenderingcontext.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_gpucanvascontext_imagebitmaprenderingcontext_offscreencanvasrenderingcontext2d_webgl2renderingcontext_webglrenderingcontext.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
 #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
@@ -20,6 +23,19 @@
 
 ImageBitmapRenderingContext::~ImageBitmapRenderingContext() = default;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8RenderingContext* ImageBitmapRenderingContext::AsV8RenderingContext() {
+  return MakeGarbageCollected<V8RenderingContext>(this);
+}
+
+V8OffscreenRenderingContext*
+ImageBitmapRenderingContext::AsV8OffscreenRenderingContext() {
+  return MakeGarbageCollected<V8OffscreenRenderingContext>(this);
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void ImageBitmapRenderingContext::SetCanvasGetContextResult(
     RenderingContext& result) {
   result.SetImageBitmapRenderingContext(this);
@@ -29,6 +45,8 @@
   result.SetImageBitmapRenderingContext(this);
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void ImageBitmapRenderingContext::transferFromImageBitmap(
     ImageBitmap* image_bitmap,
     ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h
index a0de5d6..6e54e50 100644
--- a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h
+++ b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h
@@ -7,6 +7,7 @@
 
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h"
 #include "third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h"
@@ -49,8 +50,13 @@
   }
   ImageBitmap* TransferToImageBitmap(ScriptState*) override;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8RenderingContext* AsV8RenderingContext() final;
+  V8OffscreenRenderingContext* AsV8OffscreenRenderingContext() final;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void SetCanvasGetContextResult(RenderingContext&) final;
   void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   ~ImageBitmapRenderingContext() override;
 };
diff --git a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc
index e136b32..fad044c 100644
--- a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_htmlcanvaselement_offscreencanvas.h"
 #include "third_party/blink/renderer/bindings/modules/v8/html_canvas_element_or_offscreen_canvas.h"
 #include "third_party/blink/renderer/bindings/modules/v8/rendering_context.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
@@ -26,6 +27,17 @@
 
 ImageBitmapRenderingContextBase::~ImageBitmapRenderingContextBase() = default;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionHTMLCanvasElementOrOffscreenCanvas*
+ImageBitmapRenderingContextBase::getHTMLOrOffscreenCanvas() const {
+  if (Host()->IsOffscreenCanvas()) {
+    return MakeGarbageCollected<V8UnionHTMLCanvasElementOrOffscreenCanvas>(
+        static_cast<OffscreenCanvas*>(Host()));
+  }
+  return MakeGarbageCollected<V8UnionHTMLCanvasElementOrOffscreenCanvas>(
+      static_cast<HTMLCanvasElement*>(Host()));
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void ImageBitmapRenderingContextBase::getHTMLOrOffscreenCanvas(
     HTMLCanvasElementOrOffscreenCanvas& result) const {
   if (Host()->IsOffscreenCanvas()) {
@@ -34,6 +46,7 @@
     result.SetHTMLCanvasElement(static_cast<HTMLCanvasElement*>(Host()));
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void ImageBitmapRenderingContextBase::Stop() {
   image_layer_bridge_->Dispose();
diff --git a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h
index 604c520..591bd77 100644
--- a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h
@@ -17,9 +17,10 @@
 
 namespace blink {
 
+class HTMLCanvasElementOrOffscreenCanvas;
 class ImageBitmap;
 class ImageLayerBridge;
-class HTMLCanvasElementOrOffscreenCanvas;
+class V8UnionHTMLCanvasElementOrOffscreenCanvas;
 
 class MODULES_EXPORT ImageBitmapRenderingContextBase
     : public CanvasRenderingContext {
@@ -38,7 +39,11 @@
   }
 
   bool CanCreateCanvas2dResourceProvider() const;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionHTMLCanvasElementOrOffscreenCanvas* getHTMLOrOffscreenCanvas() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void getHTMLOrOffscreenCanvas(HTMLCanvasElementOrOffscreenCanvas&) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void SetIsInHiddenPage(bool) override {}
   void SetIsBeingDisplayed(bool) override {}
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc b/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc
index b636a72..df92f8e 100644
--- a/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc
+++ b/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc
@@ -12,6 +12,33 @@
 
 namespace blink {
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8OffscreenRenderingContext* OffscreenCanvasModule::getContext(
+    ExecutionContext* execution_context,
+    OffscreenCanvas& offscreen_canvas,
+    const String& context_id,
+    const CanvasContextCreationAttributesModule* attributes,
+    ExceptionState& exception_state) {
+  if (offscreen_canvas.IsNeutered()) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+                                      "OffscreenCanvas object is detached");
+    return nullptr;
+  }
+  CanvasContextCreationAttributesCore canvas_context_creation_attributes;
+  if (!ToCanvasContextCreationAttributes(
+          attributes, canvas_context_creation_attributes, exception_state)) {
+    return nullptr;
+  }
+
+  // OffscreenCanvas cannot be transferred after getContext, so this execution
+  // context will always be the right one from here on.
+  CanvasRenderingContext* context = offscreen_canvas.GetCanvasRenderingContext(
+      execution_context, context_id, canvas_context_creation_attributes);
+  if (!context)
+    return nullptr;
+  return context->AsV8OffscreenRenderingContext();
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void OffscreenCanvasModule::getContext(
     ExecutionContext* execution_context,
     OffscreenCanvas& offscreen_canvas,
@@ -37,5 +64,6 @@
   if (context)
     context->SetOffscreenCanvasGetContextResult(result);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h b/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h
index ba2d44f..0639ae4 100644
--- a/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h
+++ b/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_OFFSCREENCANVAS_OFFSCREEN_CANVAS_MODULE_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_OFFSCREENCANVAS_OFFSCREEN_CANVAS_MODULE_H_
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -20,12 +21,21 @@
   STATIC_ONLY(OffscreenCanvasModule);
 
  public:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static V8OffscreenRenderingContext* getContext(
+      ExecutionContext* execution_context,
+      OffscreenCanvas& offscreen_canvas,
+      const String& context_id,
+      const CanvasContextCreationAttributesModule* attributes,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static void getContext(ExecutionContext*,
                          OffscreenCanvas&,
                          const String&,
                          const CanvasContextCreationAttributesModule*,
                          OffscreenRenderingContext&,
                          ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
index bdb299e..0529189 100644
--- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
@@ -7,6 +7,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/renderer/bindings/modules/v8/offscreen_rendering_context.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_gpucanvascontext_imagebitmaprenderingcontext_offscreencanvasrenderingcontext2d_webgl2renderingcontext_webglrenderingcontext.h"
 #include "third_party/blink/renderer/core/css/offscreen_font_selector.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser.h"
 #include "third_party/blink/renderer/core/css/resolver/font_style_resolver.h"
@@ -251,11 +252,26 @@
   return image;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8RenderingContext* OffscreenCanvasRenderingContext2D::AsV8RenderingContext() {
+  return nullptr;
+}
+
+V8OffscreenRenderingContext*
+OffscreenCanvasRenderingContext2D::AsV8OffscreenRenderingContext() {
+  return MakeGarbageCollected<V8OffscreenRenderingContext>(this);
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void OffscreenCanvasRenderingContext2D::SetOffscreenCanvasGetContextResult(
     OffscreenRenderingContext& result) {
   result.SetOffscreenCanvasRenderingContext2D(this);
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 bool OffscreenCanvasRenderingContext2D::ParseColorOrCurrentColor(
     Color& color,
     const String& color_string) const {
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
index 379af511..5a0a91f 100644
--- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <random>
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h"
@@ -58,11 +59,16 @@
   bool IsRenderingContext2D() const override { return true; }
   bool IsComposited() const override { return false; }
   bool IsAccelerated() const override;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8RenderingContext* AsV8RenderingContext() final;
+  V8OffscreenRenderingContext* AsV8OffscreenRenderingContext() final;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void SetCanvasGetContextResult(RenderingContext&) final {}
   void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void SetIsInHiddenPage(bool) final { NOTREACHED(); }
   void SetIsBeingDisplayed(bool) final { NOTREACHED(); }
   void Stop() final { NOTREACHED(); }
-  void SetCanvasGetContextResult(RenderingContext&) final {}
   void ClearRect(double x, double y, double width, double height) override {
     BaseRenderingContext2D::clearRect(x, y, width, height);
   }
diff --git a/third_party/blink/renderer/modules/credentialmanager/password_credential.cc b/third_party/blink/renderer/modules/credentialmanager/password_credential.cc
index 72705195..b9a086f 100644
--- a/third_party/blink/renderer/modules/credentialmanager/password_credential.cc
+++ b/third_party/blink/renderer/modules/credentialmanager/password_credential.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/credentialmanager/password_credential.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_file_usvstring.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_password_credential_data.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/html/forms/form_data.h"
@@ -64,10 +65,19 @@
     // https://html.spec.whatwg.org/C/#constructing-the-form-data-set
     DCHECK(!submittable_element->GetName().IsEmpty());
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    V8FormDataEntryValue* value =
+        form_data->get(submittable_element->GetName());
+    if (!value->IsUSVString())
+      continue;
+    const String& usv_string_value = value->GetAsUSVString();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     FileOrUSVString value;
     form_data->get(submittable_element->GetName(), value);
     if (!value.IsUSVString())
       continue;
+    const String& usv_string_value = value.GetAsUSVString();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
     Vector<String> autofill_tokens;
     submittable_element->ToHTMLElement()
@@ -77,14 +87,14 @@
         .Split(' ', autofill_tokens);
     for (const auto& token : autofill_tokens) {
       if (token == "current-password" || token == "new-password") {
-        data->setPassword(value.GetAsUSVString());
+        data->setPassword(usv_string_value);
         is_password_set = true;
       } else if (token == "photo") {
-        data->setIconURL(value.GetAsUSVString());
+        data->setIconURL(usv_string_value);
       } else if (token == "name" || token == "nickname") {
-        data->setName(value.GetAsUSVString());
+        data->setName(usv_string_value);
       } else if (token == "username") {
-        data->setId(value.GetAsUSVString());
+        data->setId(usv_string_value);
         is_id_set = true;
       }
     }
diff --git a/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc b/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc
index 8b90235b..dfb08da 100644
--- a/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc
+++ b/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc
@@ -41,6 +41,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_object_string.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_crypto_key.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
@@ -496,6 +497,34 @@
   return true;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8AlgorithmIdentifier* GetAlgorithmIdentifier(v8::Isolate* isolate,
+                                              const Dictionary& raw,
+                                              const char* property_name,
+                                              const ErrorContext& context,
+                                              ExceptionState& exception_state) {
+  // FIXME: This is not correct: http://crbug.com/438060
+  //   (1) It may retrieve the property twice from the dictionary, whereas it
+  //       should be reading the v8 value once to avoid issues with getters.
+  //   (2) The value is stringified (whereas the spec says it should be an
+  //       instance of DOMString).
+  Dictionary dictionary;
+  if (raw.Get(property_name, dictionary) && dictionary.IsObject()) {
+    return MakeGarbageCollected<V8AlgorithmIdentifier>(
+        ScriptValue(isolate, dictionary.V8Value()));
+  }
+
+  String algorithm_name;
+  if (!DictionaryHelper::Get(raw, property_name, algorithm_name)) {
+    SetTypeError(context.ToString(property_name,
+                                  "Missing or not an AlgorithmIdentifier"),
+                 exception_state);
+    return nullptr;
+  }
+
+  return MakeGarbageCollected<V8AlgorithmIdentifier>(algorithm_name);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 bool GetAlgorithmIdentifier(v8::Isolate* isolate,
                             const Dictionary& raw,
                             const char* property_name,
@@ -524,6 +553,7 @@
   value.SetString(algorithm_name);
   return true;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 // Defined by the WebCrypto spec as:
 //
@@ -560,7 +590,11 @@
 }
 
 bool ParseAlgorithmIdentifier(v8::Isolate*,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                              const V8AlgorithmIdentifier&,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                               const AlgorithmIdentifier&,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                               WebCryptoOperation,
                               WebCryptoAlgorithm&,
                               ErrorContext,
@@ -571,6 +605,18 @@
                WebCryptoAlgorithm& hash,
                ErrorContext context,
                ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8AlgorithmIdentifier* raw_hash =
+      GetAlgorithmIdentifier(isolate, raw, "hash", context, exception_state);
+  if (!raw_hash) {
+    DCHECK(exception_state.HadException());
+    return false;
+  }
+
+  context.Add("hash");
+  return ParseAlgorithmIdentifier(isolate, *raw_hash, kWebCryptoOperationDigest,
+                                  hash, context, exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   AlgorithmIdentifier raw_hash;
   if (!GetAlgorithmIdentifier(isolate, raw, "hash", raw_hash, context,
                               exception_state))
@@ -579,6 +625,7 @@
   context.Add("hash");
   return ParseAlgorithmIdentifier(isolate, raw_hash, kWebCryptoOperationDigest,
                                   hash, context, exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 // Defined by the WebCrypto spec as:
@@ -1170,7 +1217,11 @@
 }
 
 bool ParseAlgorithmIdentifier(v8::Isolate* isolate,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                              const V8AlgorithmIdentifier& raw,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                               const AlgorithmIdentifier& raw,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                               WebCryptoOperation op,
                               WebCryptoAlgorithm& algorithm,
                               ErrorContext context,
@@ -1203,12 +1254,22 @@
 }  // namespace
 
 bool NormalizeAlgorithm(v8::Isolate* isolate,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                        const V8AlgorithmIdentifier* raw,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                         const AlgorithmIdentifier& raw,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                         WebCryptoOperation op,
                         WebCryptoAlgorithm& algorithm,
                         ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DCHECK(raw);
+  return ParseAlgorithmIdentifier(isolate, *raw, op, algorithm, ErrorContext(),
+                                  exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   return ParseAlgorithmIdentifier(isolate, raw, op, algorithm, ErrorContext(),
                                   exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/crypto/normalize_algorithm.h b/third_party/blink/renderer/modules/crypto/normalize_algorithm.h
index c9f7f205..f515fd277 100644
--- a/third_party/blink/renderer/modules/crypto/normalize_algorithm.h
+++ b/third_party/blink/renderer/modules/crypto/normalize_algorithm.h
@@ -35,6 +35,7 @@
 #include "third_party/blink/public/platform/web_crypto_algorithm.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/renderer/bindings/modules/v8/object_or_string.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -58,7 +59,11 @@
 // https://w3c.github.io/webcrypto/#algorithm-normalization-normalize-an-algorithm
 MODULES_EXPORT WARN_UNUSED_RESULT bool NormalizeAlgorithm(
     v8::Isolate*,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8AlgorithmIdentifier*,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const AlgorithmIdentifier&,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     WebCryptoOperation,
     WebCryptoAlgorithm&,
     ExceptionState&);
diff --git a/third_party/blink/renderer/modules/crypto/subtle_crypto.cc b/third_party/blink/renderer/modules/crypto/subtle_crypto.cc
index 8726bd39..143d906d 100644
--- a/third_party/blink/renderer/modules/crypto/subtle_crypto.cc
+++ b/third_party/blink/renderer/modules/crypto/subtle_crypto.cc
@@ -39,6 +39,7 @@
 #include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
 #include "third_party/blink/renderer/bindings/modules/v8/array_buffer_or_array_buffer_view_or_json_web_key.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_arraybuffer_arraybufferview_jsonwebkey.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/frame/deprecation.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
@@ -113,11 +114,21 @@
 
 SubtleCrypto::SubtleCrypto() = default;
 
-ScriptPromise SubtleCrypto::encrypt(ScriptState* script_state,
-                                    const AlgorithmIdentifier& raw_algorithm,
-                                    CryptoKey* key,
-                                    const BufferSource& raw_data,
-                                    ExceptionState& exception_state) {
+ScriptPromise SubtleCrypto::encrypt(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const V8AlgorithmIdentifier* raw_algorithm,
+    CryptoKey* key,
+    const V8BufferSource* raw_data,
+    ExceptionState& exception_state
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const AlgorithmIdentifier& raw_algorithm,
+    CryptoKey* key,
+    const BufferSource& raw_data,
+    ExceptionState& exception_state
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   // Method described by:
   // https://w3c.github.io/webcrypto/Overview.html#dfn-SubtleCrypto-method-encrypt
 
@@ -157,11 +168,21 @@
   return promise;
 }
 
-ScriptPromise SubtleCrypto::decrypt(ScriptState* script_state,
-                                    const AlgorithmIdentifier& raw_algorithm,
-                                    CryptoKey* key,
-                                    const BufferSource& raw_data,
-                                    ExceptionState& exception_state) {
+ScriptPromise SubtleCrypto::decrypt(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const V8AlgorithmIdentifier* raw_algorithm,
+    CryptoKey* key,
+    const V8BufferSource* raw_data,
+    ExceptionState& exception_state
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const AlgorithmIdentifier& raw_algorithm,
+    CryptoKey* key,
+    const BufferSource& raw_data,
+    ExceptionState& exception_state
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   // Method described by:
   // https://w3c.github.io/webcrypto/Overview.html#dfn-SubtleCrypto-method-decrypt
 
@@ -201,11 +222,21 @@
   return promise;
 }
 
-ScriptPromise SubtleCrypto::sign(ScriptState* script_state,
-                                 const AlgorithmIdentifier& raw_algorithm,
-                                 CryptoKey* key,
-                                 const BufferSource& raw_data,
-                                 ExceptionState& exception_state) {
+ScriptPromise SubtleCrypto::sign(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const V8AlgorithmIdentifier* raw_algorithm,
+    CryptoKey* key,
+    const V8BufferSource* raw_data,
+    ExceptionState& exception_state
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const AlgorithmIdentifier& raw_algorithm,
+    CryptoKey* key,
+    const BufferSource& raw_data,
+    ExceptionState& exception_state
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   // Method described by:
   // https://w3c.github.io/webcrypto/Overview.html#dfn-SubtleCrypto-method-sign
 
@@ -246,12 +277,22 @@
 }
 
 ScriptPromise SubtleCrypto::verifySignature(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const V8AlgorithmIdentifier* raw_algorithm,
+    CryptoKey* key,
+    const V8BufferSource* raw_signature,
+    const V8BufferSource* raw_data,
+    ExceptionState& exception_state
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ScriptState* script_state,
     const AlgorithmIdentifier& raw_algorithm,
     CryptoKey* key,
     const BufferSource& raw_signature,
     const BufferSource& raw_data,
-    ExceptionState& exception_state) {
+    ExceptionState& exception_state
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   // Method described by:
   // https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-verify
 
@@ -295,10 +336,19 @@
   return promise;
 }
 
-ScriptPromise SubtleCrypto::digest(ScriptState* script_state,
-                                   const AlgorithmIdentifier& raw_algorithm,
-                                   const BufferSource& raw_data,
-                                   ExceptionState& exception_state) {
+ScriptPromise SubtleCrypto::digest(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const V8AlgorithmIdentifier* raw_algorithm,
+    const V8BufferSource* raw_data,
+    ExceptionState& exception_state
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const AlgorithmIdentifier& raw_algorithm,
+    const BufferSource& raw_data,
+    ExceptionState& exception_state
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   // Method described by:
   // https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-digest
 
@@ -327,11 +377,20 @@
 }
 
 ScriptPromise SubtleCrypto::generateKey(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const V8AlgorithmIdentifier* raw_algorithm,
+    bool extractable,
+    const Vector<String>& raw_key_usages,
+    ExceptionState& exception_state
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ScriptState* script_state,
     const AlgorithmIdentifier& raw_algorithm,
     bool extractable,
     const Vector<String>& raw_key_usages,
-    ExceptionState& exception_state) {
+    ExceptionState& exception_state
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   // Method described by:
   // https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-generateKey
 
@@ -367,13 +426,24 @@
 }
 
 ScriptPromise SubtleCrypto::importKey(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const String& raw_format,
+    const V8UnionBufferSourceOrJsonWebKey* raw_key_data,
+    const V8AlgorithmIdentifier* raw_algorithm,
+    bool extractable,
+    const Vector<String>& raw_key_usages,
+    ExceptionState& exception_state
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ScriptState* script_state,
     const String& raw_format,
     const ArrayBufferOrArrayBufferViewOrJsonWebKey& raw_key_data,
     const AlgorithmIdentifier& raw_algorithm,
     bool extractable,
     const Vector<String>& raw_key_usages,
-    ExceptionState& exception_state) {
+    ExceptionState& exception_state
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   // Method described by:
   // https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-importKey
 
@@ -403,6 +473,21 @@
     case kWebCryptoKeyFormatRaw:
     case kWebCryptoKeyFormatPkcs8:
     case kWebCryptoKeyFormatSpki:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      switch (raw_key_data->GetContentType()) {
+        case V8UnionBufferSourceOrJsonWebKey::ContentType::kArrayBuffer:
+          key_data = CopyBytes(raw_key_data->GetAsArrayBuffer());
+          break;
+        case V8UnionBufferSourceOrJsonWebKey::ContentType::kArrayBufferView:
+          key_data = CopyBytes(raw_key_data->GetAsArrayBufferView().Get());
+          break;
+        case V8UnionBufferSourceOrJsonWebKey::ContentType::kJsonWebKey:
+          result->CompleteWithError(
+              kWebCryptoErrorTypeType,
+              "Key data must be a BufferSource for non-JWK formats");
+          return promise;
+      }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       if (raw_key_data.IsArrayBuffer()) {
         key_data = CopyBytes(raw_key_data.GetAsArrayBuffer());
       } else if (raw_key_data.IsArrayBufferView()) {
@@ -413,6 +498,7 @@
             "Key data must be a BufferSource for non-JWK formats");
         return promise;
       }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       break;
     // 14.3.9.2: If format is equal to the string "jwk":
     //
@@ -422,6 +508,15 @@
     //  (2) Let keyData be the keyData parameter passed to the importKey
     //      method.
     case kWebCryptoKeyFormatJwk:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      if (!raw_key_data->IsJsonWebKey()) {
+        result->CompleteWithError(kWebCryptoErrorTypeType,
+                                  "Key data must be an object for JWK import");
+        return promise;
+      }
+      if (!ParseJsonWebKey(*raw_key_data->GetAsJsonWebKey(), key_data, result))
+        return promise;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       if (raw_key_data.IsJsonWebKey()) {
         if (!ParseJsonWebKey(*raw_key_data.GetAsJsonWebKey(), key_data, result))
           return promise;
@@ -430,6 +525,7 @@
                                   "Key data must be an object for JWK import");
         return promise;
       }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       break;
   }
 
@@ -488,7 +584,11 @@
     const String& raw_format,
     CryptoKey* key,
     CryptoKey* wrapping_key,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8AlgorithmIdentifier* raw_wrap_algorithm,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const AlgorithmIdentifier& raw_wrap_algorithm,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   // Method described by:
   // https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-wrapKey
@@ -548,6 +648,17 @@
 }
 
 ScriptPromise SubtleCrypto::unwrapKey(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const String& raw_format,
+    const V8BufferSource* raw_wrapped_key,
+    CryptoKey* unwrapping_key,
+    const V8AlgorithmIdentifier* raw_unwrap_algorithm,
+    const V8AlgorithmIdentifier* raw_unwrapped_key_algorithm,
+    bool extractable,
+    const Vector<String>& raw_key_usages,
+    ExceptionState& exception_state
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ScriptState* script_state,
     const String& raw_format,
     const BufferSource& raw_wrapped_key,
@@ -556,7 +667,9 @@
     const AlgorithmIdentifier& raw_unwrapped_key_algorithm,
     bool extractable,
     const Vector<String>& raw_key_usages,
-    ExceptionState& exception_state) {
+    ExceptionState& exception_state
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   // Method described by:
   // https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-unwrapKey
 
@@ -628,11 +741,16 @@
   return promise;
 }
 
-ScriptPromise SubtleCrypto::deriveBits(ScriptState* script_state,
-                                       const AlgorithmIdentifier& raw_algorithm,
-                                       CryptoKey* base_key,
-                                       unsigned length_bits,
-                                       ExceptionState& exception_state) {
+ScriptPromise SubtleCrypto::deriveBits(
+    ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8AlgorithmIdentifier* raw_algorithm,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const AlgorithmIdentifier& raw_algorithm,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    CryptoKey* base_key,
+    unsigned length_bits,
+    ExceptionState& exception_state) {
   // Method described by:
   // https://w3c.github.io/webcrypto/Overview.html#dfn-SubtleCrypto-method-deriveBits
 
@@ -670,13 +788,24 @@
 }
 
 ScriptPromise SubtleCrypto::deriveKey(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ScriptState* script_state,
+    const V8AlgorithmIdentifier* raw_algorithm,
+    CryptoKey* base_key,
+    const V8AlgorithmIdentifier* raw_derived_key_type,
+    bool extractable,
+    const Vector<String>& raw_key_usages,
+    ExceptionState& exception_state
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ScriptState* script_state,
     const AlgorithmIdentifier& raw_algorithm,
     CryptoKey* base_key,
     const AlgorithmIdentifier& raw_derived_key_type,
     bool extractable,
     const Vector<String>& raw_key_usages,
-    ExceptionState& exception_state) {
+    ExceptionState& exception_state
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   // Method described by:
   // https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-deriveKey
 
diff --git a/third_party/blink/renderer/modules/crypto/subtle_crypto.h b/third_party/blink/renderer/modules/crypto/subtle_crypto.h
index 8e9d815..922b4ff9 100644
--- a/third_party/blink/renderer/modules/crypto/subtle_crypto.h
+++ b/third_party/blink/renderer/modules/crypto/subtle_crypto.h
@@ -33,6 +33,8 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/modules/crypto/normalize_algorithm.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -51,39 +53,96 @@
  public:
   SubtleCrypto();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise encrypt(ScriptState*,
+                        const V8AlgorithmIdentifier*,
+                        CryptoKey*,
+                        const V8BufferSource*,
+                        ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise encrypt(ScriptState*,
                         const AlgorithmIdentifier&,
                         CryptoKey*,
                         const BufferSource&,
                         ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise decrypt(ScriptState*,
+                        const V8AlgorithmIdentifier*,
+                        CryptoKey*,
+                        const V8BufferSource*,
+                        ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise decrypt(ScriptState*,
                         const AlgorithmIdentifier&,
                         CryptoKey*,
                         const BufferSource&,
                         ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise sign(ScriptState*,
+                     const V8AlgorithmIdentifier*,
+                     CryptoKey*,
+                     const V8BufferSource*,
+                     ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise sign(ScriptState*,
                      const AlgorithmIdentifier&,
                      CryptoKey*,
                      const BufferSource&,
                      ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // Note that this is not named "verify" because when compiling on Mac that
   // expands to a macro and breaks.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise verifySignature(ScriptState*,
+                                const V8AlgorithmIdentifier*,
+                                CryptoKey*,
+                                const V8BufferSource* signature,
+                                const V8BufferSource* data,
+                                ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise verifySignature(ScriptState*,
                                 const AlgorithmIdentifier&,
                                 CryptoKey*,
                                 const BufferSource& signature,
                                 const BufferSource& data,
                                 ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise digest(ScriptState*,
+                       const V8AlgorithmIdentifier*,
+                       const V8BufferSource* data,
+                       ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise digest(ScriptState*,
                        const AlgorithmIdentifier&,
                        const BufferSource& data,
                        ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise generateKey(ScriptState*,
+                            const V8AlgorithmIdentifier*,
+                            bool extractable,
+                            const Vector<String>& key_usages,
+                            ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise generateKey(ScriptState*,
                             const AlgorithmIdentifier&,
                             bool extractable,
                             const Vector<String>& key_usages,
                             ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise importKey(ScriptState*,
+                          const String&,
+                          const V8UnionBufferSourceOrJsonWebKey*,
+                          const V8AlgorithmIdentifier*,
+                          bool extractable,
+                          const Vector<String>& key_usages,
+                          ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise importKey(ScriptState*,
                           const String&,
                           const ArrayBufferOrArrayBufferViewOrJsonWebKey&,
@@ -91,14 +150,35 @@
                           bool extractable,
                           const Vector<String>& key_usages,
                           ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise exportKey(ScriptState*, const String&, CryptoKey*);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise wrapKey(ScriptState*,
+                        const String&,
+                        CryptoKey*,
+                        CryptoKey*,
+                        const V8AlgorithmIdentifier*,
+                        ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise wrapKey(ScriptState*,
                         const String&,
                         CryptoKey*,
                         CryptoKey*,
                         const AlgorithmIdentifier&,
                         ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise unwrapKey(ScriptState*,
+                          const String&,
+                          const V8BufferSource*,
+                          CryptoKey*,
+                          const V8AlgorithmIdentifier*,
+                          const V8AlgorithmIdentifier*,
+                          bool,
+                          const Vector<String>&,
+                          ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise unwrapKey(ScriptState*,
                           const String&,
                           const BufferSource&,
@@ -108,12 +188,30 @@
                           bool,
                           const Vector<String>&,
                           ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise deriveBits(ScriptState*,
+                           const V8AlgorithmIdentifier*,
+                           CryptoKey*,
+                           unsigned,
+                           ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise deriveBits(ScriptState*,
                            const AlgorithmIdentifier&,
                            CryptoKey*,
                            unsigned,
                            ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise deriveKey(ScriptState*,
+                          const V8AlgorithmIdentifier*,
+                          CryptoKey*,
+                          const V8AlgorithmIdentifier*,
+                          bool extractable,
+                          const Vector<String>&,
+                          ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise deriveKey(ScriptState*,
                           const AlgorithmIdentifier&,
                           CryptoKey*,
@@ -121,6 +219,7 @@
                           bool extractable,
                           const Vector<String>&,
                           ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/csspaint/background_color_paint_worklet_test.cc b/third_party/blink/renderer/modules/csspaint/background_color_paint_worklet_test.cc
index 5091d6e5..ce5c3b7 100644
--- a/third_party/blink/renderer/modules/csspaint/background_color_paint_worklet_test.cc
+++ b/third_party/blink/renderer/modules/csspaint/background_color_paint_worklet_test.cc
@@ -275,8 +275,9 @@
   auto* model1 = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
 
   Element* element = GetElementById("target");
-  ComputedStyle* style = GetDocument().GetStyleResolver().ResolveStyle(
-      element, StyleRecalcContext());
+  scoped_refptr<ComputedStyle> style =
+      GetDocument().GetStyleResolver().ResolveStyle(element,
+                                                    StyleRecalcContext());
   EXPECT_FALSE(style->HasCurrentBackgroundColorAnimation());
 
   NonThrowableExceptionState exception_state;
@@ -347,8 +348,9 @@
   auto* model = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
 
   Element* element = GetElementById("target");
-  ComputedStyle* style = GetDocument().GetStyleResolver().ResolveStyle(
-      element, StyleRecalcContext());
+  scoped_refptr<ComputedStyle> style =
+      GetDocument().GetStyleResolver().ResolveStyle(element,
+                                                    StyleRecalcContext());
   EXPECT_FALSE(style->HasCurrentBackgroundColorAnimation());
 
   NonThrowableExceptionState exception_state;
diff --git a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_test.cc b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_test.cc
index 69977ed9..05812dc 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_test.cc
+++ b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_test.cc
@@ -3,9 +3,10 @@
 // found in the LICENSE file.
 
 #include "third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h"
-#include "third_party/blink/renderer/bindings/modules/v8/string_or_canvas_gradient_or_canvas_pattern_or_css_color_value.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/modules/v8/string_or_canvas_gradient_or_canvas_pattern_or_css_color_value.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_csscolorvalue_canvasgradient_canvaspattern_string.h"
 
 namespace blink {
 namespace {
@@ -17,6 +18,17 @@
 void TrySettingStrokeStyle(PaintRenderingContext2D* ctx,
                            const String& expected,
                            const String& value) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ctx->setStrokeStyle(
+      MakeGarbageCollected<
+          V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>("red"));
+  ctx->setStrokeStyle(
+      MakeGarbageCollected<
+          V8UnionCSSColorValueOrCanvasGradientOrCanvasPatternOrString>(value));
+  auto* result = ctx->strokeStyle();
+  ASSERT_TRUE(result);
+  EXPECT_EQ(expected, result->GetAsString());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrCanvasGradientOrCanvasPatternOrCSSColorValue result, arg, dummy;
   dummy.SetString("red");
   arg.SetString(value);
@@ -24,6 +36,7 @@
   ctx->setStrokeStyle(arg);
   ctx->strokeStyle(result);
   EXPECT_EQ(expected, result.GetAsString());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 TEST(PaintRenderingContext2DTest, testParseColorOrCurrentColor) {
diff --git a/third_party/blink/renderer/modules/encoding/text_decoder.cc b/third_party/blink/renderer/modules/encoding/text_decoder.cc
index 430b431..0da435ed 100644
--- a/third_party/blink/renderer/modules/encoding/text_decoder.cc
+++ b/third_party/blink/renderer/modules/encoding/text_decoder.cc
@@ -30,6 +30,7 @@
 
 #include "third_party/blink/renderer/modules/encoding/text_decoder.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
 #include "third_party/blink/renderer/modules/encoding/encoding.h"
@@ -77,6 +78,37 @@
   return name;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+String TextDecoder::decode(const V8BufferSource* input,
+                           const TextDecodeOptions* options,
+                           ExceptionState& exception_state) {
+  DCHECK(options);
+  // In case of `input` == IDL "missing" special value, default to (nullptr, 0).
+  void* start = nullptr;
+  size_t length = 0;
+  if (input) {
+    switch (input->GetContentType()) {
+      case V8BufferSource::ContentType::kArrayBuffer:
+        start = input->GetAsArrayBuffer()->Data();
+        length = input->GetAsArrayBuffer()->ByteLength();
+        break;
+      case V8BufferSource::ContentType::kArrayBufferView:
+        start = input->GetAsArrayBufferView()->BaseAddress();
+        length = input->GetAsArrayBufferView()->byteLength();
+        break;
+    }
+  }
+
+  if (length > std::numeric_limits<uint32_t>::max()) {
+    exception_state.ThrowRangeError(
+        "Buffer size exceeds maximum heap object size.");
+    return String();
+  }
+
+  return decode(static_cast<const char*>(start), static_cast<uint32_t>(length),
+                options, exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 String TextDecoder::decode(const BufferSource& input,
                            const TextDecodeOptions* options,
                            ExceptionState& exception_state) {
@@ -101,6 +133,7 @@
   return decode(static_cast<const char*>(start), static_cast<uint32_t>(length),
                 options, exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 String TextDecoder::decode(const char* start,
                            uint32_t length,
diff --git a/third_party/blink/renderer/modules/encoding/text_decoder.h b/third_party/blink/renderer/modules/encoding/text_decoder.h
index 0036e21..0bc718de 100644
--- a/third_party/blink/renderer/modules/encoding/text_decoder.h
+++ b/third_party/blink/renderer/modules/encoding/text_decoder.h
@@ -32,7 +32,9 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_ENCODING_TEXT_DECODER_H_
 
 #include <memory>
+
 #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_text_decode_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_text_decoder_options.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -62,7 +64,13 @@
   String encoding() const;
   bool fatal() const { return fatal_; }
   bool ignoreBOM() const { return ignore_bom_; }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  String decode(const V8BufferSource* input,
+                const TextDecodeOptions* options,
+                ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   String decode(const BufferSource&, const TextDecodeOptions*, ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   String decode(ExceptionState&);
 
  private:
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc b/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc
index dd092c95..c982d02 100644
--- a/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc
+++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc
@@ -4,16 +4,17 @@
 
 #include "third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h"
 
+#include <algorithm>
+#include <limits>
+
 #include "third_party/blink/public/platform/web_data.h"
 #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h"
 #include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
-#include <algorithm>
-#include <limits>
-
 namespace blink {
 
 // Represents the key ID and associated status.
@@ -65,13 +66,21 @@
 
 // Represents an Iterator that loops through the set of MapEntrys.
 class MapIterationSource final
-    : public PairIterable<ArrayBufferOrArrayBufferView,
-                          String>::IterationSource {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    : public PairIterable<Member<V8BufferSource>, String>::IterationSource
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    : public PairIterable<ArrayBufferOrArrayBufferView, String>::IterationSource
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+{
  public:
   MapIterationSource(MediaKeyStatusMap* map) : map_(map), current_(0) {}
 
   bool Next(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+            Member<V8BufferSource>& key,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
             ArrayBufferOrArrayBufferView& key,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
             String& value,
             ExceptionState&) override {
     // This simply advances an index and returns the next value if any,
@@ -80,15 +89,24 @@
       return false;
 
     const auto& entry = map_->at(current_++);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    key = MakeGarbageCollected<V8BufferSource>(entry.KeyId());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     key.SetArrayBuffer(entry.KeyId());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     value = entry.Status();
     return true;
   }
 
   void Trace(Visitor* visitor) const override {
     visitor->Trace(map_);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    PairIterable<Member<V8BufferSource>, String>::IterationSource::Trace(
+        visitor);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     PairIterable<ArrayBufferOrArrayBufferView, String>::IterationSource::Trace(
         visitor);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   }
 
  private:
@@ -129,13 +147,24 @@
   return std::numeric_limits<uint32_t>::max();
 }
 
-bool MediaKeyStatusMap::has(const ArrayBufferOrArrayBufferView& key_id) {
+bool MediaKeyStatusMap::has(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BufferSource* key_id
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const ArrayBufferOrArrayBufferView& key_id
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   uint32_t index = IndexOf(key_id);
   return index < entries_.size();
 }
 
 ScriptValue MediaKeyStatusMap::get(ScriptState* script_state,
-                                   const ArrayBufferOrArrayBufferView& key_id) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                   const V8BufferSource* key_id
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                   const ArrayBufferOrArrayBufferView& key_id
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   uint32_t index = IndexOf(key_id);
   if (index >= entries_.size()) {
     return ScriptValue(script_state->GetIsolate(),
@@ -144,8 +173,9 @@
   return ScriptValue::From(script_state, at(index).Status());
 }
 
-PairIterable<ArrayBufferOrArrayBufferView, String>::IterationSource*
-MediaKeyStatusMap::StartIteration(ScriptState*, ExceptionState&) {
+MediaKeyStatusMap::IterationSource* MediaKeyStatusMap::StartIteration(
+    ScriptState*,
+    ExceptionState&) {
   return MakeGarbageCollected<MapIterationSource>(this);
 }
 
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h b/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h
index 9e430ed3..6210c87d 100644
--- a/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h
+++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/iterable.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 
@@ -22,7 +23,12 @@
 // if the event loop runs.
 class MediaKeyStatusMap final
     : public ScriptWrappable,
-      public PairIterable<ArrayBufferOrArrayBufferView, String> {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      public PairIterable<Member<V8BufferSource>, String>
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      public PairIterable<ArrayBufferOrArrayBufferView, String>
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+{
   DEFINE_WRAPPERTYPEINFO();
 
  private:
@@ -43,8 +49,13 @@
 
   // IDL attributes / methods
   uint32_t size() const { return entries_.size(); }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  bool has(const V8BufferSource* key_id);
+  ScriptValue get(ScriptState*, const V8BufferSource* key_id);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool has(const ArrayBufferOrArrayBufferView& key_id);
   ScriptValue get(ScriptState*, const ArrayBufferOrArrayBufferView& key_id);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/modules/exported/web_crypto_normalize.cc b/third_party/blink/renderer/modules/exported/web_crypto_normalize.cc
index 0196797..9200667 100644
--- a/third_party/blink/renderer/modules/exported/web_crypto_normalize.cc
+++ b/third_party/blink/renderer/modules/exported/web_crypto_normalize.cc
@@ -32,6 +32,7 @@
 
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_object_string.h"
 #include "third_party/blink/renderer/modules/crypto/crypto_result_impl.h"
 #include "third_party/blink/renderer/modules/crypto/normalize_algorithm.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -49,8 +50,14 @@
   ExceptionState exception_state(isolate, ExceptionState::kQueryContext,
                                  "WebCryptoAlgorithm", "NormalizeAlgorithm");
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8AlgorithmIdentifier* algorithm_identifier =
+      MakeGarbageCollected<V8AlgorithmIdentifier>(
+          ScriptValue(isolate, algorithm_object));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   AlgorithmIdentifier algorithm_identifier;
   algorithm_identifier.SetObject(ScriptValue(isolate, algorithm_object));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   WebCryptoAlgorithm algorithm;
   if (!NormalizeAlgorithm(isolate, algorithm_identifier, operation, algorithm,
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_writable_file_stream.cc b/third_party/blink/renderer/modules/file_system_access/file_system_writable_file_stream.cc
index d5669046..b747270d 100644
--- a/third_party/blink/renderer/modules/file_system_access/file_system_writable_file_stream.cc
+++ b/third_party/blink/renderer/modules/file_system_access/file_system_writable_file_stream.cc
@@ -6,7 +6,10 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view_or_blob_or_usv_string.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_queuing_strategy_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_arraybuffer_arraybufferview_blob_usvstring_writeparams.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_write_params.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/streams/count_queuing_strategy.h"
@@ -14,8 +17,6 @@
 #include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h"
 #include "third_party/blink/renderer/modules/file_system_access/file_system_underlying_sink.h"
 
-#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
-
 namespace blink {
 
 FileSystemWritableFileStream* FileSystemWritableFileStream::Create(
@@ -57,15 +58,35 @@
 
 ScriptPromise FileSystemWritableFileStream::write(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionBlobOrBufferSourceOrUSVStringOrWriteParams* data,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrWriteParams& data,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   WritableStreamDefaultWriter* writer =
       WritableStream::AcquireDefaultWriter(script_state, this, exception_state);
   if (exception_state.HadException())
     return ScriptPromise();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  v8::Local<v8::Value> v8_data;
+  {
+    v8::TryCatch v8_try_block(script_state->GetIsolate());
+    if (!ToV8Traits<V8UnionBlobOrBufferSourceOrUSVStringOrWriteParams>::ToV8(
+             script_state, data)
+             .ToLocal(&v8_data)) {
+      exception_state.RethrowV8Exception(v8_try_block.Exception());
+      return ScriptPromise();
+    }
+  }
+  ScriptPromise promise = writer->write(
+      script_state, ScriptValue(script_state->GetIsolate(), v8_data),
+      exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise promise = writer->write(
       script_state, ScriptValue::From(script_state, data), exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   WritableStreamDefaultWriter::Release(script_state, writer);
   return promise;
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_writable_file_stream.h b/third_party/blink/renderer/modules/file_system_access/file_system_writable_file_stream.h
index 49389f39..aa2b85e0 100644
--- a/third_party/blink/renderer/modules/file_system_access/file_system_writable_file_stream.h
+++ b/third_party/blink/renderer/modules/file_system_access/file_system_writable_file_stream.h
@@ -9,6 +9,7 @@
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_error.mojom-blink.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_file_writer.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/modules/v8/array_buffer_or_array_buffer_view_or_blob_or_usv_string_or_write_params.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/streams/writable_stream.h"
 #include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -30,10 +31,17 @@
   void Trace(Visitor* visitor) const override;
 
   // IDL defined functions specific to FileSystemWritableFileStream.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise write(
+      ScriptState*,
+      const V8UnionBlobOrBufferSourceOrUSVStringOrWriteParams* data,
+      ExceptionState&);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise write(
       ScriptState*,
       const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrWriteParams& data,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise truncate(ScriptState*, uint64_t size, ExceptionState&);
   ScriptPromise seek(ScriptState*, uint64_t offset, ExceptionState&);
 
diff --git a/third_party/blink/renderer/modules/font_access/font_metadata.h b/third_party/blink/renderer/modules/font_access/font_metadata.h
index 38f881c..3df6dbe0 100644
--- a/third_party/blink/renderer/modules/font_access/font_metadata.h
+++ b/third_party/blink/renderer/modules/font_access/font_metadata.h
@@ -5,9 +5,10 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_METADATA_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_METADATA_H_
 
-#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/modules/font_access/font_table_map.h b/third_party/blink/renderer/modules/font_access/font_table_map.h
index b48a3e9f..9e6b120 100644
--- a/third_party/blink/renderer/modules/font_access/font_table_map.h
+++ b/third_party/blink/renderer/modules/font_access/font_table_map.h
@@ -5,7 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_TABLE_MAP_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_TABLE_MAP_H_
 
-#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/bindings/core/v8/maplike.h"
 #include "third_party/blink/renderer/core/fileapi/blob.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
diff --git a/third_party/blink/renderer/modules/hid/hid_device.cc b/third_party/blink/renderer/modules/hid/hid_device.cc
index 377bd2b..4cc5f28e 100644
--- a/third_party/blink/renderer/modules/hid/hid_device.cc
+++ b/third_party/blink/renderer/modules/hid/hid_device.cc
@@ -6,6 +6,7 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_hid_collection_info.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_hid_report_info.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -34,6 +35,26 @@
 const char kArrayBufferTooBig[] =
     "The provided ArrayBuffer exceeds the maximum allowed size.";
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+Vector<uint8_t> ConvertBufferSource(const V8BufferSource* buffer) {
+  DCHECK(buffer);
+  Vector<uint8_t> vector;
+  switch (buffer->GetContentType()) {
+    case V8BufferSource::ContentType::kArrayBuffer:
+      vector.Append(static_cast<uint8_t*>(buffer->GetAsArrayBuffer()->Data()),
+                    base::checked_cast<wtf_size_t>(
+                        buffer->GetAsArrayBuffer()->ByteLength()));
+      break;
+    case V8BufferSource::ContentType::kArrayBufferView:
+      vector.Append(
+          static_cast<uint8_t*>(buffer->GetAsArrayBufferView()->BaseAddress()),
+          base::checked_cast<wtf_size_t>(
+              buffer->GetAsArrayBufferView()->byteLength()));
+      break;
+  }
+  return vector;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 Vector<uint8_t> ConvertBufferSource(
     const ArrayBufferOrArrayBufferView& buffer) {
   DCHECK(!buffer.IsNull());
@@ -50,6 +71,7 @@
   }
   return vector;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 bool IsProtected(
     const device::mojom::blink::HidUsageAndPage& hid_usage_and_page) {
@@ -299,7 +321,12 @@
 
 ScriptPromise HIDDevice::sendReport(ScriptState* script_state,
                                     uint8_t report_id,
-                                    const ArrayBufferOrArrayBufferView& data) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                    const V8BufferSource* data
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                    const ArrayBufferOrArrayBufferView& data
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   ScriptPromiseResolver* resolver =
       MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
@@ -312,9 +339,15 @@
     return promise;
   }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  size_t data_size = data->IsArrayBuffer()
+                         ? data->GetAsArrayBuffer()->ByteLength()
+                         : data->GetAsArrayBufferView()->byteLength();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   size_t data_size = data.IsArrayBuffer()
                          ? data.GetAsArrayBuffer()->ByteLength()
                          : data.GetAsArrayBufferView()->byteLength();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   if (!base::CheckedNumeric<wtf_size_t>(data_size).IsValid()) {
     resolver->Reject(MakeGarbageCollected<DOMException>(
@@ -329,10 +362,15 @@
   return promise;
 }
 
-ScriptPromise HIDDevice::sendFeatureReport(
-    ScriptState* script_state,
-    uint8_t report_id,
-    const ArrayBufferOrArrayBufferView& data) {
+ScriptPromise HIDDevice::sendFeatureReport(ScriptState* script_state,
+                                           uint8_t report_id,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                           const V8BufferSource* data
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                           const ArrayBufferOrArrayBufferView&
+                                               data
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   ScriptPromiseResolver* resolver =
       MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
@@ -345,9 +383,15 @@
     return promise;
   }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  size_t data_size = data->IsArrayBuffer()
+                         ? data->GetAsArrayBuffer()->ByteLength()
+                         : data->GetAsArrayBufferView()->byteLength();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   size_t data_size = data.IsArrayBuffer()
                          ? data.GetAsArrayBuffer()->ByteLength()
                          : data.GetAsArrayBufferView()->byteLength();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   if (!base::CheckedNumeric<wtf_size_t>(data_size).IsValid()) {
     resolver->Reject(MakeGarbageCollected<DOMException>(
diff --git a/third_party/blink/renderer/modules/hid/hid_device.h b/third_party/blink/renderer/modules/hid/hid_device.h
index b5f6ab0..465996f 100644
--- a/third_party/blink/renderer/modules/hid/hid_device.h
+++ b/third_party/blink/renderer/modules/hid/hid_device.h
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_hid_report_item.h"
 #include "third_party/blink/renderer/core/dom/events/event_target.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
@@ -62,12 +63,21 @@
 
   ScriptPromise open(ScriptState*);
   ScriptPromise close(ScriptState*);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise sendReport(ScriptState*,
+                           uint8_t report_id,
+                           const V8BufferSource* data);
+  ScriptPromise sendFeatureReport(ScriptState*,
+                                  uint8_t report_id,
+                                  const V8BufferSource* data);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise sendReport(ScriptState*,
                            uint8_t report_id,
                            const ArrayBufferOrArrayBufferView& data);
   ScriptPromise sendFeatureReport(ScriptState*,
                                   uint8_t report_id,
                                   const ArrayBufferOrArrayBufferView& data);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise receiveFeatureReport(ScriptState*, uint8_t report_id);
 
   // ExecutionContextLifecycleObserver:
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc b/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
index 6c0070e..260ba95 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
@@ -32,6 +32,8 @@
 #include "third_party/blink/renderer/bindings/modules/v8/to_v8_for_modules.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_idb_request.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_idbcursor_idbindex_idbobjectstore.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_idbindex_idbobjectstore.h"
 #include "third_party/blink/renderer/modules/indexed_db_names.h"
 #include "third_party/blink/renderer/modules/indexeddb/idb_any.h"
 #include "third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h"
@@ -51,7 +53,11 @@
 IDBCursor::IDBCursor(std::unique_ptr<WebIDBCursor> backend,
                      mojom::IDBCursorDirection direction,
                      IDBRequest* request,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                     const Source* source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                      const Source& source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                      IDBTransaction* transaction)
     : backend_(std::move(backend)),
       request_(request),
@@ -60,7 +66,11 @@
       transaction_(transaction) {
   DCHECK(backend_);
   DCHECK(request_);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DCHECK(source_);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DCHECK(!source_.IsNull());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DCHECK(transaction_);
 }
 
@@ -124,8 +134,12 @@
 
   IDBObjectStore* object_store = EffectiveObjectStore();
   return object_store->DoPut(script_state, mojom::IDBPutMode::CursorUpdate,
-                             IDBRequest::Source::FromIDBCursor(this), value,
-                             IdbPrimaryKey(), exception_state);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                             MakeGarbageCollected<IDBRequest::Source>(this),
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                             IDBRequest::Source::FromIDBCursor(this),
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                             value, IdbPrimaryKey(), exception_state);
 }
 
 void IDBCursor::advance(unsigned count, ExceptionState& exception_state) {
@@ -218,7 +232,13 @@
     return;
   }
 
-  if (!source_.IsIDBIndex()) {
+  if (
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      !source_->IsIDBIndex()
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      !source_.IsIDBIndex()
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ) {
     exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError,
                                       "The cursor's source is not an index.");
     return;
@@ -419,9 +439,15 @@
   return script_value;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+const IDBCursor::Source* IDBCursor::source() const {
+  return source_;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void IDBCursor::source(Source& source) const {
   source = source_;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void IDBCursor::SetValueReady(std::unique_ptr<IDBKey> key,
                               std::unique_ptr<IDBKey> primary_key,
@@ -470,15 +496,37 @@
 }
 
 IDBObjectStore* IDBCursor::EffectiveObjectStore() const {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (source_->GetContentType()) {
+    case Source::ContentType::kIDBIndex:
+      return source_->GetAsIDBIndex()->objectStore();
+    case Source::ContentType::kIDBObjectStore:
+      return source_->GetAsIDBObjectStore();
+  }
+  NOTREACHED();
+  return nullptr;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (source_.IsIDBObjectStore())
     return source_.GetAsIDBObjectStore();
   return source_.GetAsIDBIndex()->objectStore();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 bool IDBCursor::IsDeleted() const {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (source_->GetContentType()) {
+    case Source::ContentType::kIDBIndex:
+      return source_->GetAsIDBIndex()->IsDeleted();
+    case Source::ContentType::kIDBObjectStore:
+      return source_->GetAsIDBObjectStore()->IsDeleted();
+  }
+  NOTREACHED();
+  return false;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (source_.IsIDBObjectStore())
     return source_.GetAsIDBObjectStore()->IsDeleted();
   return source_.GetAsIDBIndex()->IsDeleted();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 mojom::IDBCursorDirection IDBCursor::StringToDirection(
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_cursor.h b/third_party/blink/renderer/modules/indexeddb/idb_cursor.h
index 7f0f682e..f6a8a5a4 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_cursor.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_cursor.h
@@ -45,20 +45,33 @@
 class IDBTransaction;
 class IDBValue;
 class ScriptState;
+class V8UnionIDBIndexOrIDBObjectStore;
 
 class IDBCursor : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  using Source = V8UnionIDBIndexOrIDBObjectStore;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   using Source = IDBObjectStoreOrIDBIndex;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   static mojom::IDBCursorDirection StringToDirection(const String& mode_string);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  IDBCursor(std::unique_ptr<WebIDBCursor> backend,
+            mojom::blink::IDBCursorDirection direction,
+            IDBRequest* request,
+            const Source* source,
+            IDBTransaction* transaction);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   IDBCursor(std::unique_ptr<WebIDBCursor>,
             mojom::IDBCursorDirection,
             IDBRequest*,
             const Source&,
             IDBTransaction*);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ~IDBCursor() override;
 
   void Trace(Visitor*) const override;
@@ -75,7 +88,11 @@
   ScriptValue primaryKey(ScriptState*);
   ScriptValue value(ScriptState*);
   IDBRequest* request() { return request_.Get(); }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const Source* source() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void source(Source&) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   IDBRequest* update(ScriptState*, const ScriptValue&, ExceptionState&);
   void advance(unsigned, ExceptionState&);
@@ -110,7 +127,11 @@
   std::unique_ptr<WebIDBCursor> backend_;
   Member<IDBRequest> request_;
   const mojom::IDBCursorDirection direction_;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Member<const Source> source_;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Source source_;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Member<IDBTransaction> transaction_;
   bool got_value_ = false;
   bool key_dirty_ = true;
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.cc b/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.cc
index 09bfec8..1e8aab7 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.cc
@@ -35,9 +35,14 @@
 IDBCursorWithValue::IDBCursorWithValue(std::unique_ptr<WebIDBCursor> backend,
                                        mojom::IDBCursorDirection direction,
                                        IDBRequest* request,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                       const Source* source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                        const Source& source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                        IDBTransaction* transaction)
-    : IDBCursor(std::move(backend), direction, request, source, transaction) {}
+    : IDBCursor(std::move(backend), direction, request, source, transaction) {
+}
 
 IDBCursorWithValue::~IDBCursorWithValue() = default;
 
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h b/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h
index 26b35f26..e41f92c 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h
@@ -45,7 +45,11 @@
   IDBCursorWithValue(std::unique_ptr<WebIDBCursor>,
                      mojom::IDBCursorDirection,
                      IDBRequest*,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                     const Source*,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                      const Source&,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                      IDBTransaction*);
   ~IDBCursorWithValue() override;
 
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_database.cc b/third_party/blink/renderer/modules/indexeddb/idb_database.cc
index 9f2a3e6..318d082 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_database.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -35,6 +35,7 @@
 #include "third_party/blink/public/common/indexeddb/web_idb_types.h"
 #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_stringsequence.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/dom/events/event_queue.h"
@@ -330,7 +331,11 @@
 
 IDBTransaction* IDBDatabase::transaction(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionStringOrStringSequence* store_names,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const StringOrStringSequence& store_names,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const String& mode,
     ExceptionState& exception_state) {
   return transaction(script_state, store_names, mode, nullptr, exception_state);
@@ -338,13 +343,29 @@
 
 IDBTransaction* IDBDatabase::transaction(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionStringOrStringSequence* store_names,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const StringOrStringSequence& store_names,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const String& mode_string,
     const IDBTransactionOptions* options,
     ExceptionState& exception_state) {
   IDB_TRACE("IDBDatabase::transaction");
 
   HashSet<String> scope;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DCHECK(store_names);
+  switch (store_names->GetContentType()) {
+    case V8UnionStringOrStringSequence::ContentType::kString:
+      scope.insert(store_names->GetAsString());
+      break;
+    case V8UnionStringOrStringSequence::ContentType::kStringSequence:
+      for (const String& name : store_names->GetAsStringSequence())
+        scope.insert(name);
+      break;
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (store_names.IsString()) {
     scope.insert(store_names.GetAsString());
   } else if (store_names.IsStringSequence()) {
@@ -353,6 +374,7 @@
   } else {
     NOTREACHED();
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   if (version_change_transaction_) {
     exception_state.ThrowDOMException(
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_database.h b/third_party/blink/renderer/modules/indexeddb/idb_database.h
index 738010b..bbdf8fa2 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_database.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_database.h
@@ -55,6 +55,7 @@
 
 class ExceptionState;
 class ExecutionContext;
+class V8UnionStringOrStringSequence;
 
 class MODULES_EXPORT IDBDatabase final
     : public EventTargetWithInlineData,
@@ -96,6 +97,17 @@
     return createObjectStore(name, IDBKeyPath(options->keyPath()),
                              options->autoIncrement(), exception_state);
   }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  IDBTransaction* transaction(ScriptState* script_state,
+                              const V8UnionStringOrStringSequence* store_names,
+                              const String& mode,
+                              ExceptionState& exception_state);
+  IDBTransaction* transaction(ScriptState* script_state,
+                              const V8UnionStringOrStringSequence* store_names,
+                              const String& mode,
+                              const IDBTransactionOptions* options,
+                              ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   IDBTransaction* transaction(ScriptState*,
                               const StringOrStringSequence& store_names,
                               const String& mode,
@@ -105,6 +117,7 @@
                               const String& mode,
                               const IDBTransactionOptions* options,
                               ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void deleteObjectStore(const String& name, ExceptionState&);
   void close();
 
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc b/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc
index d4c6486b..20664f1 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/modules/indexeddb/idb_key_path.h"
 
 #include "third_party/blink/public/common/indexeddb/web_idb_types.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_stringsequence.h"
 #include "third_party/blink/renderer/platform/wtf/dtoa.h"
 #include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h"
 #include "third_party/blink/renderer/platform/wtf/text/character_names.h"
@@ -114,6 +115,31 @@
 #endif
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+IDBKeyPath::IDBKeyPath(const V8UnionStringOrStringSequence* key_path) {
+  if (!key_path) {
+    type_ = mojom::IDBKeyPathType::Null;
+    return;
+  }
+
+  switch (key_path->GetContentType()) {
+    case V8UnionStringOrStringSequence::ContentType::kString:
+      type_ = mojom::IDBKeyPathType::String;
+      string_ = key_path->GetAsString();
+      DCHECK(!string_.IsNull());
+      break;
+    case V8UnionStringOrStringSequence::ContentType::kStringSequence:
+      type_ = mojom::IDBKeyPathType::Array;
+      array_ = key_path->GetAsStringSequence();
+#if DCHECK_IS_ON()
+      for (const auto& element : array_)
+        DCHECK(!element.IsNull());
+#endif
+      break;
+  }
+}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 IDBKeyPath::IDBKeyPath(const StringOrStringSequence& key_path) {
   if (key_path.IsNull()) {
     type_ = mojom::IDBKeyPathType::Null;
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_key_path.h b/third_party/blink/renderer/modules/indexeddb/idb_key_path.h
index 3a9dbe2..f003d97 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_key_path.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_key_path.h
@@ -35,6 +35,8 @@
 
 namespace blink {
 
+class V8UnionStringOrStringSequence;
+
 enum IDBKeyPathParseError {
   kIDBKeyPathParseErrorNone,
   kIDBKeyPathParseErrorIdentifier,
@@ -51,6 +53,10 @@
   IDBKeyPath() : type_(mojom::IDBKeyPathType::Null) {}
   explicit IDBKeyPath(const String&);
   explicit IDBKeyPath(const Vector<String>& array);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  explicit IDBKeyPath(const V8UnionStringOrStringSequence* key_path);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  // TODO(crbug.com/1181288): Remove the old IDL union version.
   explicit IDBKeyPath(const StringOrStringSequence& key_path);
 
   mojom::IDBKeyPathType GetType() const { return type_; }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc b/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
index 8af6a84..60dca5a2 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
@@ -40,6 +40,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
 #include "third_party/blink/renderer/bindings/modules/v8/to_v8_for_modules.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_idbcursor_idbindex_idbobjectstore.h"
 #include "third_party/blink/renderer/core/dom/dom_string_list.h"
 #include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -400,7 +401,12 @@
     keys.push_back(std::move(key_ptr));
   }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const IDBRequest::Source* source =
+      MakeGarbageCollected<IDBRequest::Source>(this);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   IDBRequest::Source source = IDBRequest::Source::FromIDBObjectStore(this);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   IDBRequest::AsyncTraceState metrics("IDBObjectStore::putAll");
   if (IsDeleted()) {
@@ -597,13 +603,21 @@
   if (exception_state.HadException())
     return nullptr;
   return DoPut(script_state, put_mode,
-               IDBRequest::Source::FromIDBObjectStore(this), value, key.get(),
-               exception_state);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+               MakeGarbageCollected<IDBRequest::Source>(this),
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+               IDBRequest::Source::FromIDBObjectStore(this),
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+               value, key.get(), exception_state);
 }
 
 IDBRequest* IDBObjectStore::DoPut(ScriptState* script_state,
                                   mojom::IDBPutMode put_mode,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                  const IDBRequest::Source* source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                   const IDBRequest::Source& source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                   const ScriptValue& value,
                                   const IDBKey* key,
                                   ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_object_store.h b/third_party/blink/renderer/modules/indexeddb/idb_object_store.h
index 1761c674..2424b6f 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_object_store.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_object_store.h
@@ -121,7 +121,11 @@
 
   IDBIndex* createIndex(ScriptState* script_state,
                         const String& name,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                        const V8UnionStringOrStringSequence* key_path,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                         const StringOrStringSequence& key_path,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                         const IDBIndexParameters* options,
                         ExceptionState& exception_state) {
     return createIndex(script_state, name, IDBKeyPath(key_path), options,
@@ -135,7 +139,11 @@
   // Exposed for the use of IDBCursor::update().
   IDBRequest* DoPut(ScriptState*,
                     mojom::IDBPutMode,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                    const IDBRequest::Source*,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                     const IDBRequest::Source&,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                     const ScriptValue&,
                     const IDBKey*,
                     ExceptionState&);
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc b/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc
index d2fa6e91..7273d921 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc
@@ -50,7 +50,11 @@
     IDBRequest::AsyncTraceState metrics,
     mojo::PendingRemote<mojom::blink::ObservedFeature> connection_lifetime)
     : IDBRequest(script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                 nullptr,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                  IDBRequest::Source(),
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                  nullptr,
                  std::move(metrics)),
       callbacks_receiver_(std::move(callbacks_receiver)),
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.cc b/third_party/blink/renderer/modules/indexeddb/idb_request.cc
index f4c494d..1d5a248e 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_request.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -37,6 +37,8 @@
 #include "third_party/blink/renderer/bindings/modules/v8/idb_object_store_or_idb_index_or_idb_cursor.h"
 #include "third_party/blink/renderer/bindings/modules/v8/to_v8_for_modules.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_idbcursor_idbindex_idbobjectstore.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_idbindex_idbobjectstore.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/dom/events/event_queue.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -98,28 +100,50 @@
                                IDBIndex* source,
                                IDBTransaction* transaction,
                                IDBRequest::AsyncTraceState metrics) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  return Create(script_state,
+                source ? MakeGarbageCollected<Source>(source) : nullptr,
+                transaction, std::move(metrics));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   return IDBRequest::Create(script_state, Source::FromIDBIndex(source),
                             transaction, std::move(metrics));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 IDBRequest* IDBRequest::Create(ScriptState* script_state,
                                IDBObjectStore* source,
                                IDBTransaction* transaction,
                                IDBRequest::AsyncTraceState metrics) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  return Create(script_state,
+                source ? MakeGarbageCollected<Source>(source) : nullptr,
+                transaction, std::move(metrics));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   return IDBRequest::Create(script_state, Source::FromIDBObjectStore(source),
                             transaction, std::move(metrics));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 IDBRequest* IDBRequest::Create(ScriptState* script_state,
                                IDBCursor* source,
                                IDBTransaction* transaction,
                                IDBRequest::AsyncTraceState metrics) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  return Create(script_state,
+                source ? MakeGarbageCollected<Source>(source) : nullptr,
+                transaction, std::move(metrics));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   return IDBRequest::Create(script_state, Source::FromIDBCursor(source),
                             transaction, std::move(metrics));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 IDBRequest* IDBRequest::Create(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                               const Source* source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                const Source& source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                IDBTransaction* transaction,
                                IDBRequest::AsyncTraceState metrics) {
   IDBRequest* request = MakeGarbageCollected<IDBRequest>(
@@ -132,7 +156,11 @@
 }
 
 IDBRequest::IDBRequest(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                       const Source* source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                        const Source& source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                        IDBTransaction* transaction,
                        AsyncTraceState metrics)
     : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
@@ -142,7 +170,8 @@
       source_(source),
       event_queue_(
           MakeGarbageCollected<EventQueue>(ExecutionContext::From(script_state),
-                                           TaskType::kDatabaseAccess)) {}
+                                           TaskType::kDatabaseAccess)) {
+}
 
 IDBRequest::~IDBRequest() {
   if (!GetExecutionContext())
@@ -194,6 +223,13 @@
   return error_;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+const IDBRequest::Source* IDBRequest::source(ScriptState* script_state) const {
+  if (!GetExecutionContext())
+    return nullptr;
+  return source_;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void IDBRequest::source(ScriptState* script_state,
                         IDBObjectStoreOrIDBIndexOrIDBCursor& source) const {
   if (!GetExecutionContext()) {
@@ -201,6 +237,7 @@
   }
   source = source_;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 const String& IDBRequest::readyState() const {
   DCHECK(ready_state_ == PENDING || ready_state_ == DONE);
@@ -450,6 +487,24 @@
 
   DCHECK(!pending_cursor_);
   IDBCursor* cursor = nullptr;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  IDBCursor::Source* source = nullptr;
+
+  DCHECK(source_);
+  switch (source_->GetContentType()) {
+    case Source::ContentType::kIDBCursor:
+      break;
+    case Source::ContentType::kIDBIndex:
+      source =
+          MakeGarbageCollected<IDBCursor::Source>(source_->GetAsIDBIndex());
+      break;
+    case Source::ContentType::kIDBObjectStore:
+      source = MakeGarbageCollected<IDBCursor::Source>(
+          source_->GetAsIDBObjectStore());
+      break;
+  }
+  DCHECK(source);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   IDBObjectStoreOrIDBIndex source;
 
   if (source_.IsIDBObjectStore()) {
@@ -459,6 +514,7 @@
     source = IDBCursor::Source::FromIDBIndex(source_.GetAsIDBIndex());
   }
   DCHECK(!source.IsNull());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   switch (cursor_type_) {
     case indexed_db::kCursorKeyOnly:
@@ -512,6 +568,22 @@
 }
 
 #if DCHECK_IS_ON()
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+static IDBObjectStore* EffectiveObjectStore(const IDBRequest::Source* source) {
+  DCHECK(source);
+  switch (source->GetContentType()) {
+    case IDBRequest::Source::ContentType::kIDBCursor:
+      NOTREACHED();
+      return nullptr;
+    case IDBRequest::Source::ContentType::kIDBIndex:
+      return source->GetAsIDBIndex()->objectStore();
+    case IDBRequest::Source::ContentType::kIDBObjectStore:
+      return source->GetAsIDBObjectStore();
+  }
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 static IDBObjectStore* EffectiveObjectStore(const IDBRequest::Source& source) {
   if (source.IsIDBObjectStore())
     return source.GetAsIDBObjectStore();
@@ -521,6 +593,7 @@
   NOTREACHED();
   return nullptr;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 #endif  // DCHECK_IS_ON()
 
 void IDBRequest::EnqueueResponse(std::unique_ptr<IDBValue> value) {
@@ -609,8 +682,13 @@
       transaction_->UnregisterRequest(this);
   }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  if (source_ && source_->IsIDBCursor())
+    source_->GetAsIDBCursor()->ContextWillBeDestroyed();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (source_.IsIDBCursor())
     source_.GetAsIDBCursor()->ContextWillBeDestroyed();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (result_)
     result_->ContextWillBeDestroyed();
   if (pending_cursor_)
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.h b/third_party/blink/renderer/modules/indexeddb/idb_request.h
index 7f0deaf..bed4528e 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_request.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_request.h
@@ -63,6 +63,7 @@
 class IDBCursor;
 struct IDBDatabaseMetadata;
 class IDBValue;
+class V8UnionIDBCursorOrIDBIndexOrIDBObjectStore;
 
 class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
                                   public ActiveScriptWrappable<IDBRequest>,
@@ -70,7 +71,11 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  using Source = V8UnionIDBCursorOrIDBIndexOrIDBObjectStore;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   using Source = IDBObjectStoreOrIDBIndexOrIDBCursor;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   // Container for async tracing state.
   //
   // The documentation for TRACE_EVENT_NESTABLE_ASYNC_{BEGIN,END} suggests
@@ -176,11 +181,22 @@
                             IDBTransaction* source,
                             AsyncTraceState);
   static IDBRequest* Create(ScriptState*,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                            const Source*,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                             const Source&,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                             IDBTransaction*,
                             AsyncTraceState);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  IDBRequest(ScriptState* script_state,
+             const Source* source,
+             IDBTransaction* transaction,
+             AsyncTraceState metrics);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   IDBRequest(ScriptState*, const Source&, IDBTransaction*, AsyncTraceState);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ~IDBRequest() override;
 
   void Trace(Visitor*) const override;
@@ -188,7 +204,11 @@
   v8::Isolate* GetIsolate() const { return isolate_; }
   ScriptValue result(ScriptState*, ExceptionState&);
   DOMException* error(ExceptionState&) const;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const Source* source(ScriptState* script_state) const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void source(ScriptState*, Source&) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   IDBTransaction* transaction() const { return transaction_.Get(); }
 
   bool isResultDirty() const { return result_dirty_; }
@@ -388,7 +408,11 @@
 
   void ClearPutOperationBlobs() { transit_blob_handles_.clear(); }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Member<const Source> source_;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Source source_;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   Member<IDBAny> result_;
   Member<DOMException> error_;
 
diff --git a/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc b/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
index b034b238..4a2e9c4 100644
--- a/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
+++ b/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
@@ -36,6 +36,7 @@
 #include "third_party/blink/public/common/indexeddb/web_idb_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_stringsequence.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_idb_transaction_options.h"
 #include "third_party/blink/renderer/core/dom/dom_string_list.h"
 #include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
@@ -331,8 +332,13 @@
     const String& object_store_name,
     const String& mode = indexed_db_names::kReadonly) {
   DummyExceptionStateForTesting exception_state;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionStringOrStringSequence* scope =
+      MakeGarbageCollected<V8UnionStringOrStringSequence>(object_store_name);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrStringSequence scope;
   scope.SetString(object_store_name);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   IDBTransactionOptions options;
   options.setDurability("relaxed");
   IDBTransaction* idb_transaction = idb_database->transaction(
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
index 24dc941..b556f28 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -94,6 +94,17 @@
   WebTimeRanges seekable_;
 };
 
+class MockLayoutObject : public LayoutObject {
+ public:
+  MockLayoutObject(Node* node) : LayoutObject(node) {}
+
+  const char* GetName() const override { return "MockLayoutObject"; }
+  void UpdateLayout() override {}
+  FloatRect LocalBoundingBoxRectForAccessibility() const override {
+    return FloatRect();
+  }
+};
+
 class StubLocalFrameClientForImpl : public EmptyLocalFrameClient {
  public:
   std::unique_ptr<WebMediaPlayer> CreateWebMediaPlayer(
@@ -960,8 +971,6 @@
   auto& video =
       To<HTMLVideoElement>(*page_holder->GetDocument().QuerySelector("video"));
   WeakPersistent<HTMLMediaElement> weak_persistent_video = &video;
-  WeakPersistent<LayoutObject> weak_persistent_layout_object =
-      video.GetLayoutObject();
 
   video.remove();
   page_holder->GetDocument().View()->UpdateAllLifecyclePhasesForTest();
@@ -969,7 +978,6 @@
 
   ThreadState::Current()->CollectAllGarbageForTesting();
   EXPECT_EQ(nullptr, weak_persistent_video);
-  EXPECT_EQ(nullptr, weak_persistent_layout_object);
 }
 
 TEST_F(MediaControlsImplTest,
diff --git a/third_party/blink/renderer/modules/mediasource/source_buffer.cc b/third_party/blink/renderer/modules/mediasource/source_buffer.cc
index 6530b38..b3653f1 100644
--- a/third_party/blink/renderer/modules/mediasource/source_buffer.cc
+++ b/third_party/blink/renderer/modules/mediasource/source_buffer.cc
@@ -47,6 +47,8 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_source_buffer_config.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_encodedaudiochunk_encodedaudiochunkorencodedvideochunksequence_encodedvideochunk.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_encodedaudiochunk_encodedvideochunk.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_config.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -631,7 +633,11 @@
 // append use-cases.
 ScriptPromise SourceBuffer::appendEncodedChunks(
     ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8EncodedChunks* chunks,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const EncodedChunks& chunks,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
   DVLOG(2) << __func__ << " this=" << this;
 
@@ -655,6 +661,62 @@
   auto buffer_queue = std::make_unique<media::StreamParser::BufferQueue>();
   size_t size = 0;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (chunks->GetContentType()) {
+    case V8EncodedChunks::ContentType::kEncodedAudioChunk:
+      buffer_queue->emplace_back(
+          MakeAudioStreamParserBuffer(*(chunks->GetAsEncodedAudioChunk())));
+      size += buffer_queue->back()->data_size() +
+              buffer_queue->back()->side_data_size();
+      break;
+    case V8EncodedChunks::ContentType::kEncodedVideoChunk: {
+      const auto& video_chunk = *(chunks->GetAsEncodedVideoChunk());
+      if (!video_chunk.duration().has_value()) {
+        MediaSource::LogAndThrowTypeError(
+            exception_state,
+            "EncodedVideoChunk is missing duration, required for use with "
+            "SourceBuffer.");
+        return ScriptPromise();
+      }
+      buffer_queue->emplace_back(MakeVideoStreamParserBuffer(video_chunk));
+      size += buffer_queue->back()->data_size() +
+              buffer_queue->back()->side_data_size();
+      break;
+    }
+    case V8EncodedChunks::ContentType::
+        kEncodedAudioChunkOrEncodedVideoChunkSequence:
+      for (const auto& av_chunk :
+           chunks->GetAsEncodedAudioChunkOrEncodedVideoChunkSequence()) {
+        DCHECK(av_chunk);
+        switch (av_chunk->GetContentType()) {
+          case V8UnionEncodedAudioChunkOrEncodedVideoChunk::ContentType::
+              kEncodedAudioChunk:
+            buffer_queue->emplace_back(MakeAudioStreamParserBuffer(
+                *(av_chunk->GetAsEncodedAudioChunk())));
+            size += buffer_queue->back()->data_size() +
+                    buffer_queue->back()->side_data_size();
+            break;
+          case V8UnionEncodedAudioChunkOrEncodedVideoChunk::ContentType::
+              kEncodedVideoChunk: {
+            const auto& video_chunk = *(av_chunk->GetAsEncodedVideoChunk());
+            if (!video_chunk.duration().has_value()) {
+              MediaSource::LogAndThrowTypeError(
+                  exception_state,
+                  "EncodedVideoChunk is missing duration, required for use "
+                  "with SourceBuffer.");
+              return ScriptPromise();
+            }
+            buffer_queue->emplace_back(
+                MakeVideoStreamParserBuffer(video_chunk));
+            size += buffer_queue->back()->data_size() +
+                    buffer_queue->back()->side_data_size();
+            break;
+          }
+        }
+      }
+      break;
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (chunks.IsEncodedAudioChunk()) {
     buffer_queue->emplace_back(
         MakeAudioStreamParserBuffer(*(chunks.GetAsEncodedAudioChunk())));
@@ -702,6 +764,7 @@
       }
     }
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   DCHECK(!append_encoded_chunks_resolver_);
   append_encoded_chunks_resolver_ =
diff --git a/third_party/blink/renderer/modules/mediasource/source_buffer.h b/third_party/blink/renderer/modules/mediasource/source_buffer.h
index 92bc081..6592b2d 100644
--- a/third_party/blink/renderer/modules/mediasource/source_buffer.h
+++ b/third_party/blink/renderer/modules/mediasource/source_buffer.h
@@ -38,6 +38,7 @@
 #include "third_party/blink/public/platform/web_source_buffer_client.h"
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
 #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
 #include "third_party/blink/renderer/modules/event_target_modules.h"
@@ -93,9 +94,15 @@
   void setTimestampOffset(double, ExceptionState&);
   void appendBuffer(DOMArrayBuffer* data, ExceptionState&);
   void appendBuffer(NotShared<DOMArrayBufferView> data, ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise appendEncodedChunks(ScriptState* script_state,
+                                    const V8EncodedChunks* chunks,
+                                    ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise appendEncodedChunks(ScriptState*,
                                     const EncodedChunks&,
                                     ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void abort(ExceptionState&);
   void remove(double start, double end, ExceptionState&);
   void changeType(const String& type, ExceptionState&);
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.cc b/third_party/blink/renderer/modules/mediastream/media_devices.cc
index ff0c464..b1abeb9 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -16,6 +16,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_constraints.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_supported_constraints.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_domexception_overconstrainederror.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -53,10 +54,17 @@
                  MediaStream* stream) override {
     resolver_->Resolve(stream);
   }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void OnError(ScriptWrappable* callback_this_value,
+               const V8MediaStreamError* error) override {
+    resolver_->Reject(error);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void OnError(ScriptWrappable* callback_this_value,
                DOMExceptionOrOverconstrainedError error) override {
     resolver_->Reject(error);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor* visitor) const override {
     visitor->Trace(resolver_);
diff --git a/third_party/blink/renderer/modules/mediastream/media_error_state.cc b/third_party/blink/renderer/modules/mediastream/media_error_state.cc
index 3fbe384..da1ddaeb 100644
--- a/third_party/blink/renderer/modules/mediastream/media_error_state.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_error_state.cc
@@ -30,6 +30,7 @@
 
 #include "third_party/blink/renderer/modules/mediastream/media_error_state.h"
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_domexception_overconstrainederror.h"
 #include "third_party/blink/renderer/modules/mediastream/overconstrained_error.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
 
@@ -116,10 +117,18 @@
   return String();
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionDOMExceptionOrOverconstrainedError* MediaErrorState::CreateError() {
+  DCHECK_EQ(error_type_, kConstraintError);
+  return MakeGarbageCollected<V8UnionDOMExceptionOrOverconstrainedError>(
+      MakeGarbageCollected<OverconstrainedError>(constraint_, message_));
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 DOMExceptionOrOverconstrainedError MediaErrorState::CreateError() {
   DCHECK(error_type_ == kConstraintError);
   return DOMExceptionOrOverconstrainedError::FromOverconstrainedError(
       MakeGarbageCollected<OverconstrainedError>(constraint_, message_));
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/media_error_state.h b/third_party/blink/renderer/modules/mediastream/media_error_state.h
index 34ba5342..ec918f5 100644
--- a/third_party/blink/renderer/modules/mediastream/media_error_state.h
+++ b/third_party/blink/renderer/modules/mediastream/media_error_state.h
@@ -38,6 +38,7 @@
 namespace blink {
 
 class OverconstrainedError;
+class V8UnionDOMExceptionOrOverconstrainedError;
 
 // A class that is able to be used like ExceptionState for carrying
 // information about an error up the stack, but it is up to the higher
@@ -56,7 +57,11 @@
   bool CanGenerateException();
   void RaiseException(ExceptionState&);
   String GetErrorMessage();
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionDOMExceptionOrOverconstrainedError* CreateError();
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DOMExceptionOrOverconstrainedError CreateError();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
  private:
   enum ErrorType { kNoError, kTypeError, kDOMException, kConstraintError };
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_request.cc b/third_party/blink/renderer/modules/mediastream/user_media_request.cc
index c0da974..fc89221 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_request.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_request.cc
@@ -41,6 +41,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_constraints.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_constraints.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_domexception_overconstrainederror.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/dom/space_split_string.h"
 #include "third_party/blink/renderer/core/frame/deprecation.h"
@@ -317,10 +318,17 @@
                  MediaStream* stream) override {
     success_callback_->InvokeAndReportException(callback_this_value, stream);
   }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void OnError(ScriptWrappable* callback_this_value,
+               const V8MediaStreamError* error) override {
+    error_callback_->InvokeAndReportException(callback_this_value, error);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void OnError(ScriptWrappable* callback_this_value,
                DOMExceptionOrOverconstrainedError error) override {
     error_callback_->InvokeAndReportException(callback_this_value, error);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
  private:
   Member<V8NavigatorUserMediaSuccessCallback> success_callback_;
@@ -573,9 +581,15 @@
   RecordIdentifiabilityMetric(surface_, GetExecutionContext(),
                               IdentifiabilityBenignStringToken(message));
   // After this call, the execution context may be invalid.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  callbacks_->OnError(
+      nullptr, MakeGarbageCollected<V8MediaStreamError>(
+                   OverconstrainedError::Create(constraint_name, message)));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   callbacks_->OnError(
       nullptr, DOMExceptionOrOverconstrainedError::FromOverconstrainedError(
                    OverconstrainedError::Create(constraint_name, message)));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   is_resolved_ = true;
 }
 
@@ -617,10 +631,16 @@
   RecordIdentifiabilityMetric(surface_, GetExecutionContext(),
                               IdentifiabilityBenignStringToken(message));
   // After this call, the execution context may be invalid.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  callbacks_->OnError(nullptr, MakeGarbageCollected<V8MediaStreamError>(
+                                   MakeGarbageCollected<DOMException>(
+                                       exception_code, message)));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   callbacks_->OnError(
       nullptr,
       DOMExceptionOrOverconstrainedError::FromDOMException(
           MakeGarbageCollected<DOMException>(exception_code, message)));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   is_resolved_ = true;
 }
 
@@ -635,11 +655,18 @@
           "audio constraints=%s, video constraints=%s",
           AudioConstraints().ToString().Utf8().c_str(),
           VideoConstraints().ToString().Utf8().c_str()));
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      callbacks_->OnError(nullptr, MakeGarbageCollected<V8MediaStreamError>(
+                                       MakeGarbageCollected<DOMException>(
+                                           DOMExceptionCode::kAbortError,
+                                           "Context destroyed")));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
       callbacks_->OnError(
           nullptr,
           DOMExceptionOrOverconstrainedError::FromDOMException(
               MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError,
                                                  "Context destroyed")));
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     }
     controller_ = nullptr;
   }
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_request.h b/third_party/blink/renderer/modules/mediastream/user_media_request.h
index 6e58987..12d7261 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_request.h
+++ b/third_party/blink/renderer/modules/mediastream/user_media_request.h
@@ -32,8 +32,10 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_USER_MEDIA_REQUEST_H_
 
 #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
+#include "third_party/blink/renderer/bindings/modules/v8/dom_exception_or_overconstrained_error.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_navigator_user_media_error_callback.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_navigator_user_media_success_callback.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
@@ -80,8 +82,13 @@
 
     virtual void OnSuccess(ScriptWrappable* callback_this_value,
                            MediaStream*) = 0;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    virtual void OnError(ScriptWrappable* callback_this_value,
+                         const V8MediaStreamError* error) = 0;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     virtual void OnError(ScriptWrappable* callback_this_value,
                          DOMExceptionOrOverconstrainedError) = 0;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
     virtual void Trace(Visitor*) const {}
 
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
index b1748b1d4..391f6b7b 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_renderer.h"
 #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_video_renderer.h"
 #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
+#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/url_conversion.h"
 #include "third_party/blink/public/platform/web_media_player_client.h"
 #include "third_party/blink/public/platform/web_media_player_source.h"
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
index 2f0da77..a42f7bb 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc
@@ -22,6 +22,7 @@
 #include "media/renderers/paint_canvas_video_renderer.h"
 #include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
 #include "skia/ext/platform_canvas.h"
+#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_video_frame_submitter.h"
 #include "third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h"
 #include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
diff --git a/third_party/blink/renderer/modules/nfc/ndef_message.cc b/third_party/blink/renderer/modules/nfc/ndef_message.cc
index bceaacb1..a9b78254 100644
--- a/third_party/blink/renderer/modules/nfc/ndef_message.cc
+++ b/third_party/blink/renderer/modules/nfc/ndef_message.cc
@@ -8,6 +8,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_array_buffer_or_array_buffer_view_or_ndef_message_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_message_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_record_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_arraybuffer_arraybufferview_ndefmessageinit_string.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/modules/nfc/ndef_record.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -41,6 +42,65 @@
   return message;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// static
+NDEFMessage* NDEFMessage::Create(const ExecutionContext* execution_context,
+                                 const V8NDEFMessageSource* source,
+                                 ExceptionState& exception_state) {
+  DCHECK(source);
+
+  // https://w3c.github.io/web-nfc/#creating-ndef-message
+  switch (source->GetContentType()) {
+    case V8NDEFMessageSource::ContentType::kArrayBuffer: {
+      WTF::Vector<uint8_t> payload_data;
+      size_t byte_length = source->GetAsArrayBuffer()->ByteLength();
+      if (byte_length > std::numeric_limits<wtf_size_t>::max()) {
+        exception_state.ThrowRangeError(
+            "Buffer size exceeds maximum heap object size.");
+        return nullptr;
+      }
+      payload_data.Append(
+          static_cast<uint8_t*>(source->GetAsArrayBuffer()->Data()),
+          static_cast<wtf_size_t>(byte_length));
+      NDEFMessage* message = MakeGarbageCollected<NDEFMessage>();
+      message->records_.push_back(MakeGarbageCollected<NDEFRecord>(
+          String() /* id */, "application/octet-stream",
+          std::move(payload_data)));
+      return message;
+    }
+    case V8NDEFMessageSource::ContentType::kArrayBufferView: {
+      size_t byte_length = source->GetAsArrayBufferView()->byteLength();
+      if (byte_length > std::numeric_limits<wtf_size_t>::max()) {
+        exception_state.ThrowRangeError(
+            "Buffer size exceeds maximum heap object size.");
+        return nullptr;
+      }
+      WTF::Vector<uint8_t> payload_data;
+      payload_data.Append(
+          static_cast<uint8_t*>(source->GetAsArrayBufferView()->BaseAddress()),
+          static_cast<wtf_size_t>(byte_length));
+      NDEFMessage* message = MakeGarbageCollected<NDEFMessage>();
+      message->records_.push_back(MakeGarbageCollected<NDEFRecord>(
+          String() /* id */, "application/octet-stream",
+          std::move(payload_data)));
+      return message;
+    }
+    case V8NDEFMessageSource::ContentType::kNDEFMessageInit: {
+      return Create(execution_context, source->GetAsNDEFMessageInit(),
+                    exception_state);
+    }
+    case V8NDEFMessageSource::ContentType::kString: {
+      NDEFMessage* message = MakeGarbageCollected<NDEFMessage>();
+      message->records_.push_back(MakeGarbageCollected<NDEFRecord>(
+          execution_context, source->GetAsString()));
+      return message;
+    }
+  }
+
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 // static
 NDEFMessage* NDEFMessage::Create(const ExecutionContext* execution_context,
                                  const NDEFMessageSource& source,
@@ -97,6 +157,7 @@
   NOTREACHED();
   return nullptr;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 // static
 NDEFMessage* NDEFMessage::CreateAsPayloadOfSmartPoster(
diff --git a/third_party/blink/renderer/modules/nfc/ndef_message.h b/third_party/blink/renderer/modules/nfc/ndef_message.h
index c6183f07..e3c8e7bdfd 100644
--- a/third_party/blink/renderer/modules/nfc/ndef_message.h
+++ b/third_party/blink/renderer/modules/nfc/ndef_message.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_NFC_NDEF_MESSAGE_H_
 
 #include "services/device/public/mojom/nfc.mojom-blink-forward.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -30,9 +31,15 @@
                              const NDEFMessageInit*,
                              ExceptionState&,
                              bool is_embedded = false);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static NDEFMessage* Create(const ExecutionContext* execution_context,
+                             const V8NDEFMessageSource* source,
+                             ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static NDEFMessage* Create(const ExecutionContext*,
                              const NDEFMessageSource&,
                              ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static NDEFMessage* CreateAsPayloadOfSmartPoster(const ExecutionContext*,
                                                    const NDEFMessageInit*,
                                                    ExceptionState&);
diff --git a/third_party/blink/renderer/modules/nfc/ndef_reader.cc b/third_party/blink/renderer/modules/nfc/ndef_reader.cc
index 29fa6ff..110a3a7 100644
--- a/third_party/blink/renderer/modules/nfc/ndef_reader.cc
+++ b/third_party/blink/renderer/modules/nfc/ndef_reader.cc
@@ -215,7 +215,11 @@
 // https://w3c.github.io/web-nfc/#writing-content
 // https://w3c.github.io/web-nfc/#the-write-method
 ScriptPromise NDEFReader::write(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                const V8NDEFMessageSource* write_message,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                 const NDEFMessageSource& write_message,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                 const NDEFWriteOptions* options,
                                 ExceptionState& exception_state) {
   // https://w3c.github.io/web-nfc/#security-policies
diff --git a/third_party/blink/renderer/modules/nfc/ndef_reader.h b/third_party/blink/renderer/modules/nfc/ndef_reader.h
index c3390d5..2963cabd 100644
--- a/third_party/blink/renderer/modules/nfc/ndef_reader.h
+++ b/third_party/blink/renderer/modules/nfc/ndef_reader.h
@@ -9,6 +9,7 @@
 #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/dom/events/event_target.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
@@ -53,10 +54,17 @@
                      ExceptionState& exception_state);
 
   // Write NDEFMessageSource asynchronously to NFC tag.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise write(ScriptState* script_state,
+                      const V8NDEFMessageSource* write_message,
+                      const NDEFWriteOptions* options,
+                      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise write(ScriptState* script_state,
                       const NDEFMessageSource& write_message,
                       const NDEFWriteOptions* options,
                       ExceptionState& exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index ca78f160..e9bf05c 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -48,6 +48,7 @@
 #include "third_party/blink/public/web/web_local_frame.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_object_string.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h"
 #include "third_party/blink/renderer/bindings/modules/v8/media_stream_track_or_string.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track.h"
@@ -63,6 +64,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_callback.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_stats_callback.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_mediastreamtrack_string.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/dom/dom_time_stamp.h"
@@ -1789,12 +1791,22 @@
 
 ScriptPromise RTCPeerConnection::generateCertificate(
     ScriptState* script_state,
-    const AlgorithmIdentifier& keygen_algorithm,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8AlgorithmIdentifier* keygen_algorithm_arg,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const AlgorithmIdentifier& keygen_algorithm_arg,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const V8AlgorithmIdentifier* keygen_algorithm = keygen_algorithm_arg;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const AlgorithmIdentifier* keygen_algorithm = &keygen_algorithm_arg;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
   // Normalize |keygenAlgorithm| with WebCrypto, making sure it is a recognized
   // AlgorithmIdentifier.
   WebCryptoAlgorithm crypto_algorithm;
-  if (!NormalizeAlgorithm(script_state->GetIsolate(), keygen_algorithm,
+  if (!NormalizeAlgorithm(script_state->GetIsolate(), keygen_algorithm_arg,
                           kWebCryptoOperationGenerateKey, crypto_algorithm,
                           exception_state)) {
     return ScriptPromise();
@@ -1803,9 +1815,9 @@
   // Check if |keygenAlgorithm| contains the optional DOMTimeStamp |expires|
   // attribute.
   base::Optional<DOMTimeStamp> expires;
-  if (keygen_algorithm.IsObject()) {
+  if (keygen_algorithm->IsObject()) {
     Dictionary keygen_algorithm_dict(script_state->GetIsolate(),
-                                     keygen_algorithm.GetAsObject().V8Value(),
+                                     keygen_algorithm->GetAsObject().V8Value(),
                                      exception_state);
     if (exception_state.HadException())
       return ScriptPromise();
@@ -2372,7 +2384,11 @@
 }
 
 RTCRtpTransceiver* RTCPeerConnection::addTransceiver(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionMediaStreamTrackOrString* track_or_kind,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const MediaStreamTrackOrString& track_or_kind,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const RTCRtpTransceiverInit* init,
     ExceptionState& exception_state) {
   if (sdp_semantics_ != webrtc::SdpSemantics::kUnifiedPlan) {
@@ -2399,6 +2415,36 @@
   }
   webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>> result =
       webrtc::RTCError(webrtc::RTCErrorType::UNSUPPORTED_OPERATION);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (track_or_kind->GetContentType()) {
+    case V8UnionMediaStreamTrackOrString::ContentType::kMediaStreamTrack: {
+      MediaStreamTrack* track = track_or_kind->GetAsMediaStreamTrack();
+      RegisterTrack(track);
+      result = peer_handler_->AddTransceiverWithTrack(track->Component(),
+                                                      std::move(webrtc_init));
+      break;
+    }
+    case V8UnionMediaStreamTrackOrString::ContentType::kString: {
+      const String& kind_string = track_or_kind->GetAsString();
+      // TODO(hbos): Make cricket::MediaType an allowed identifier in
+      // rtc_peer_connection.cc and use that instead of a boolean.
+      String kind;
+      if (kind_string == "audio") {
+        kind = webrtc::MediaStreamTrackInterface::kAudioKind;
+      } else if (kind_string == "video") {
+        kind = webrtc::MediaStreamTrackInterface::kVideoKind;
+      } else {
+        exception_state.ThrowTypeError(
+            "The argument provided as parameter 1 is not a valid "
+            "MediaStreamTrack kind ('audio' or 'video').");
+        return nullptr;
+      }
+      result = peer_handler_->AddTransceiverWithKind(std::move(kind),
+                                                     std::move(webrtc_init));
+      break;
+    }
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (track_or_kind.IsMediaStreamTrack()) {
     MediaStreamTrack* track = track_or_kind.GetAsMediaStreamTrack();
     RegisterTrack(track);
@@ -2422,6 +2468,7 @@
     result = peer_handler_->AddTransceiverWithKind(std::move(kind),
                                                    std::move(webrtc_init));
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (!result.ok()) {
     ThrowExceptionFromRTCError(result.error(), exception_state);
     return nullptr;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
index 241dc8e..d74ebfb 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
@@ -37,6 +37,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
 #include "third_party/blink/renderer/modules/crypto/normalize_algorithm.h"
 #include "third_party/blink/renderer/modules/event_target_modules.h"
@@ -64,10 +65,10 @@
 class MediaStreamTrackOrString;
 class RTCAnswerOptions;
 class RTCConfiguration;
-class RTCDtlsTransport;
 class RTCDTMFSender;
 class RTCDataChannel;
 class RTCDataChannelInit;
+class RTCDtlsTransport;
 class RTCIceCandidateInit;
 class RTCIceTransport;
 class RTCOfferOptions;
@@ -82,6 +83,7 @@
 class V8RTCPeerConnectionErrorCallback;
 class V8RTCSessionDescriptionCallback;
 class V8RTCStatsCallback;
+class V8UnionMediaStreamTrackOrString;
 class V8VoidFunction;
 
 extern const char kOnlySupportedInUnifiedPlanMessage[];
@@ -205,10 +207,17 @@
 
   // Certificate management
   // http://w3c.github.io/webrtc-pc/#sec.cert-mgmt
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static ScriptPromise generateCertificate(
+      ScriptState* script_state,
+      const V8AlgorithmIdentifier* keygen_algorithm,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static ScriptPromise generateCertificate(
       ScriptState*,
       const AlgorithmIdentifier& keygen_algorithm,
       ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   ScriptPromise addIceCandidate(ScriptState*,
                                 const RTCIceCandidateInit*,
@@ -269,9 +278,16 @@
   const HeapVector<Member<RTCRtpTransceiver>>& getTransceivers() const;
   const HeapVector<Member<RTCRtpSender>>& getSenders() const;
   const HeapVector<Member<RTCRtpReceiver>>& getReceivers() const;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  RTCRtpTransceiver* addTransceiver(
+      const V8UnionMediaStreamTrackOrString* track_or_kind,
+      const RTCRtpTransceiverInit* init,
+      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RTCRtpTransceiver* addTransceiver(const MediaStreamTrackOrString&,
                                     const RTCRtpTransceiverInit*,
                                     ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   RTCRtpSender* addTrack(MediaStreamTrack*, MediaStreamVector, ExceptionState&);
   void removeTrack(RTCRtpSender*, ExceptionState&);
   DEFINE_ATTRIBUTE_EVENT_LISTENER(track, kTrack)
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
index dea67c43..9501794c 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
@@ -6,7 +6,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_RTP_RECEIVER_H_
 
 #include "base/optional.h"
-#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_vector.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_contributing_source.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_receive_parameters.h"
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
index 3278e9a3..b30c025 100644
--- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
+++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
@@ -7,6 +7,8 @@
 #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_node_filter.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_parse_from_string_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string_trustedhtml.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_document_fragment_or_document.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_trusted_html_or_document_fragment_or_document.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_sanitizer_config.h"
@@ -105,12 +107,55 @@
 }
 
 String Sanitizer::sanitizeToString(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                   const V8SanitizerInput* input,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                    StringOrDocumentFragmentOrDocument& input,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                    ExceptionState& exception_state) {
   return CreateMarkup(SanitizeImpl(script_state, input, exception_state),
                       kChildrenOnly);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+DocumentFragment* Sanitizer::sanitize(
+    ScriptState* script_state,
+    const V8SanitizerInputWithTrustedHTML* input,
+    ExceptionState& exception_state) {
+  V8SanitizerInput* new_input = nullptr;
+  switch (input->GetContentType()) {
+    case V8SanitizerInputWithTrustedHTML::ContentType::kDocument:
+      new_input =
+          MakeGarbageCollected<V8SanitizerInput>(input->GetAsDocument());
+      break;
+    case V8SanitizerInputWithTrustedHTML::ContentType::kDocumentFragment:
+      new_input = MakeGarbageCollected<V8SanitizerInput>(
+          input->GetAsDocumentFragment());
+      break;
+    case V8SanitizerInputWithTrustedHTML::ContentType::kString: {
+      LocalDOMWindow* window = LocalDOMWindow::From(script_state);
+      if (!window) {
+        exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+                                          "Cannot find current DOM window.");
+        return nullptr;
+      }
+      new_input =
+          MakeGarbageCollected<V8SanitizerInput>(TrustedTypesCheckForHTML(
+              input->GetAsString(), window->GetExecutionContext(),
+              exception_state));
+      if (exception_state.HadException()) {
+        return nullptr;
+      }
+      break;
+    }
+    case V8SanitizerInputWithTrustedHTML::ContentType::kTrustedHTML:
+      new_input = MakeGarbageCollected<V8SanitizerInput>(
+          input->GetAsTrustedHTML()->toString());
+      break;
+  }
+  return SanitizeImpl(script_state, new_input, exception_state);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 DocumentFragment* Sanitizer::sanitize(
     ScriptState* script_state,
     StringOrTrustedHTMLOrDocumentFragmentOrDocument& input,
@@ -137,7 +182,55 @@
   }
   return SanitizeImpl(script_state, new_input, exception_state);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+DocumentFragment* Sanitizer::PrepareFragment(LocalDOMWindow* window,
+                                             ScriptState* script_state,
+                                             const V8SanitizerInput* input,
+                                             ExceptionState& exception_state) {
+  DCHECK(input);
+
+  if (!window) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+                                      "Cannot find current DOM window.");
+    return nullptr;
+  }
+
+  switch (input->GetContentType()) {
+    case V8SanitizerInput::ContentType::kDocument: {
+      UseCounter::Count(window->GetExecutionContext(),
+                        WebFeature::kSanitizerAPIFromDocument);
+      DocumentFragment* fragment =
+          input->GetAsDocument()->createDocumentFragment();
+      fragment->CloneChildNodesFrom(*(input->GetAsDocument()->body()),
+                                    CloneChildrenFlag::kClone);
+      return fragment;
+    }
+    case V8SanitizerInput::ContentType::kDocumentFragment:
+      UseCounter::Count(window->GetExecutionContext(),
+                        WebFeature::kSanitizerAPIFromFragment);
+      return input->GetAsDocumentFragment();
+    case V8SanitizerInput::ContentType::kString: {
+      UseCounter::Count(window->GetExecutionContext(),
+                        WebFeature::kSanitizerAPIFromString);
+      Document* document =
+          window->document()
+              ? window->document()->implementation().createHTMLDocument()
+              : DOMParser::Create(script_state)
+                    ->parseFromString(
+                        "<!DOCTYPE html><html><body></body></html>",
+                        "text/html", ParseFromStringOptions::Create());
+      // TODO(https://crbug.com/1178774): Behavior difference need further
+      // investgate.
+      return document->createRange()->createContextualFragment(
+          input->GetAsString(), exception_state);
+    }
+  }
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 DocumentFragment* Sanitizer::PrepareFragment(
     LocalDOMWindow* window,
     ScriptState* script_state,
@@ -183,6 +276,7 @@
   }
   return fragment;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 DocumentFragment* Sanitizer::DoSanitizing(DocumentFragment* fragment,
                                           LocalDOMWindow* window,
@@ -253,10 +347,14 @@
   return fragment;
 }
 
-DocumentFragment* Sanitizer::SanitizeImpl(
-    ScriptState* script_state,
-    StringOrDocumentFragmentOrDocument& input,
-    ExceptionState& exception_state) {
+DocumentFragment* Sanitizer::SanitizeImpl(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                          const V8SanitizerInput* input,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                          StringOrDocumentFragmentOrDocument&
+                                              input,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                          ExceptionState& exception_state) {
   LocalDOMWindow* window = LocalDOMWindow::From(script_state);
   DocumentFragment* fragment =
       PrepareFragment(window, script_state, input, exception_state);
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h
index c5414e12..73c3ec2 100644
--- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h
+++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SANITIZER_API_SANITIZER_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_SANITIZER_API_SANITIZER_H_
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/dom/node.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/modules/sanitizer_api/sanitizer_config_impl.h"
@@ -38,12 +39,21 @@
   explicit Sanitizer(ExecutionContext*, const SanitizerConfig*);
   ~Sanitizer() override;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  String sanitizeToString(ScriptState* script_state,
+                          const V8SanitizerInput* input,
+                          ExceptionState& exception_state);
+  DocumentFragment* sanitize(ScriptState* script_state,
+                             const V8SanitizerInputWithTrustedHTML* input,
+                             ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   String sanitizeToString(ScriptState*,
                           StringOrDocumentFragmentOrDocument&,
                           ExceptionState&);
   DocumentFragment* sanitize(ScriptState*,
                              StringOrTrustedHTMLOrDocumentFragmentOrDocument&,
                              ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   SanitizerConfig* config() const;
   static SanitizerConfig* defaultConfig();
@@ -59,16 +69,29 @@
   void AttrFormatter(HashMap<String, Vector<String>>&,
                      const Vector<std::pair<String, Vector<String>>>&);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DocumentFragment* PrepareFragment(LocalDOMWindow* window,
+                                    ScriptState* script_state,
+                                    const V8SanitizerInput* input,
+                                    ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DocumentFragment* PrepareFragment(LocalDOMWindow*,
                                     ScriptState*,
                                     StringOrDocumentFragmentOrDocument&,
                                     ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DocumentFragment* DoSanitizing(DocumentFragment*,
                                  LocalDOMWindow*,
                                  ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DocumentFragment* SanitizeImpl(ScriptState* script_state,
+                                 const V8SanitizerInput* input,
+                                 ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DocumentFragment* SanitizeImpl(ScriptState*,
                                  StringOrDocumentFragmentOrDocument&,
                                  ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   SanitizerConfigImpl config_;
   Member<const SanitizerConfig> config_dictionary_;
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc
index ff141f5..9ea259d 100644
--- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc
+++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc
@@ -19,6 +19,8 @@
 
 #include "testing/libfuzzer/proto/lpm_interface.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string_trustedhtml.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_document_fragment_or_document.h"
 #include "third_party/blink/renderer/bindings/modules/v8/string_or_trusted_html_or_document_fragment_or_document.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_sanitizer_config.h"
@@ -93,12 +95,22 @@
   // Sanitize string given in proto. Method depends on sanitize_to_string.
   String str = proto.html_string().c_str();
   if (proto.sanitize_to_string()) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* str1 = MakeGarbageCollected<
+        V8UnionDocumentOrDocumentFragmentOrStringOrTrustedHTML>(str);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     StringOrTrustedHTMLOrDocumentFragmentOrDocument str1 =
         StringOrTrustedHTMLOrDocumentFragmentOrDocument::FromString(str);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     sanitizer->sanitize(script_state, str1, IGNORE_EXCEPTION_FOR_TESTING);
   } else {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* str2 =
+        MakeGarbageCollected<V8UnionDocumentOrDocumentFragmentOrString>(str);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     StringOrDocumentFragmentOrDocument str2 =
         StringOrDocumentFragmentOrDocument::FromString(str);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     sanitizer->sanitizeToString(script_state, str2,
                                 IGNORE_EXCEPTION_FOR_TESTING);
   }
diff --git a/third_party/blink/renderer/modules/sensor/orientation_sensor.cc b/third_party/blink/renderer/modules/sensor/orientation_sensor.cc
index 35f75fd3..bb21e9dc 100644
--- a/third_party/blink/renderer/modules/sensor/orientation_sensor.cc
+++ b/third_party/blink/renderer/modules/sensor/orientation_sensor.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/sensor/orientation_sensor.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_dommatrix_float32array_float64array.h"
 #include "third_party/blink/renderer/core/geometry/dom_matrix.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 
@@ -98,6 +99,25 @@
   DoPopulateMatrix(target_matrix, quat.x, quat.y, quat.z, quat.w);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void OrientationSensor::populateMatrix(
+    const V8RotationMatrixType* target_buffer,
+    ExceptionState& exception_state) {
+  switch (target_buffer->GetContentType()) {
+    case V8RotationMatrixType::ContentType::kDOMMatrix:
+      PopulateMatrixInternal(target_buffer->GetAsDOMMatrix(), exception_state);
+      break;
+    case V8RotationMatrixType::ContentType::kFloat32Array:
+      PopulateMatrixInternal(target_buffer->GetAsFloat32Array().Get(),
+                             exception_state);
+      break;
+    case V8RotationMatrixType::ContentType::kFloat64Array:
+      PopulateMatrixInternal(target_buffer->GetAsFloat64Array().Get(),
+                             exception_state);
+      break;
+  }
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void OrientationSensor::populateMatrix(
     Float32ArrayOrFloat64ArrayOrDOMMatrix& matrix,
     ExceptionState& exception_state) {
@@ -110,6 +130,7 @@
   else
     NOTREACHED() << "Unexpected rotation matrix type.";
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 bool OrientationSensor::isReadingDirty() const {
   return reading_dirty_ || !hasReading();
diff --git a/third_party/blink/renderer/modules/sensor/orientation_sensor.h b/third_party/blink/renderer/modules/sensor/orientation_sensor.h
index 81eefc30..32404cd 100644
--- a/third_party/blink/renderer/modules/sensor/orientation_sensor.h
+++ b/third_party/blink/renderer/modules/sensor/orientation_sensor.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/renderer/bindings/modules/v8/float32_array_or_float64_array_or_dom_matrix.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_spatial_sensor_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
 #include "third_party/blink/renderer/modules/sensor/sensor.h"
 
@@ -17,7 +18,12 @@
 
  public:
   base::Optional<Vector<double>> quaternion();
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void populateMatrix(const V8RotationMatrixType* target_buffer,
+                      ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void populateMatrix(Float32ArrayOrFloat64ArrayOrDOMMatrix&, ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   bool isReadingDirty() const;
 
diff --git a/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc b/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc
index 7780d3da..01938cb7 100644
--- a/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc
+++ b/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/service_worker/extendable_message_event.h"
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_client_messageport_serviceworker.h"
 #include "third_party/blink/renderer/core/messaging/message_port.h"
 #include "third_party/blink/renderer/modules/service_worker/service_worker.h"
 #include "third_party/blink/renderer/modules/service_worker/service_worker_client.h"
@@ -77,6 +78,22 @@
   return ScriptValue(script_state->GetIsolate(), value);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionClientOrMessagePortOrServiceWorker* ExtendableMessageEvent::source()
+    const {
+  if (source_as_client_) {
+    return MakeGarbageCollected<V8UnionClientOrMessagePortOrServiceWorker>(
+        source_as_client_);
+  } else if (source_as_service_worker_) {
+    return MakeGarbageCollected<V8UnionClientOrMessagePortOrServiceWorker>(
+        source_as_service_worker_);
+  } else if (source_as_message_port_) {
+    return MakeGarbageCollected<V8UnionClientOrMessagePortOrServiceWorker>(
+        source_as_message_port_);
+  }
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void ExtendableMessageEvent::source(
     ClientOrServiceWorkerOrMessagePort& result) const {
   if (source_as_client_)
@@ -90,6 +107,7 @@
   else
     result = ClientOrServiceWorkerOrMessagePort();
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 MessagePortArray ExtendableMessageEvent::ports() const {
   // TODO(bashi): Currently we return a copied array because the binding
diff --git a/third_party/blink/renderer/modules/service_worker/extendable_message_event.h b/third_party/blink/renderer/modules/service_worker/extendable_message_event.h
index 8526303..dfa9a234 100644
--- a/third_party/blink/renderer/modules/service_worker/extendable_message_event.h
+++ b/third_party/blink/renderer/modules/service_worker/extendable_message_event.h
@@ -16,8 +16,9 @@
 namespace blink {
 
 class MessagePort;
-class ServiceWorkerClient;
 class ServiceWorker;
+class ServiceWorkerClient;
+class V8UnionClientOrMessagePortOrServiceWorker;
 
 class MODULES_EXPORT ExtendableMessageEvent final : public ExtendableEvent {
   DEFINE_WRAPPERTYPEINFO();
@@ -72,7 +73,11 @@
   bool isDataDirty() const { return false; }
   const String& origin() const { return origin_; }
   const String& lastEventId() const { return last_event_id_; }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionClientOrMessagePortOrServiceWorker* source() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void source(ClientOrServiceWorkerOrMessagePort& result) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   MessagePortArray ports() const;
 
   const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index 823383a6..75dfc56 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -857,13 +857,6 @@
       this, script_url, std::move(meta_data));
 }
 
-ScriptPromise ServiceWorkerGlobalScope::fetch(ScriptState* script_state,
-                                              const RequestInfo& input,
-                                              const RequestInit* init,
-                                              ExceptionState& exception_state) {
-  return GlobalFetch::fetch(script_state, *this, input, init, exception_state);
-}
-
 void ServiceWorkerGlobalScope::ExceptionThrown(ErrorEvent* event) {
   WorkerGlobalScope::ExceptionThrown(event);
   if (WorkerThreadDebugger* debugger =
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
index 8ba7a10..928443f 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -155,11 +155,6 @@
   ServiceWorkerRegistration* registration();
   ::blink::ServiceWorker* serviceWorker();
 
-  ScriptPromise fetch(ScriptState*,
-                      const RequestInfo&,
-                      const RequestInit*,
-                      ExceptionState&);
-
   ScriptPromise skipWaiting(ScriptState*);
 
   void BindServiceWorker(mojo::PendingReceiver<mojom::blink::ServiceWorker>);
diff --git a/third_party/blink/renderer/modules/shapedetection/shape_detector.cc b/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
index 7bfbf5e..d4c2d291 100644
--- a/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
+++ b/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
@@ -8,6 +8,7 @@
 
 #include "base/numerics/checked_math.h"
 #include "skia/ext/skia_utils_base.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_blob_htmlcanvaselement_htmlimageelement_htmlvideoelement_imagebitmap_imagedata_offscreencanvas_svgimageelement_videoframe.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -25,9 +26,18 @@
 
 namespace blink {
 
-ScriptPromise ShapeDetector::detect(
-    ScriptState* script_state,
-    const ImageBitmapSourceUnion& image_source) {
+ScriptPromise ShapeDetector::detect(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                    const V8ImageBitmapSource* image_source_ptr
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                    const ImageBitmapSourceUnion& image_source
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DCHECK(image_source_ptr);
+  const V8ImageBitmapSource& image_source = *image_source_ptr;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
diff --git a/third_party/blink/renderer/modules/shapedetection/shape_detector.h b/third_party/blink/renderer/modules/shapedetection/shape_detector.h
index 181b95b..cc70fd1 100644
--- a/third_party/blink/renderer/modules/shapedetection/shape_detector.h
+++ b/third_party/blink/renderer/modules/shapedetection/shape_detector.h
@@ -8,6 +8,7 @@
 #include "skia/public/mojom/bitmap.mojom-blink-forward.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h"
 #include "third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_source_union.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
@@ -20,7 +21,12 @@
  public:
   ~ShapeDetector() override = default;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise detect(ScriptState* script_state,
+                       const V8ImageBitmapSource* image_source);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise detect(ScriptState*, const ImageBitmapSourceUnion&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
  private:
   ScriptPromise DetectShapesOnImageData(ScriptPromiseResolver*, ImageData*);
diff --git a/third_party/blink/renderer/modules/url_pattern/url_pattern.cc b/third_party/blink/renderer/modules/url_pattern/url_pattern.cc
index b5c6480..dd6290367 100644
--- a/third_party/blink/renderer/modules/url_pattern/url_pattern.cc
+++ b/third_party/blink/renderer/modules/url_pattern/url_pattern.cc
@@ -7,6 +7,7 @@
 #include "base/strings/string_util.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_regexp.h"
 #include "third_party/blink/renderer/bindings/modules/v8/usv_string_or_url_pattern_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_urlpatterninit_usvstring.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component_result.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_result.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -834,28 +835,48 @@
       search_(search),
       hash_(hash) {}
 
-bool URLPattern::test(const USVStringOrURLPatternInit& input,
-                      const String& base_url,
-                      ExceptionState& exception_state) const {
+bool URLPattern::test(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8URLPatternInput* input,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const USVStringOrURLPatternInit& input,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const String& base_url,
+    ExceptionState& exception_state) const {
   return Match(input, base_url, /*result=*/nullptr, exception_state);
 }
 
-bool URLPattern::test(const USVStringOrURLPatternInit& input,
-                      ExceptionState& exception_state) const {
+bool URLPattern::test(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8URLPatternInput* input,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const USVStringOrURLPatternInit& input,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) const {
   return test(input, /*base_url=*/String(), exception_state);
 }
 
-URLPatternResult* URLPattern::exec(const USVStringOrURLPatternInit& input,
-                                   const String& base_url,
-                                   ExceptionState& exception_state) const {
+URLPatternResult* URLPattern::exec(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8URLPatternInput* input,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const USVStringOrURLPatternInit& input,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const String& base_url,
+    ExceptionState& exception_state) const {
   URLPatternResult* result = URLPatternResult::Create();
   if (!Match(input, base_url, result, exception_state))
     return nullptr;
   return result;
 }
 
-URLPatternResult* URLPattern::exec(const USVStringOrURLPatternInit& input,
-                                   ExceptionState& exception_state) const {
+URLPatternResult* URLPattern::exec(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8URLPatternInput* input,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const USVStringOrURLPatternInit& input,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) const {
   return exec(input, /*base_url=*/String(), exception_state);
 }
 
@@ -1002,10 +1023,15 @@
       std::move(wtf_name_list));
 }
 
-bool URLPattern::Match(const USVStringOrURLPatternInit& input,
-                       const String& base_url,
-                       URLPatternResult* result,
-                       ExceptionState& exception_state) const {
+bool URLPattern::Match(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8URLPatternInput* input,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const USVStringOrURLPatternInit& input,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const String& base_url,
+    URLPatternResult* result,
+    ExceptionState& exception_state) const {
   // By default each URL component value starts with an empty string.  The
   // given input is then layered on top of these defaults.
   String protocol(g_empty_string);
@@ -1017,6 +1043,62 @@
   String search(g_empty_string);
   String hash(g_empty_string);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DCHECK(input);
+  switch (input->GetContentType()) {
+    case V8URLPatternInput::ContentType::kURLPatternInit:
+      if (base_url) {
+        exception_state.ThrowTypeError(
+            "Invalid second argument baseURL '" + base_url +
+            "' provided with a URLPatternInit input. Use the "
+            "URLPatternInit.baseURL property instead.");
+        return false;
+      }
+
+      // Layer the URLPatternInit values on top of the default empty strings.
+      ApplyInit(input->GetAsURLPatternInit(), ValueType::kURL, protocol,
+                username, password, hostname, port, pathname, search, hash,
+                exception_state);
+      if (exception_state.HadException()) {
+        // Treat exceptions simply as a failure to match.
+        exception_state.ClearException();
+        return false;
+      }
+      break;
+    case V8URLPatternInput::ContentType::kUSVString:
+      KURL parsed_base_url(base_url);
+      if (base_url && !parsed_base_url.IsValid()) {
+        // Treat as failure to match, but don't throw an exception.
+        return false;
+      }
+
+      // The compile the input string as a fully resolved URL.
+      KURL url(parsed_base_url, input->GetAsUSVString());
+      if (!url.IsValid() || url.IsEmpty()) {
+        // Treat as failure to match, but don't throw an exception.
+        return false;
+      }
+
+      // Apply the parsed URL components on top of our defaults.
+      if (url.Protocol())
+        protocol = url.Protocol();
+      if (url.User())
+        username = url.User();
+      if (url.Pass())
+        password = url.Pass();
+      if (url.Host())
+        hostname = url.Host();
+      if (url.Port() > 0)
+        port = String::Number(url.Port());
+      if (url.GetPath())
+        pathname = url.GetPath();
+      if (url.Query())
+        search = url.Query();
+      if (url.FragmentIdentifier())
+        hash = url.FragmentIdentifier();
+      break;
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (input.IsURLPatternInit()) {
     if (base_url) {
       exception_state.ThrowTypeError(
@@ -1067,6 +1149,7 @@
     if (url.FragmentIdentifier())
       hash = url.FragmentIdentifier();
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   Vector<String> protocol_group_list;
   Vector<String> username_group_list;
@@ -1105,7 +1188,20 @@
     return matched;
 
   HeapVector<USVStringOrURLPatternInit> inputs;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  switch (input->GetContentType()) {
+    case V8URLPatternInput::ContentType::kURLPatternInit:
+      inputs.push_back(USVStringOrURLPatternInit::FromURLPatternInit(
+          input->GetAsURLPatternInit()));
+      break;
+    case V8URLPatternInput::ContentType::kUSVString:
+      inputs.push_back(
+          USVStringOrURLPatternInit::FromUSVString(input->GetAsUSVString()));
+      break;
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   inputs.push_back(input);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (base_url)
     inputs.push_back(USVStringOrURLPatternInit::FromUSVString(base_url));
   result->setInputs(std::move(inputs));
diff --git a/third_party/blink/renderer/modules/url_pattern/url_pattern.h b/third_party/blink/renderer/modules/url_pattern/url_pattern.h
index 31923a9..0609081 100644
--- a/third_party/blink/renderer/modules/url_pattern/url_pattern.h
+++ b/third_party/blink/renderer/modules/url_pattern/url_pattern.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_URL_PATTERN_URL_PATTERN_H_
 
 #include "base/types/pass_key.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/liburlpattern/parse.h"
 
@@ -39,17 +40,33 @@
              Component* hash,
              base::PassKey<URLPattern> key);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  bool test(const V8URLPatternInput* input,
+            const String& base_url,
+            ExceptionState& exception_state) const;
+  bool test(const V8URLPatternInput* input,
+            ExceptionState& exception_state) const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool test(const USVStringOrURLPatternInit& input,
             const String& base_url,
             ExceptionState& exception_state) const;
   bool test(const USVStringOrURLPatternInit& input,
             ExceptionState& exception_state) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  URLPatternResult* exec(const V8URLPatternInput* input,
+                         const String& base_url,
+                         ExceptionState& exception_state) const;
+  URLPatternResult* exec(const V8URLPatternInput* input,
+                         ExceptionState& exception_state) const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   URLPatternResult* exec(const USVStringOrURLPatternInit& input,
                          const String& base_url,
                          ExceptionState& exception_state) const;
   URLPatternResult* exec(const USVStringOrURLPatternInit& input,
                          ExceptionState& exception_state) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   String protocol() const;
   String username() const;
@@ -81,10 +98,17 @@
   // A utility function to determine if a given |input| matches the pattern
   // or not.  Returns |true| if there is a match and |false| otherwise.  If
   // |result| is not nullptr then the URLPatternResult contents will be filled.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  bool Match(const V8URLPatternInput* input,
+             const String& base_url,
+             URLPatternResult* result,
+             ExceptionState& exception_state) const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   bool Match(const USVStringOrURLPatternInit& input,
              const String& base_url,
              URLPatternResult* result,
              ExceptionState& exception_state) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // A utility function that constructs a URLPatternComponentResult for
   // a given |component|, |input|, and |group_list|.  The |component| may
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
index a17aa1c..4442f5c 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
@@ -14,6 +14,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder_config.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_cssimagevalue_htmlcanvaselement_htmlimageelement_htmlvideoelement_imagebitmap_offscreencanvas_svgimageelement_videoframe.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_config.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_config.h"
@@ -188,8 +189,12 @@
   video_frame_init->setTimestamp(proto.timestamp());
   video_frame_init->setDuration(proto.duration());
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* source = MakeGarbageCollected<V8CanvasImageSource>(image_bitmap);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CanvasImageSourceUnion source;
   source.SetImageBitmap(image_bitmap);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   return VideoFrame::Create(script_state, source, video_frame_init,
                             IGNORE_EXCEPTION_FOR_TESTING);
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_core.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_core.cc
index f03e0e09..9ede7c13 100644
--- a/third_party/blink/renderer/modules/webcodecs/image_decoder_core.cc
+++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_core.cc
@@ -158,8 +158,8 @@
 
   // Due to implementation limitations YUV support for some formats is only
   // known once all data is received. Animated images are never supported.
-  if (decoder_->CanDecodeToYUV() && !have_completed_rgb_decode_) {
-    DCHECK_EQ(frame_index, 0u);
+  if (decoder_->CanDecodeToYUV() && !have_completed_rgb_decode_ &&
+      frame_index == 0u) {
     if (!have_completed_yuv_decode_) {
       MaybeDecodeToYuv();
       if (decoder_->Failed()) {
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc
index 953b15e..86d1f97 100644
--- a/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc
+++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_external_test.cc
@@ -571,6 +571,69 @@
   EXPECT_EQ(frame->displayHeight(), 159u);
 }
 
+TEST_F(ImageDecoderTest, ReadableStreamAvifStillYuvDecoding) {
+  V8TestingScope v8_scope;
+  constexpr char kImageType[] = "image/avif";
+  EXPECT_TRUE(IsTypeSupported(&v8_scope, kImageType));
+
+  auto data = ReadFile("images/resources/avif/red-limited-range-420-8bpc.avif");
+
+  Persistent<TestUnderlyingSource> underlying_source =
+      MakeGarbageCollected<TestUnderlyingSource>(v8_scope.GetScriptState());
+  Persistent<ReadableStream> stream =
+      ReadableStream::CreateWithCountQueueingStrategy(v8_scope.GetScriptState(),
+                                                      underlying_source, 0);
+
+  auto* init = MakeGarbageCollected<ImageDecoderInit>();
+  init->setType(kImageType);
+  init->setData(
+      ArrayBufferOrArrayBufferViewOrReadableStream::FromReadableStream(stream));
+
+  Persistent<ImageDecoderExternal> decoder = ImageDecoderExternal::Create(
+      v8_scope.GetScriptState(), init, IGNORE_EXCEPTION_FOR_TESTING);
+  ASSERT_TRUE(decoder);
+  ASSERT_FALSE(v8_scope.GetExceptionState().HadException());
+  EXPECT_EQ(decoder->type(), kImageType);
+
+  // Append all data, but don't mark the stream as complete yet.
+  const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(data->Data());
+  underlying_source->Enqueue(ScriptValue(
+      v8_scope.GetIsolate(), ToV8(DOMUint8Array::Create(data_ptr, data->size()),
+                                  v8_scope.GetScriptState())));
+
+  base::RunLoop().RunUntilIdle();
+
+  // Attempt to decode a frame greater than the first.
+  auto bad_promise = decoder->decode(MakeOptions(1, true));
+  base::RunLoop().RunUntilIdle();
+
+  // Mark the stream as complete.
+  underlying_source->Close();
+
+  // Now that all data is in we see only 1 frame and request should be rejected.
+  {
+    ScriptPromiseTester tester(v8_scope.GetScriptState(), bad_promise);
+    tester.WaitUntilSettled();
+    EXPECT_TRUE(tester.IsRejected());
+  }
+
+  {
+    auto promise = decoder->decode();
+    ScriptPromiseTester tester(v8_scope.GetScriptState(), promise);
+    tester.WaitUntilSettled();
+    ASSERT_TRUE(tester.IsFulfilled());
+    auto* result = ToImageDecodeResult(&v8_scope, tester.Value());
+    EXPECT_TRUE(result->complete());
+
+    auto* frame = result->image();
+    EXPECT_EQ(frame->format(), "I420");
+    EXPECT_EQ(frame->timestamp(), base::nullopt);
+    EXPECT_EQ(frame->duration(), base::nullopt);
+    EXPECT_EQ(frame->displayWidth(), 3u);
+    EXPECT_EQ(frame->displayHeight(), 3u);
+  }
+}
+
 TEST_F(ImageDecoderTest, DecodePartialImage) {
   V8TestingScope v8_scope;
   constexpr char kImageType[] = "image/png";
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder_test.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder_test.cc
index 7205708..89919fe 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder_test.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder_test.cc
@@ -3,11 +3,13 @@
 // found in the LICENSE file.
 
 #include "third_party/blink/renderer/modules/webcodecs/video_encoder.h"
+
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_function.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_cssimagevalue_htmlcanvaselement_htmlimageelement_htmlvideoelement_imagebitmap_offscreencanvas_svgimageelement_videoframe.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_config.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_encode_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_init.h"
@@ -89,8 +91,12 @@
   VideoFrameInit* video_frame_init = VideoFrameInit::Create();
   video_frame_init->setTimestamp(timestamp);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* source = MakeGarbageCollected<V8CanvasImageSource>(image_bitmap);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CanvasImageSourceUnion source;
   source.SetImageBitmap(image_bitmap);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   return VideoFrame::Create(script_state, source, video_frame_init,
                             IGNORE_EXCEPTION_FOR_TESTING);
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.cc b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
index c41f72d..6967d29 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
@@ -19,6 +19,7 @@
 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
 #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_plane_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_cssimagevalue_htmlcanvaselement_htmlimageelement_htmlvideoelement_imagebitmap_offscreencanvas_svgimageelement_videoframe.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_plane_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_pixel_format.h"
@@ -234,7 +235,11 @@
 
 // static
 VideoFrame* VideoFrame::Create(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                               const V8CanvasImageSource* source,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                const CanvasImageSourceUnion& source,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                const VideoFrameInit* init,
                                ExceptionState& exception_state) {
   auto* image_source = ToCanvasImageSource(source, exception_state);
@@ -253,8 +258,31 @@
   constexpr char kAlphaKeep[] = "keep";
 
   // Special case <video> and VideoFrame to directly use the underlying frame.
-  if (source.IsVideoFrame() || source.IsHTMLVideoElement()) {
+  if (
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      source->IsVideoFrame() || source->IsHTMLVideoElement()
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+      source.IsVideoFrame() || source.IsHTMLVideoElement()
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ) {
     scoped_refptr<media::VideoFrame> source_frame;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    switch (source->GetContentType()) {
+      case V8CanvasImageSource::ContentType::kVideoFrame:
+        if (!init || (!init->hasTimestamp() && !init->hasDuration() &&
+                      init->alpha() == kAlphaKeep)) {
+          return source->GetAsVideoFrame()->clone(exception_state);
+        }
+        source_frame = source->GetAsVideoFrame()->frame();
+        break;
+      case V8CanvasImageSource::ContentType::kHTMLVideoElement:
+        if (auto* wmp = source->GetAsHTMLVideoElement()->GetWebMediaPlayer())
+          source_frame = wmp->GetCurrentFrame();
+        break;
+      default:
+        NOTREACHED();
+    }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     if (source.IsVideoFrame()) {
       if (!init || (!init->hasTimestamp() && !init->hasDuration() &&
                     init->alpha() == kAlphaKeep)) {
@@ -265,6 +293,7 @@
       if (auto* wmp = source.GetAsHTMLVideoElement()->GetWebMediaPlayer())
         source_frame = wmp->GetCurrentFrame();
     }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
     if (!source_frame) {
       exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
@@ -838,11 +867,15 @@
   return layout.min_buffer_size;
 }
 
-ScriptPromise VideoFrame::readInto(
-    ScriptState* script_state,
-    const ArrayBufferOrArrayBufferView& destination,
-    VideoFrameReadIntoOptions* options,
-    ExceptionState& exception_state) {
+ScriptPromise VideoFrame::readInto(ScriptState* script_state,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                   const V8BufferSource* destination,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                   const ArrayBufferOrArrayBufferView&
+                                       destination,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                   VideoFrameReadIntoOptions* options,
+                                   ExceptionState& exception_state) {
   auto local_frame = handle_->frame();
   if (!local_frame) {
     exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.h b/third_party/blink/renderer/modules/webcodecs/video_frame.h
index 701fd96a..07b46425 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame.h
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame.h
@@ -8,6 +8,8 @@
 #include <stdint.h>
 
 #include "base/optional.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_image_source.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h"
 #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h"
@@ -55,10 +57,17 @@
   explicit VideoFrame(scoped_refptr<VideoFrameHandle> handle);
 
   // video_frame.idl implementation.
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static VideoFrame* Create(ScriptState* script_state,
+                            const V8CanvasImageSource* source,
+                            const VideoFrameInit* init,
+                            ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static VideoFrame* Create(ScriptState*,
                             const CanvasImageSourceUnion&,
                             const VideoFrameInit*,
                             ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static VideoFrame* Create(ScriptState*,
                             const String& format,
                             const HeapVector<Member<PlaneInit>>&,
@@ -87,10 +96,17 @@
 
   uint32_t allocationSize(VideoFrameReadIntoOptions* options, ExceptionState&);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise readInto(ScriptState* script_state,
+                         const V8BufferSource* destination,
+                         VideoFrameReadIntoOptions* options,
+                         ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise readInto(ScriptState*,
                          const ArrayBufferOrArrayBufferView& destination,
                          VideoFrameReadIntoOptions* options,
                          ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Invalidates |handle_|, releasing underlying media::VideoFrame references.
   // This effectively "destroys" all frames sharing the same Handle.
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc b/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
index a314144..fddf3af 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
@@ -2,16 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "media/base/video_frame.h"
+#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
+
 #include "components/viz/test/test_context_provider.h"
+#include "media/base/video_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_blob_htmlcanvaselement_htmlimageelement_htmlvideoelement_imagebitmap_imagedata_offscreencanvas_svgimageelement_videoframe.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_cssimagevalue_htmlcanvaselement_htmlimageelement_htmlvideoelement_imagebitmap_offscreencanvas_svgimageelement_videoframe.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_init.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
 #include "third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.h"
-#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
 #include "third_party/blink/renderer/modules/webcodecs/video_frame_handle.h"
 #include "third_party/blink/renderer/modules/webcodecs/webcodecs_logger.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
@@ -233,16 +236,24 @@
   auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(
       UnacceleratedStaticBitmapImage::Create(original_image), base::nullopt,
       default_options);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* source = MakeGarbageCollected<V8CanvasImageSource>(image_bitmap);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CanvasImageSourceUnion source;
   source.SetImageBitmap(image_bitmap);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   auto* video_frame = VideoFrame::Create(scope.GetScriptState(), source, init,
                                          scope.GetExceptionState());
 
   EXPECT_EQ(video_frame->handle()->sk_image(), original_image);
 
   {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    auto* ibs_source = MakeGarbageCollected<V8ImageBitmapSource>(video_frame);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     ImageBitmapSourceUnion ibs_source;
     ibs_source.SetVideoFrame(video_frame);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     auto promise = ImageBitmapFactories::CreateImageBitmap(
         scope.GetScriptState(), ibs_source, default_options,
         scope.GetExceptionState());
@@ -282,8 +293,12 @@
   auto* init = VideoFrameInit::Create();
   init->setTimestamp(0);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  auto* source = MakeGarbageCollected<V8CanvasImageSource>(image_bitmap);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   CanvasImageSourceUnion source;
   source.SetImageBitmap(image_bitmap);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   auto* video_frame = VideoFrame::Create(scope.GetScriptState(), source, init,
                                          scope.GetExceptionState());
   ASSERT_TRUE(video_frame);
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
index 97a3b51..154a4950 100644
--- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
@@ -5,11 +5,14 @@
 #include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h"
 
 #include <memory>
+
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
 #include "third_party/blink/renderer/bindings/modules/v8/offscreen_rendering_context.h"
 #include "third_party/blink/renderer/bindings/modules/v8/rendering_context.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_canvasrenderingcontext2d_gpucanvascontext_imagebitmaprenderingcontext_webgl2renderingcontext_webglrenderingcontext.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_gpucanvascontext_imagebitmaprenderingcontext_offscreencanvasrenderingcontext2d_webgl2renderingcontext_webglrenderingcontext.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
@@ -130,6 +133,19 @@
                                  requested_attributes,
                                  Platform::kWebGL2ContextType) {}
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8RenderingContext* WebGL2RenderingContext::AsV8RenderingContext() {
+  return MakeGarbageCollected<V8RenderingContext>(this);
+}
+
+V8OffscreenRenderingContext*
+WebGL2RenderingContext::AsV8OffscreenRenderingContext() {
+  return MakeGarbageCollected<V8OffscreenRenderingContext>(this);
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void WebGL2RenderingContext::SetCanvasGetContextResult(
     RenderingContext& result) {
   result.SetWebGL2RenderingContext(this);
@@ -140,6 +156,8 @@
   result.SetWebGL2RenderingContext(this);
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 ImageBitmap* WebGL2RenderingContext::TransferToImageBitmap(
     ScriptState* script_state) {
   return TransferToImageBitmapBase(script_state);
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
index 470c5e8..6d6988d 100644
--- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
+++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/macros.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h"
 #include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h"
 
@@ -66,8 +67,13 @@
   ImageBitmap* TransferToImageBitmap(ScriptState*) final;
   String ContextName() const override { return "WebGL2RenderingContext"; }
   void RegisterContextExtensions() override;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8RenderingContext* AsV8RenderingContext() final;
+  V8OffscreenRenderingContext* AsV8OffscreenRenderingContext() final;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void SetCanvasGetContextResult(RenderingContext&) final;
   void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h b/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h
index 162721f9..0c3996b 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h
@@ -23,6 +23,17 @@
   explicit WebGLMultiDraw(WebGLRenderingContextBase*);
   WebGLExtensionName GetName() const override;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void multiDrawArraysWEBGL(GLenum mode,
+                            const V8UnionInt32ArrayOrLongSequence* firstsList,
+                            GLuint firstsOffset,
+                            const V8UnionInt32ArrayOrLongSequence* countsList,
+                            GLuint countsOffset,
+                            GLsizei drawcount) {
+    multiDrawArraysImpl(mode, MakeSpan(firstsList), firstsOffset,
+                        MakeSpan(countsList), countsOffset, drawcount);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void multiDrawArraysWEBGL(GLenum mode,
                             Int32ArrayOrLongSequence firstsList,
                             GLuint firstsOffset,
@@ -32,7 +43,21 @@
     multiDrawArraysImpl(mode, MakeSpan(firstsList), firstsOffset,
                         MakeSpan(countsList), countsOffset, drawcount);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void multiDrawElementsWEBGL(
+      GLenum mode,
+      const V8UnionInt32ArrayOrLongSequence* countsList,
+      GLuint countsOffset,
+      GLenum type,
+      const V8UnionInt32ArrayOrLongSequence* offsetsList,
+      GLuint offsetsOffset,
+      GLsizei drawcount) {
+    multiDrawElementsImpl(mode, MakeSpan(countsList), countsOffset, type,
+                          MakeSpan(offsetsList), offsetsOffset, drawcount);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void multiDrawElementsWEBGL(GLenum mode,
                               Int32ArrayOrLongSequence countsList,
                               GLuint countsOffset,
@@ -43,7 +68,24 @@
     multiDrawElementsImpl(mode, MakeSpan(countsList), countsOffset, type,
                           MakeSpan(offsetsList), offsetsOffset, drawcount);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void multiDrawArraysInstancedWEBGL(
+      GLenum mode,
+      const V8UnionInt32ArrayOrLongSequence* firstsList,
+      GLuint firstsOffset,
+      const V8UnionInt32ArrayOrLongSequence* countsList,
+      GLuint countsOffset,
+      const V8UnionInt32ArrayOrLongSequence* instanceCountsList,
+      GLuint instanceCountsOffset,
+      GLsizei drawcount) {
+    multiDrawArraysInstancedImpl(mode, MakeSpan(firstsList), firstsOffset,
+                                 MakeSpan(countsList), countsOffset,
+                                 MakeSpan(instanceCountsList),
+                                 instanceCountsOffset, drawcount);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void multiDrawArraysInstancedWEBGL(
       GLenum mode,
       Int32ArrayOrLongSequence firstsList,
@@ -58,7 +100,25 @@
                                  MakeSpan(instanceCountsList),
                                  instanceCountsOffset, drawcount);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void multiDrawElementsInstancedWEBGL(
+      GLenum mode,
+      const V8UnionInt32ArrayOrLongSequence* countsList,
+      GLuint countsOffset,
+      GLenum type,
+      const V8UnionInt32ArrayOrLongSequence* offsetsList,
+      GLuint offsetsOffset,
+      const V8UnionInt32ArrayOrLongSequence* instanceCountsList,
+      GLuint instanceCountsOffset,
+      GLsizei drawcount) {
+    multiDrawElementsInstancedImpl(mode, MakeSpan(countsList), countsOffset,
+                                   type, MakeSpan(offsetsList), offsetsOffset,
+                                   MakeSpan(instanceCountsList),
+                                   instanceCountsOffset, drawcount);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void multiDrawElementsInstancedWEBGL(
       GLenum mode,
       Int32ArrayOrLongSequence countsList,
@@ -74,6 +134,7 @@
                                    MakeSpan(instanceCountsList),
                                    instanceCountsOffset, drawcount);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
  private:
   void multiDrawArraysImpl(GLenum mode,
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.cc b/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.cc
index e0da2d4c..fb122d3 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.cc
@@ -4,6 +4,9 @@
 
 #include "third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_int32array_longsequence.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_uint32array_unsignedlongsequence.h"
+
 namespace blink {
 
 bool WebGLMultiDrawCommon::ValidateDrawcount(
@@ -37,6 +40,23 @@
   return true;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// static
+base::span<const int32_t> WebGLMultiDrawCommon::MakeSpan(
+    const V8UnionInt32ArrayOrLongSequence* array) {
+  DCHECK(array);
+  switch (array->GetContentType()) {
+    case V8UnionInt32ArrayOrLongSequence::ContentType::kInt32Array:
+      return base::span<const int32_t>(array->GetAsInt32Array()->Data(),
+                                       array->GetAsInt32Array()->length());
+    case V8UnionInt32ArrayOrLongSequence::ContentType::kLongSequence:
+      return base::span<const int32_t>(array->GetAsLongSequence().data(),
+                                       array->GetAsLongSequence().size());
+  }
+  NOTREACHED();
+  return {};
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 // static
 base::span<const int32_t> WebGLMultiDrawCommon::MakeSpan(
     const Int32ArrayOrLongSequence& array) {
@@ -47,7 +67,27 @@
   return base::span<const int32_t>(array.GetAsLongSequence().data(),
                                    array.GetAsLongSequence().size());
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// static
+base::span<const uint32_t> WebGLMultiDrawCommon::MakeSpan(
+    const V8UnionUint32ArrayOrUnsignedLongSequence* array) {
+  DCHECK(array);
+  switch (array->GetContentType()) {
+    case V8UnionUint32ArrayOrUnsignedLongSequence::ContentType::kUint32Array:
+      return base::span<const uint32_t>(array->GetAsUint32Array()->Data(),
+                                        array->GetAsUint32Array()->length());
+    case V8UnionUint32ArrayOrUnsignedLongSequence::ContentType::
+        kUnsignedLongSequence:
+      return base::span<const uint32_t>(
+          array->GetAsUnsignedLongSequence().data(),
+          array->GetAsUnsignedLongSequence().size());
+  }
+  NOTREACHED();
+  return {};
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 // static
 base::span<const uint32_t> WebGLMultiDrawCommon::MakeSpan(
     const Uint32ArrayOrUnsignedLongSequence& array) {
@@ -58,5 +98,6 @@
   return base::span<const uint32_t>(array.GetAsUnsignedLongSequence().data(),
                                     array.GetAsUnsignedLongSequence().size());
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.h b/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.h
index fad98f3..5ba0c1e 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_multi_draw_common.h
@@ -12,7 +12,10 @@
 
 namespace blink {
 
+class V8UnionInt32ArrayOrLongSequence;
+class V8UnionUint32ArrayOrUnsignedLongSequence;
 class WebGLExtensionScopedContext;
+
 class WebGLMultiDrawCommon {
  protected:
   bool ValidateDrawcount(WebGLExtensionScopedContext* scoped,
@@ -26,11 +29,21 @@
                      GLuint offset,
                      GLsizei drawcount);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static base::span<const int32_t> MakeSpan(
+      const V8UnionInt32ArrayOrLongSequence* array);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static base::span<const int32_t> MakeSpan(
       const Int32ArrayOrLongSequence& array);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static base::span<const uint32_t> MakeSpan(
+      const V8UnionUint32ArrayOrUnsignedLongSequence* array);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static base::span<const uint32_t> MakeSpan(
       const Uint32ArrayOrUnsignedLongSequence& array);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.h b/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.h
index ba852de3..f3a8818 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.h
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
+
 class WebGLMultiDrawInstancedBaseVertexBaseInstance final
     : public WebGLExtension,
       public WebGLMultiDrawCommon {
@@ -25,6 +26,24 @@
       WebGLRenderingContextBase*);
   WebGLExtensionName GetName() const override;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void multiDrawArraysInstancedBaseInstanceWEBGL(
+      GLenum mode,
+      const V8UnionInt32ArrayOrLongSequence* firsts_list,
+      GLuint firsts_offset,
+      const V8UnionInt32ArrayOrLongSequence* counts_list,
+      GLuint counts_offset,
+      const V8UnionInt32ArrayOrLongSequence* instance_counts_list,
+      GLuint instance_counts_offset,
+      const V8UnionUint32ArrayOrUnsignedLongSequence* baseinstances_list,
+      GLuint baseinstances_offset,
+      GLsizei drawcount) {
+    multiDrawArraysInstancedBaseInstanceImpl(
+        mode, MakeSpan(firsts_list), firsts_offset, MakeSpan(counts_list),
+        counts_offset, MakeSpan(instance_counts_list), instance_counts_offset,
+        MakeSpan(baseinstances_list), baseinstances_offset, drawcount);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void multiDrawArraysInstancedBaseInstanceWEBGL(
       GLenum mode,
       Int32ArrayOrLongSequence firsts_list,
@@ -41,7 +60,31 @@
         counts_offset, MakeSpan(instance_counts_list), instance_counts_offset,
         MakeSpan(baseinstances_list), baseinstances_offset, drawcount);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(
+      GLenum mode,
+      const V8UnionInt32ArrayOrLongSequence* counts_list,
+      GLuint counts_offset,
+      GLenum type,
+      const V8UnionInt32ArrayOrLongSequence* offsets_list,
+      GLuint offsets_offset,
+      const V8UnionInt32ArrayOrLongSequence* instance_counts_list,
+      GLuint instance_counts_offset,
+      const V8UnionInt32ArrayOrLongSequence* basevertices_list,
+      GLuint basevertices_offset,
+      const V8UnionUint32ArrayOrUnsignedLongSequence* baseinstances_list,
+      GLuint baseinstances_offset,
+      GLsizei drawcount) {
+    multiDrawElementsInstancedBaseVertexBaseInstanceImpl(
+        mode, MakeSpan(counts_list), counts_offset, type,
+        MakeSpan(offsets_list), offsets_offset, MakeSpan(instance_counts_list),
+        instance_counts_offset, MakeSpan(basevertices_list),
+        basevertices_offset, MakeSpan(baseinstances_list), baseinstances_offset,
+        drawcount);
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(
       GLenum mode,
       Int32ArrayOrLongSequence counts_list,
@@ -63,6 +106,7 @@
         basevertices_offset, MakeSpan(baseinstances_list), baseinstances_offset,
         drawcount);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
  private:
   void multiDrawArraysInstancedBaseInstanceImpl(
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
index 93c7edb..bd52f32 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc
@@ -26,12 +26,15 @@
 #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h"
 
 #include <memory>
+
 #include "base/numerics/checked_math.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
 #include "third_party/blink/renderer/bindings/modules/v8/offscreen_rendering_context.h"
 #include "third_party/blink/renderer/bindings/modules/v8/rendering_context.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_canvasrenderingcontext2d_gpucanvascontext_imagebitmaprenderingcontext_webgl2renderingcontext_webglrenderingcontext.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_gpucanvascontext_imagebitmaprenderingcontext_offscreencanvasrenderingcontext2d_webgl2renderingcontext_webglrenderingcontext.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
@@ -155,6 +158,19 @@
                                 requested_attributes,
                                 Platform::kWebGL1ContextType) {}
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8RenderingContext* WebGLRenderingContext::AsV8RenderingContext() {
+  return MakeGarbageCollected<V8RenderingContext>(this);
+}
+
+V8OffscreenRenderingContext*
+WebGLRenderingContext::AsV8OffscreenRenderingContext() {
+  return MakeGarbageCollected<V8OffscreenRenderingContext>(this);
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void WebGLRenderingContext::SetCanvasGetContextResult(
     RenderingContext& result) {
   result.SetWebGLRenderingContext(this);
@@ -165,6 +181,8 @@
   result.SetWebGLRenderingContext(this);
 }
 
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 ImageBitmap* WebGLRenderingContext::TransferToImageBitmap(
     ScriptState* script_state) {
   return TransferToImageBitmapBase(script_state);
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h
index 3dda1dc1..a905317 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h
@@ -29,6 +29,7 @@
 #include <memory>
 
 #include "base/macros.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
 
@@ -94,8 +95,13 @@
   ImageBitmap* TransferToImageBitmap(ScriptState*) final;
   String ContextName() const override { return "WebGLRenderingContext"; }
   void RegisterContextExtensions() override;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8RenderingContext* AsV8RenderingContext() final;
+  V8OffscreenRenderingContext* AsV8OffscreenRenderingContext() final;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void SetCanvasGetContextResult(RenderingContext&) final;
   void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index 63c68b1..074edda 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -45,6 +45,7 @@
 #include "third_party/blink/public/mojom/gpu/gpu.mojom-blink.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/task_type.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_htmlcanvaselement_offscreencanvas.h"
 #include "third_party/blink/renderer/bindings/modules/v8/html_canvas_element_or_offscreen_canvas.h"
 #include "third_party/blink/renderer/bindings/modules/v8/webgl_any.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -5295,7 +5296,11 @@
   if (isContextLost())
     return;
   DCHECK(pixels);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DCHECK(pixels->data());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   DCHECK(!pixels->data().IsNull());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (pixels->IsBufferBaseDetached()) {
     SynthesizeGLError(GL_INVALID_VALUE, func_name,
                       "The source data has been detached.");
@@ -8903,6 +8908,17 @@
     ContextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment_);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+V8UnionHTMLCanvasElementOrOffscreenCanvas*
+WebGLRenderingContextBase::getHTMLOrOffscreenCanvas() const {
+  if (canvas()) {
+    return MakeGarbageCollected<V8UnionHTMLCanvasElementOrOffscreenCanvas>(
+        static_cast<HTMLCanvasElement*>(Host()));
+  }
+  return MakeGarbageCollected<V8UnionHTMLCanvasElementOrOffscreenCanvas>(
+      static_cast<OffscreenCanvas*>(Host()));
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas(
     HTMLCanvasElementOrOffscreenCanvas& result) const {
   if (canvas()) {
@@ -8911,6 +8927,7 @@
     result.SetOffscreenCanvas(static_cast<OffscreenCanvas*>(Host()));
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 void WebGLRenderingContextBase::addProgramCompletionQuery(WebGLProgram* program,
                                                           GLuint query) {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
index 114ec7c..5a13a6a 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -90,6 +90,7 @@
 class ImageData;
 class IntSize;
 class OESVertexArrayObject;
+class V8UnionHTMLCanvasElementOrOffscreenCanvas;
 class VideoFrame;
 class WebGLActiveInfo;
 class WebGLBuffer;
@@ -637,7 +638,11 @@
   void SetFilterQuality(SkFilterQuality) override;
   bool IsWebGL2() { return context_type_ == Platform::kWebGL2ContextType; }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8UnionHTMLCanvasElementOrOffscreenCanvas* getHTMLOrOffscreenCanvas() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void getHTMLOrOffscreenCanvas(HTMLCanvasElementOrOffscreenCanvas&) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   void commit();
 
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
index 9a1af69..6aee647 100644
--- a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
+++ b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
@@ -13,6 +13,8 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_image_data_layout.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_index_format.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_programmable_stage.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_doublesequence_gpucolordict.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_gpuextent3ddict_unsignedlongenforcerangesequence.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_shader_module.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
@@ -43,6 +45,21 @@
   return dawn_color;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+WGPUColor AsDawnType(const V8GPUColor* webgpu_color) {
+  DCHECK(webgpu_color);
+
+  switch (webgpu_color->GetContentType()) {
+    case V8GPUColor::ContentType::kDoubleSequence:
+      return AsDawnColor(webgpu_color->GetAsDoubleSequence());
+    case V8GPUColor::ContentType::kGPUColorDict:
+      return AsDawnType(webgpu_color->GetAsGPUColorDict());
+  }
+
+  NOTREACHED();
+  return WGPUColor{};
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 WGPUColor AsDawnType(const DoubleSequenceOrGPUColorDict* webgpu_color) {
   DCHECK(webgpu_color);
 
@@ -55,6 +72,58 @@
   WGPUColor dawn_color = {};
   return dawn_color;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+WGPUExtent3D AsDawnType(const V8GPUExtent3D* webgpu_extent, GPUDevice* device) {
+  DCHECK(webgpu_extent);
+
+  // Set all extents to their default value of 1.
+  // TODO (crbug.com/1206740): The last member of WGPUExtent3D (depth) is being
+  // removed from Dawn soon, but until it has been removed it must be set to 1
+  // or the correct value, in depthOrArrayLayers, will be ignored. Once depth
+  // has been removed from WGPUExtent3D in Dawn this can be to be updated to
+  // WGPUExtent3D dawn_extent = {1, 1, 1};
+  WGPUExtent3D dawn_extent;
+  uint32_t extent_defaults[4] = {1, 1, 1, 1};
+  memcpy(&dawn_extent, extent_defaults, sizeof(WGPUExtent3D));
+
+  switch (webgpu_extent->GetContentType()) {
+    case V8GPUExtent3D::ContentType::kGPUExtent3DDict: {
+      const GPUExtent3DDict* webgpu_extent_3d_dict =
+          webgpu_extent->GetAsGPUExtent3DDict();
+      dawn_extent.width = webgpu_extent_3d_dict->width();
+      dawn_extent.height = webgpu_extent_3d_dict->height();
+      dawn_extent.depthOrArrayLayers =
+          webgpu_extent_3d_dict->depthOrArrayLayers();
+      break;
+    }
+    case V8GPUExtent3D::ContentType::kUnsignedLongEnforceRangeSequence: {
+      const Vector<uint32_t>& webgpu_extent_sequence =
+          webgpu_extent->GetAsUnsignedLongEnforceRangeSequence();
+
+      // The WebGPU spec states that if the sequence isn't big enough then the
+      // default values of 1 are used (which are set above).
+      switch (webgpu_extent_sequence.size()) {
+        default:
+          dawn_extent.depth = webgpu_extent_sequence[2];
+          FALLTHROUGH;
+        case 2:
+          dawn_extent.height = webgpu_extent_sequence[1];
+          FALLTHROUGH;
+        case 1:
+          dawn_extent.width = webgpu_extent_sequence[0];
+          FALLTHROUGH;
+        case 0:
+          break;
+      }
+      break;
+    }
+  }
+
+  return dawn_extent;
+}
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 WGPUExtent3D AsDawnType(
     const UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict* webgpu_extent,
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_conversions.h b/third_party/blink/renderer/modules/webgpu/dawn_conversions.h
index 1d294e6..9814780 100644
--- a/third_party/blink/renderer/modules/webgpu/dawn_conversions.h
+++ b/third_party/blink/renderer/modules/webgpu/dawn_conversions.h
@@ -10,6 +10,7 @@
 #include <memory>
 
 #include "base/check.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.h"
 #include "third_party/blink/renderer/modules/webgpu/dawn_object.h"
 #include "third_party/blink/renderer/platform/heap/heap_allocator.h"
@@ -33,7 +34,13 @@
 // individually.
 WGPUColor AsDawnColor(const Vector<double>&);
 WGPUColor AsDawnType(const GPUColorDict*);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+WGPUColor AsDawnType(const V8GPUColor* webgpu_color);
+WGPUExtent3D AsDawnType(const V8GPUExtent3D* webgpu_extent, GPUDevice* device);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 WGPUColor AsDawnType(const DoubleSequenceOrGPUColorDict*);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+// TODO(crbug.com/1181288): Remove the old IDL union version.
 WGPUExtent3D AsDawnType(
     const UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict*,
     GPUDevice* device);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
index ad61b8e..ad3c2c4 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
@@ -7,6 +7,8 @@
 #include "third_party/blink/renderer/bindings/modules/v8/offscreen_rendering_context.h"
 #include "third_party/blink/renderer/bindings/modules/v8/rendering_context.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_swap_chain_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_canvasrenderingcontext2d_gpucanvascontext_imagebitmaprenderingcontext_webgl2renderingcontext_webglrenderingcontext.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_gpucanvascontext_imagebitmaprenderingcontext_offscreencanvasrenderingcontext2d_webgl2renderingcontext_webglrenderingcontext.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
 #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_adapter.h"
@@ -54,10 +56,29 @@
   return CanvasRenderingContext::kContextGPUPresent;
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
+V8RenderingContext* GPUCanvasContext::AsV8RenderingContext() {
+  return MakeGarbageCollected<V8RenderingContext>(this);
+}
+
+V8OffscreenRenderingContext* GPUCanvasContext::AsV8OffscreenRenderingContext() {
+  return MakeGarbageCollected<V8OffscreenRenderingContext>(this);
+}
+
+#else  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void GPUCanvasContext::SetCanvasGetContextResult(RenderingContext& result) {
   result.SetGPUCanvasContext(this);
 }
 
+void GPUCanvasContext::SetOffscreenCanvasGetContextResult(
+    OffscreenRenderingContext& result) {
+  result.SetGPUCanvasContext(this);
+}
+
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+
 void GPUCanvasContext::Stop() {
   if (swapchain_) {
     swapchain_->Neuter();
@@ -82,11 +103,6 @@
   }
 }
 
-void GPUCanvasContext::SetOffscreenCanvasGetContextResult(
-    OffscreenRenderingContext& result) {
-  result.SetGPUCanvasContext(this);
-}
-
 bool GPUCanvasContext::PushFrame() {
   DCHECK(Host());
   DCHECK(Host()->IsOffscreenCanvas());
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
index 8c5ef99..9acb5a08 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_CANVAS_CONTEXT_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_CANVAS_CONTEXT_H_
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h"
@@ -45,7 +46,13 @@
 
   // CanvasRenderingContext implementation
   ContextType GetContextType() const override;
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  V8RenderingContext* AsV8RenderingContext() final;
+  V8OffscreenRenderingContext* AsV8OffscreenRenderingContext() final;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void SetCanvasGetContextResult(RenderingContext&) final;
+  void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   scoped_refptr<StaticBitmapImage> GetImage() final { return nullptr; }
   void SetIsInHiddenPage(bool) override {}
   void SetIsBeingDisplayed(bool) override {}
@@ -61,7 +68,6 @@
   cc::Layer* CcLayer() const final;
 
   // OffscreenCanvas-specific methods
-  void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
   bool PushFrame() final;
   ImageBitmap* TransferToImageBitmap(ScriptState*) final;
 
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
index 87cd1fa9..5e0450f 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
@@ -274,11 +274,20 @@
   return encoder;
 }
 
-void GPUCommandEncoder::copyBufferToTexture(
-    GPUImageCopyBuffer* source,
-    GPUImageCopyTexture* destination,
-    UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& copy_size) {
+void GPUCommandEncoder::copyBufferToTexture(GPUImageCopyBuffer* source,
+                                            GPUImageCopyTexture* destination,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                            const V8GPUExtent3D* copy_size
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                            UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict&
+                                                copy_size
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  WGPUExtent3D dawn_copy_size = AsDawnType(copy_size, device_);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   WGPUExtent3D dawn_copy_size = AsDawnType(&copy_size, device_);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   WGPUTextureCopyView dawn_destination = AsDawnType(destination, device_);
 
   const char* error = nullptr;
@@ -293,11 +302,20 @@
       GetHandle(), &dawn_source, &dawn_destination, &dawn_copy_size);
 }
 
-void GPUCommandEncoder::copyTextureToBuffer(
-    GPUImageCopyTexture* source,
-    GPUImageCopyBuffer* destination,
-    UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& copy_size) {
+void GPUCommandEncoder::copyTextureToBuffer(GPUImageCopyTexture* source,
+                                            GPUImageCopyBuffer* destination,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                            const V8GPUExtent3D* copy_size
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                            UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict&
+                                                copy_size
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  WGPUExtent3D dawn_copy_size = AsDawnType(copy_size, device_);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   WGPUExtent3D dawn_copy_size = AsDawnType(&copy_size, device_);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   WGPUTextureCopyView dawn_source = AsDawnType(source, device_);
 
   const char* error = nullptr;
@@ -312,13 +330,22 @@
       GetHandle(), &dawn_source, &dawn_destination, &dawn_copy_size);
 }
 
-void GPUCommandEncoder::copyTextureToTexture(
-    GPUImageCopyTexture* source,
-    GPUImageCopyTexture* destination,
-    UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& copy_size) {
+void GPUCommandEncoder::copyTextureToTexture(GPUImageCopyTexture* source,
+                                             GPUImageCopyTexture* destination,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                             const V8GPUExtent3D* copy_size
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                             UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict&
+                                                 copy_size
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   WGPUTextureCopyView dawn_source = AsDawnType(source, device_);
   WGPUTextureCopyView dawn_destination = AsDawnType(destination, device_);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  WGPUExtent3D dawn_copy_size = AsDawnType(copy_size, device_);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   WGPUExtent3D dawn_copy_size = AsDawnType(&copy_size, device_);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   GetProcs().commandEncoderCopyTextureToTexture(
       GetHandle(), &dawn_source, &dawn_destination, &dawn_copy_size);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h
index 7543053..636b706 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_COMMAND_ENCODER_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_COMMAND_ENCODER_H_
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/modules/webgpu/dawn_object.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 
@@ -49,6 +50,17 @@
                                                 src_offset, dst->GetHandle(),
                                                 dst_offset, size);
   }
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void copyBufferToTexture(GPUImageCopyBuffer* source,
+                           GPUImageCopyTexture* destination,
+                           const V8GPUExtent3D* copy_size);
+  void copyTextureToBuffer(GPUImageCopyTexture* source,
+                           GPUImageCopyBuffer* destination,
+                           const V8GPUExtent3D* copy_size);
+  void copyTextureToTexture(GPUImageCopyTexture* source,
+                            GPUImageCopyTexture* destination,
+                            const V8GPUExtent3D* copy_size);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void copyBufferToTexture(
       GPUImageCopyBuffer* source,
       GPUImageCopyTexture* destination,
@@ -61,6 +73,7 @@
       GPUImageCopyTexture* source,
       GPUImageCopyTexture* destination,
       UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& copy_size);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void pushDebugGroup(String groupLabel) {
     std::string label = groupLabel.Utf8();
     GetProcs().commandEncoderPushDebugGroup(GetHandle(), label.c_str());
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
index f414b47..69e3e47 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -264,35 +264,51 @@
                               data_ptr, static_cast<size_t>(write_byte_size));
 }
 
-void GPUQueue::writeTexture(
-    GPUImageCopyTexture* destination,
-    const MaybeShared<DOMArrayBufferView>& data,
-    GPUImageDataLayout* data_layout,
-    UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& write_size,
-    ExceptionState& exception_state) {
+void GPUQueue::writeTexture(GPUImageCopyTexture* destination,
+                            const MaybeShared<DOMArrayBufferView>& data,
+                            GPUImageDataLayout* data_layout,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                            const V8GPUExtent3D* write_size,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                            UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict&
+                                write_size,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                            ExceptionState& exception_state) {
   WriteTextureImpl(destination, data->BaseAddressMaybeShared(),
                    data->byteLength(), data_layout, write_size,
                    exception_state);
 }
 
-void GPUQueue::writeTexture(
-    GPUImageCopyTexture* destination,
-    const DOMArrayBufferBase* data,
-    GPUImageDataLayout* data_layout,
-    UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& write_size,
-    ExceptionState& exception_state) {
+void GPUQueue::writeTexture(GPUImageCopyTexture* destination,
+                            const DOMArrayBufferBase* data,
+                            GPUImageDataLayout* data_layout,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                            const V8GPUExtent3D* write_size,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                            UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict&
+                                write_size,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                            ExceptionState& exception_state) {
   WriteTextureImpl(destination, data->DataMaybeShared(), data->ByteLength(),
                    data_layout, write_size, exception_state);
 }
 
-void GPUQueue::WriteTextureImpl(
-    GPUImageCopyTexture* destination,
-    const void* data,
-    size_t data_size,
-    GPUImageDataLayout* data_layout,
-    UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& write_size,
-    ExceptionState& exception_state) {
+void GPUQueue::WriteTextureImpl(GPUImageCopyTexture* destination,
+                                const void* data,
+                                size_t data_size,
+                                GPUImageDataLayout* data_layout,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                const V8GPUExtent3D* write_size,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict&
+                                    write_size,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  WGPUExtent3D dawn_write_size = AsDawnType(write_size, device_);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   WGPUExtent3D dawn_write_size = AsDawnType(&write_size, device_);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   WGPUTextureCopyView dawn_destination = AsDawnType(destination, device_);
 
   WGPUTextureDataLayout dawn_data_layout = {};
@@ -311,11 +327,15 @@
 }
 
 // TODO(shaobo.yan@intel.com): Implement this function
-void GPUQueue::copyImageBitmapToTexture(
-    GPUImageCopyImageBitmap* source,
-    GPUImageCopyTexture* destination,
-    UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& copy_size,
-    ExceptionState& exception_state) {
+void GPUQueue::copyImageBitmapToTexture(GPUImageCopyImageBitmap* source,
+                                        GPUImageCopyTexture* destination,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                        const V8GPUExtent3D* copy_size,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                        UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict&
+                                            copy_size,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                        ExceptionState& exception_state) {
   if (!source->imageBitmap()) {
     exception_state.ThrowTypeError("No valid imageBitmap");
     return;
@@ -335,7 +355,11 @@
   // appropriate format. Now only support texture format exactly the same. The
   // compatible formats need to be defined in WebGPU spec.
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  WGPUExtent3D dawn_copy_size = AsDawnType(copy_size, device_);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   WGPUExtent3D dawn_copy_size = AsDawnType(&copy_size, device_);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   // Extract imageBitmap attributes
   WGPUOrigin3D origin_in_image_bitmap =
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.h b/third_party/blink/renderer/modules/webgpu/gpu_queue.h
index f367970b..9440cdd2 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_queue.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_QUEUE_H_
 
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
 #include "third_party/blink/renderer/modules/webgpu/dawn_object.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -54,6 +55,22 @@
                    uint64_t data_byte_offset,
                    uint64_t byte_size,
                    ExceptionState& exception_state);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void writeTexture(GPUImageCopyTexture* destination,
+                    const MaybeShared<DOMArrayBufferView>& data,
+                    GPUImageDataLayout* data_layout,
+                    const V8GPUExtent3D* write_size,
+                    ExceptionState& exception_state);
+  void writeTexture(GPUImageCopyTexture* destination,
+                    const DOMArrayBufferBase* data,
+                    GPUImageDataLayout* data_layout,
+                    const V8GPUExtent3D* write_size,
+                    ExceptionState& exception_state);
+  void copyImageBitmapToTexture(GPUImageCopyImageBitmap* source,
+                                GPUImageCopyTexture* destination,
+                                const V8GPUExtent3D* copy_size,
+                                ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void writeTexture(
       GPUImageCopyTexture* destination,
       const MaybeShared<DOMArrayBufferView>& data,
@@ -71,6 +88,7 @@
       GPUImageCopyTexture* destination,
       UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& copySize,
       ExceptionState& exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
  private:
   void OnWorkDoneCallback(ScriptPromiseResolver* resolver,
@@ -93,6 +111,14 @@
                        uint64_t data_byte_offset,
                        base::Optional<uint64_t> byte_size,
                        ExceptionState& exception_state);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void WriteTextureImpl(GPUImageCopyTexture* destination,
+                        const void* data,
+                        size_t dataSize,
+                        GPUImageDataLayout* data_layout,
+                        const V8GPUExtent3D* write_size,
+                        ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void WriteTextureImpl(
       GPUImageCopyTexture* destination,
       const void* data,
@@ -100,6 +126,7 @@
       GPUImageDataLayout* data_layout,
       UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict& write_size,
       ExceptionState& exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   DISALLOW_COPY_AND_ASSIGN(GPUQueue);
 };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
index 46cdaf9..994335f 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
@@ -6,6 +6,7 @@
 
 #include "third_party/blink/renderer/bindings/modules/v8/double_sequence_or_gpu_color_dict.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_index_format.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_doublesequence_gpucolordict.h"
 #include "third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h"
 #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h"
@@ -52,6 +53,18 @@
                                            dynamic_offsets_data_length, data);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+void GPURenderPassEncoder::setBlendConstant(const V8GPUColor* color,
+                                            ExceptionState& exception_state) {
+  if (color->IsDoubleSequence() && color->GetAsDoubleSequence().size() != 4) {
+    exception_state.ThrowRangeError("color size must be 4");
+    return;
+  }
+
+  WGPUColor dawn_color = AsDawnType(color);
+  GetProcs().renderPassEncoderSetBlendConstant(GetHandle(), &dawn_color);
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void GPURenderPassEncoder::setBlendConstant(DoubleSequenceOrGPUColorDict& color,
                                             ExceptionState& exception_state) {
   if (color.IsDoubleSequence() && color.GetAsDoubleSequence().size() != 4) {
@@ -62,9 +75,15 @@
   WGPUColor dawn_color = AsDawnType(&color);
   GetProcs().renderPassEncoderSetBlendConstant(GetHandle(), &dawn_color);
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
-void GPURenderPassEncoder::setBlendColor(DoubleSequenceOrGPUColorDict& color,
-                                         ExceptionState& exception_state) {
+void GPURenderPassEncoder::setBlendColor(
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8GPUColor* color,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    DoubleSequenceOrGPUColorDict& color,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   device_->AddConsoleWarning(
       "setBlendColor is deprecated. Use setBlendConstant instead.");
 
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h
index 611ffb7..a034b74 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_RENDER_PASS_ENCODER_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_RENDER_PASS_ENCODER_H_
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.h"
 #include "third_party/blink/renderer/modules/webgpu/dawn_object.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.h"
@@ -56,10 +57,16 @@
     GetProcs().renderPassEncoderSetPipeline(GetHandle(), pipeline->GetHandle());
   }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  void setBlendConstant(const V8GPUColor* color,
+                        ExceptionState& exception_state);
+  void setBlendColor(const V8GPUColor* color, ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void setBlendConstant(DoubleSequenceOrGPUColorDict& color,
                         ExceptionState& exception_state);
   void setBlendColor(DoubleSequenceOrGPUColorDict& color,
                      ExceptionState& exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void setStencilReference(uint32_t reference) {
     GetProcs().renderPassEncoderSetStencilReference(GetHandle(), reference);
   }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc b/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc
index 6839782..c3de2031 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h"
 
 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_uncaptured_error_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_gpuoutofmemoryerror_gpuvalidationerror.h"
 
 namespace blink {
 
@@ -20,7 +21,20 @@
     const AtomicString& type,
     const GPUUncapturedErrorEventInit* gpuUncapturedErrorEventInitDict)
     : Event(type, Bubbles::kNo, Cancelable::kYes) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const auto& old_union = gpuUncapturedErrorEventInitDict->error();
+  if (old_union.IsGPUOutOfMemoryError()) {
+    error_ =
+        MakeGarbageCollected<V8GPUError>(old_union.GetAsGPUOutOfMemoryError());
+  } else if (old_union.IsGPUValidationError()) {
+    error_ =
+        MakeGarbageCollected<V8GPUError>(old_union.GetAsGPUValidationError());
+  } else {
+    NOTREACHED();
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   error_ = gpuUncapturedErrorEventInitDict->error();
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 void GPUUncapturedErrorEvent::Trace(Visitor* visitor) const {
@@ -28,9 +42,15 @@
   Event::Trace(visitor);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+const V8GPUError* GPUUncapturedErrorEvent::error() const {
+  return error_;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 void GPUUncapturedErrorEvent::error(
     GPUOutOfMemoryErrorOrGPUValidationError& error) const {
   error = error_;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h b/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h
index 1ad83e9b..9751a04 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_UNCAPTURED_ERROR_EVENT_H_
 
 #include "third_party/blink/renderer/bindings/modules/v8/gpu_out_of_memory_error_or_gpu_validation_error.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/modules/event_modules.h"
 
 namespace blink {
@@ -25,10 +26,18 @@
   void Trace(Visitor*) const override;
 
   // gpu_uncaptured_error_event.idl
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  const V8GPUError* error() const;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   void error(GPUOutOfMemoryErrorOrGPUValidationError&) const;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
  private:
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  Member<V8GPUError> error_;
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   GPUOutOfMemoryErrorOrGPUValidationError error_;
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   DISALLOW_COPY_AND_ASSIGN(GPUUncapturedErrorEvent);
 };
diff --git a/third_party/blink/renderer/modules/webshare/navigator_share_test.cc b/third_party/blink/renderer/modules/webshare/navigator_share_test.cc
index f7efe957..01fbfea 100644
--- a/third_party/blink/renderer/modules/webshare/navigator_share_test.cc
+++ b/third_party/blink/renderer/modules/webshare/navigator_share_test.cc
@@ -6,10 +6,12 @@
 
 #include <memory>
 #include <utility>
+
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_file_property_bag.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview_blob_usvstring.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_share_data.h"
 #include "third_party/blink/renderer/core/fileapi/file.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
@@ -158,9 +160,14 @@
                        const String& file_name,
                        const String& content_type,
                        const String& file_contents) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  HeapVector<Member<V8BlobPart>> blob_parts;
+  blob_parts.push_back(MakeGarbageCollected<V8BlobPart>(file_contents));
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   HeapVector<ArrayBufferOrArrayBufferViewOrBlobOrUSVString> blob_parts;
   blob_parts.push_back(ArrayBufferOrArrayBufferViewOrBlobOrUSVString());
   blob_parts.back().SetUSVString(file_contents);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   FilePropertyBag file_property_bag;
   file_property_bag.setType(content_type);
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
index bd9b6ce..aadc768 100644
--- a/third_party/blink/renderer/modules/websockets/dom_websocket.cc
+++ b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -43,6 +43,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
 #include "third_party/blink/renderer/bindings/core/v8/source_location.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_string_sequence.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_stringsequence.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/events/message_event.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -203,14 +204,26 @@
 DOMWebSocket* DOMWebSocket::Create(ExecutionContext* context,
                                    const String& url,
                                    ExceptionState& exception_state) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  return Create(
+      context, url,
+      MakeGarbageCollected<V8UnionStringOrStringSequence>(Vector<String>()),
+      exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   StringOrStringSequence protocols;
   return Create(context, url, protocols, exception_state);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
-DOMWebSocket* DOMWebSocket::Create(ExecutionContext* context,
-                                   const String& url,
-                                   const StringOrStringSequence& protocols,
-                                   ExceptionState& exception_state) {
+DOMWebSocket* DOMWebSocket::Create(
+    ExecutionContext* context,
+    const String& url,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8UnionStringOrStringSequence* protocols,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const StringOrStringSequence& protocols,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    ExceptionState& exception_state) {
   if (url.IsNull()) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kSyntaxError,
@@ -221,6 +234,21 @@
   DOMWebSocket* websocket = MakeGarbageCollected<DOMWebSocket>(context);
   websocket->UpdateStateIfNeeded();
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  DCHECK(protocols);
+  switch (protocols->GetContentType()) {
+    case V8UnionStringOrStringSequence::ContentType::kString: {
+      Vector<String> protocols_vector;
+      protocols_vector.push_back(protocols->GetAsString());
+      websocket->Connect(url, protocols_vector, exception_state);
+      break;
+    }
+    case V8UnionStringOrStringSequence::ContentType::kStringSequence:
+      websocket->Connect(url, protocols->GetAsStringSequence(),
+                         exception_state);
+      break;
+  }
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   if (protocols.IsNull()) {
     Vector<String> protocols_vector;
     websocket->Connect(url, protocols_vector, exception_state);
@@ -232,6 +260,7 @@
     DCHECK(protocols.IsStringSequence());
     websocket->Connect(url, protocols.GetAsStringSequence(), exception_state);
   }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   if (exception_state.HadException())
     return nullptr;
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket.h b/third_party/blink/renderer/modules/websockets/dom_websocket.h
index 98b7160..ddd3f110 100644
--- a/third_party/blink/renderer/modules/websockets/dom_websocket.h
+++ b/third_party/blink/renderer/modules/websockets/dom_websocket.h
@@ -60,6 +60,7 @@
 class ExceptionState;
 class ExecutionContext;
 class StringOrStringSequence;
+class V8UnionStringOrStringSequence;
 
 class MODULES_EXPORT DOMWebSocket
     : public EventTargetWithInlineData,
@@ -81,10 +82,17 @@
   static DOMWebSocket* Create(ExecutionContext*,
                               const String& url,
                               ExceptionState&);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static DOMWebSocket* Create(ExecutionContext* execution_context,
+                              const String& url,
+                              const V8UnionStringOrStringSequence* protocols,
+                              ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static DOMWebSocket* Create(ExecutionContext*,
                               const String& url,
                               const StringOrStringSequence& protocols,
                               ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   explicit DOMWebSocket(ExecutionContext*);
   ~DOMWebSocket() override;
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.cc b/third_party/blink/renderer/modules/webusb/usb_device.cc
index a7c25006..016c301 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.cc
+++ b/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_usb_control_transfer_parameters.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
@@ -94,6 +95,44 @@
   }
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+bool ConvertBufferSource(const V8BufferSource* buffer_source,
+                         Vector<uint8_t>* vector,
+                         ScriptPromiseResolver* resolver) {
+  DCHECK(buffer_source);
+  DOMArrayBuffer* array_buffer = nullptr;
+  void* data = nullptr;
+  size_t size = 0;
+  switch (buffer_source->GetContentType()) {
+    case V8BufferSource::ContentType::kArrayBuffer:
+      array_buffer = buffer_source->GetAsArrayBuffer();
+      data = array_buffer->Data();
+      size = array_buffer->ByteLength();
+      break;
+    case V8BufferSource::ContentType::kArrayBufferView: {
+      const auto& array_buffer_view = buffer_source->GetAsArrayBufferView();
+      array_buffer = array_buffer_view->buffer();
+      data = array_buffer_view->BaseAddress();
+      size = array_buffer_view->byteLength();
+      break;
+    }
+  }
+
+  if (array_buffer->IsDetached()) {
+    resolver->Reject(MakeGarbageCollected<DOMException>(
+        DOMExceptionCode::kInvalidStateError, kDetachedBuffer));
+    return false;
+  }
+  if (size > std::numeric_limits<wtf_size_t>::max()) {
+    resolver->Reject(MakeGarbageCollected<DOMException>(
+        DOMExceptionCode::kDataError, kBufferTooBig));
+    return false;
+  }
+
+  vector->Append(static_cast<uint8_t*>(data), static_cast<wtf_size_t>(size));
+  return true;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 bool ConvertBufferSource(const ArrayBufferOrArrayBufferView& buffer_source,
                          Vector<uint8_t>* vector,
                          ScriptPromiseResolver* resolver) {
@@ -131,6 +170,7 @@
   }
   return true;
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 }  // namespace
 
@@ -401,7 +441,12 @@
 ScriptPromise USBDevice::controlTransferOut(
     ScriptState* script_state,
     const USBControlTransferParameters* setup,
-    const ArrayBufferOrArrayBufferView& data) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BufferSource* data
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const ArrayBufferOrArrayBufferView& data
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (!EnsureNoDeviceOrInterfaceChangeInProgress(resolver))
@@ -466,7 +511,12 @@
 
 ScriptPromise USBDevice::transferOut(ScriptState* script_state,
                                      uint8_t endpoint_number,
-                                     const ArrayBufferOrArrayBufferView& data) {
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                     const V8BufferSource* data
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                     const ArrayBufferOrArrayBufferView& data
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+) {
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (!EnsureEndpointAvailable(false /* out */, endpoint_number, resolver))
@@ -504,7 +554,11 @@
 ScriptPromise USBDevice::isochronousTransferOut(
     ScriptState* script_state,
     uint8_t endpoint_number,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+    const V8BufferSource* data,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     const ArrayBufferOrArrayBufferView& data,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
     Vector<unsigned> packet_lengths) {
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.h b/third_party/blink/renderer/modules/webusb/usb_device.h
index c81eb4a..a70bec9 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.h
+++ b/third_party/blink/renderer/modules/webusb/usb_device.h
@@ -6,10 +6,12 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBUSB_USB_DEVICE_H_
 
 #include <bitset>
+
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "services/device/public/mojom/usb_device.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -74,25 +76,44 @@
                                   unsigned length);
   ScriptPromise controlTransferOut(ScriptState*,
                                    const USBControlTransferParameters* setup);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise controlTransferOut(ScriptState* script_state,
+                                   const USBControlTransferParameters* setup,
+                                   const V8BufferSource* data);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise controlTransferOut(ScriptState*,
                                    const USBControlTransferParameters* setup,
                                    const ArrayBufferOrArrayBufferView& data);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise clearHalt(ScriptState*,
                           String direction,
                           uint8_t endpoint_number);
   ScriptPromise transferIn(ScriptState*,
                            uint8_t endpoint_number,
                            unsigned length);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise transferOut(ScriptState* script_state,
+                            uint8_t endpoint_number,
+                            const V8BufferSource* data);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise transferOut(ScriptState*,
                             uint8_t endpoint_number,
                             const ArrayBufferOrArrayBufferView& data);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise isochronousTransferIn(ScriptState*,
                                       uint8_t endpoint_number,
                                       Vector<unsigned> packet_lengths);
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  ScriptPromise isochronousTransferOut(ScriptState* script_state,
+                                       uint8_t endpoint_number,
+                                       const V8BufferSource* data,
+                                       Vector<unsigned> packet_lengths);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise isochronousTransferOut(ScriptState*,
                                        uint8_t endpoint_number,
                                        const ArrayBufferOrArrayBufferView& data,
                                        Vector<unsigned> packet_lengths);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   ScriptPromise reset(ScriptState*);
 
   // ExecutionContextLifecycleObserver interface.
diff --git a/third_party/blink/renderer/modules/xr/xr_utils.cc b/third_party/blink/renderer/modules/xr/xr_utils.cc
index 541841e..4338b5d 100644
--- a/third_party/blink/renderer/modules/xr/xr_utils.cc
+++ b/third_party/blink/renderer/modules/xr/xr_utils.cc
@@ -6,6 +6,7 @@
 
 #include <cmath>
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_webgl2renderingcontext_webglrenderingcontext.h"
 #include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
 #include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h"
@@ -66,6 +67,20 @@
                                   w / length);
 }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+WebGLRenderingContextBase* webglRenderingContextBaseFromUnion(
+    const V8XRWebGLRenderingContext* context) {
+  DCHECK(context);
+  switch (context->GetContentType()) {
+    case V8XRWebGLRenderingContext::ContentType::kWebGL2RenderingContext:
+      return context->GetAsWebGL2RenderingContext();
+    case V8XRWebGLRenderingContext::ContentType::kWebGLRenderingContext:
+      return context->GetAsWebGLRenderingContext();
+  }
+  NOTREACHED();
+  return nullptr;
+}
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 WebGLRenderingContextBase* webglRenderingContextBaseFromUnion(
     const XRWebGLRenderingContext& context) {
   if (context.IsWebGL2RenderingContext()) {
@@ -74,6 +89,7 @@
     return context.GetAsWebGLRenderingContext();
   }
 }
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 base::Optional<device::Pose> CreatePose(
     const blink::TransformationMatrix& matrix) {
diff --git a/third_party/blink/renderer/modules/xr/xr_utils.h b/third_party/blink/renderer/modules/xr/xr_utils.h
index 2eea771b..fa5b010 100644
--- a/third_party/blink/renderer/modules/xr/xr_utils.h
+++ b/third_party/blink/renderer/modules/xr/xr_utils.h
@@ -7,6 +7,7 @@
 
 #include "device/vr/public/mojom/pose.h"
 #include "device/vr/public/mojom/vr_service.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
 #include "third_party/blink/renderer/modules/xr/xr_webgl_rendering_context.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -30,8 +31,13 @@
                                            double z,
                                            double w);
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+WebGLRenderingContextBase* webglRenderingContextBaseFromUnion(
+    const V8XRWebGLRenderingContext* context);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 WebGLRenderingContextBase* webglRenderingContextBaseFromUnion(
     const XRWebGLRenderingContext&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
 constexpr char kUnableToNormalizeZeroLength[] =
     "Unable to normalize vector of length 0.";
diff --git a/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc b/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc
index d089ab0..da29aeb 100644
--- a/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc
+++ b/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/xr/xr_webgl_binding.h"
 
+#include "third_party/blink/renderer/bindings/modules/v8/v8_union_webgl2renderingcontext_webglrenderingcontext.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_texture.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_unowned_texture.h"
@@ -23,7 +24,11 @@
 namespace blink {
 
 XRWebGLBinding* XRWebGLBinding::Create(XRSession* session,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                       const V8XRWebGLRenderingContext* context,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                        const XRWebGLRenderingContext& context,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                        ExceptionState& exception_state) {
   if (session->ended()) {
     exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
@@ -57,8 +62,13 @@
     return nullptr;
   }
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  return MakeGarbageCollected<XRWebGLBinding>(
+      session, webgl_context, context->IsWebGL2RenderingContext());
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   return MakeGarbageCollected<XRWebGLBinding>(
       session, webgl_context, context.IsWebGL2RenderingContext());
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 }
 
 XRWebGLBinding::XRWebGLBinding(XRSession* session,
diff --git a/third_party/blink/renderer/modules/xr/xr_webgl_binding.h b/third_party/blink/renderer/modules/xr/xr_webgl_binding.h
index 22d6cf3..a7548c81 100644
--- a/third_party/blink/renderer/modules/xr/xr_webgl_binding.h
+++ b/third_party/blink/renderer/modules/xr/xr_webgl_binding.h
@@ -28,9 +28,15 @@
   XRWebGLBinding(XRSession*, WebGLRenderingContextBase*, bool webgl2);
   ~XRWebGLBinding() override = default;
 
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+  static XRWebGLBinding* Create(XRSession* session,
+                                const V8XRWebGLRenderingContext* context,
+                                ExceptionState& exception_state);
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
   static XRWebGLBinding* Create(XRSession*,
                                 const XRWebGLRenderingContext&,
                                 ExceptionState&);
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
 
   XRSession* session() const { return session_; }
 
diff --git a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
index 16485bb6..cedeeb0 100644
--- a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
+++ b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
@@ -41,7 +41,11 @@
 }  // namespace
 
 XRWebGLLayer* XRWebGLLayer::Create(XRSession* session,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                                   const V8XRWebGLRenderingContext* context,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                    const XRWebGLRenderingContext& context,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                                    const XRWebGLLayerInit* initializer,
                                    ExceptionState& exception_state) {
   if (session->ended()) {
diff --git a/third_party/blink/renderer/modules/xr/xr_webgl_layer.h b/third_party/blink/renderer/modules/xr/xr_webgl_layer.h
index 6734f05..e47d371 100644
--- a/third_party/blink/renderer/modules/xr/xr_webgl_layer.h
+++ b/third_party/blink/renderer/modules/xr/xr_webgl_layer.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_WEBGL_LAYER_H_
 
 #include "device/vr/public/mojom/vr_service.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_xr_webgl_layer_init.h"
 #include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h"
@@ -39,7 +40,11 @@
   ~XRWebGLLayer() override;
 
   static XRWebGLLayer* Create(XRSession*,
+#if defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
+                              const V8XRWebGLRenderingContext*,
+#else   // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                               const XRWebGLRenderingContext&,
+#endif  // defined(USE_BLINK_V8_BINDING_NEW_IDL_UNION)
                               const XRWebGLLayerInit*,
                               ExceptionState&);
 
diff --git a/third_party/blink/renderer/platform/fonts/font.cc b/third_party/blink/renderer/platform/fonts/font.cc
index b0b39fdc..00e0cdb8 100644
--- a/third_party/blink/renderer/platform/fonts/font.cc
+++ b/third_party/blink/renderer/platform/fonts/font.cc
@@ -317,7 +317,7 @@
     curr_point.Move(bloberizer.Advance(), 0);
   }
 
-  bidi_runs.ClearRuns();
+  bidi_runs.DeleteRuns();
   return true;
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_resource_provider_cache.h b/third_party/blink/renderer/platform/graphics/gpu/webgpu_resource_provider_cache.h
index b8327155..e6f210f 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_resource_provider_cache.h
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_resource_provider_cache.h
@@ -10,6 +10,7 @@
 #include "gpu/command_buffer/client/webgpu_interface.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/deque.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h b/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h
index c51e9a8e..d8efee11 100644
--- a/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h
+++ b/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h
@@ -7,7 +7,7 @@
 
 #include "cc/paint/paint_canvas.h"
 #include "cc/paint/record_paint_canvas.h"
-#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
 
diff --git a/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h b/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h
index 1450219..72e27ed 100644
--- a/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h
+++ b/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h
@@ -27,8 +27,8 @@
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_MEMORY_MANAGED_PAINT_RECORDER_H_
 
 #include "cc/paint/paint_recorder.h"
-#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
 
 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
index bb35f797..1aa6ec6 100644
--- a/third_party/blink/renderer/platform/heap/impl/blink_gc.h
+++ b/third_party/blink/renderer/platform/heap/impl/blink_gc.h
@@ -41,7 +41,6 @@
   H(HashTable)            \
   H(Node)                 \
   H(CSSValue)             \
-  H(LayoutObject)         \
   H(LargeObject)
 
 class PLATFORM_EXPORT WorklistTaskId {
diff --git a/third_party/blink/renderer/platform/heap/impl/threading_traits.h b/third_party/blink/renderer/platform/heap/impl/threading_traits.h
index 28c10e9e..bfae97b 100644
--- a/third_party/blink/renderer/platform/heap/impl/threading_traits.h
+++ b/third_party/blink/renderer/platform/heap/impl/threading_traits.h
@@ -30,7 +30,6 @@
 
 // TODO(haraken): These forward declarations violate dependency rules.
 // Remove them.
-class LayoutObject;
 class Node;
 class NodeList;
 class NodeRareData;
@@ -38,8 +37,6 @@
 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,
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/DEPS b/third_party/blink/renderer/platform/loader/fetch/url_loader/DEPS
index d1edc9d..e07539b 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/DEPS
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
     "+base/atomic_sequence_num.h",
+    "+base/containers/queue.h",
     "+net/base/registry_controlled_domains/registry_controlled_domain.h",
     "+net/base/request_priority.h",
     "+net/base/host_port_pair.h",
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.cc
index 4143811c..b3c1fef 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/mojo_url_loader_client.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/containers/queue.h"
 #include "base/feature_list.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/single_thread_task_runner.h"
diff --git a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
index b58078c..73b9605 100644
--- a/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
+++ b/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
@@ -16,6 +16,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/webaudiosourceprovider_impl.h"
 #include "third_party/blink/renderer/platform/media/web_audio_source_provider_client.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 
 using ::testing::_;
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index df2c64e..32a5e7f 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1888,7 +1888,6 @@
     },
     {
       name: "SharedArrayBuffer",
-      status: "stable",
     },
     {
       name: "SharedArrayBufferOnDesktop",
diff --git a/third_party/blink/renderer/platform/text/bidi_character_run.h b/third_party/blink/renderer/platform/text/bidi_character_run.h
index 024a10a..84d97c7 100644
--- a/third_party/blink/renderer/platform/text/bidi_character_run.h
+++ b/third_party/blink/renderer/platform/text/bidi_character_run.h
@@ -28,7 +28,9 @@
 
 namespace blink {
 
-struct BidiCharacterRun : public GarbageCollected<BidiCharacterRun> {
+struct BidiCharacterRun {
+  USING_FAST_MALLOC(BidiCharacterRun);
+
  public:
   BidiCharacterRun(bool override,
                    unsigned char level,
@@ -85,8 +87,6 @@
   BidiCharacterRun* Next() const { return next_; }
   void SetNext(BidiCharacterRun* next) { next_ = next; }
 
-  virtual void Trace(Visitor* visitor) const { visitor->Trace(next_); }
-
   // Do not add anything apart from bitfields until after m_next. See
   // https://bugs.webkit.org/show_bug.cgi?id=100173
   bool override_ : 1;
@@ -94,7 +94,7 @@
   // save 8 bytes per object on 64-bit.
   bool has_hyphen_ : 1;
   unsigned char level_;
-  Member<BidiCharacterRun> next_;
+  BidiCharacterRun* next_;
   int start_;
   int stop_;
 };
diff --git a/third_party/blink/renderer/platform/text/bidi_resolver.h b/third_party/blink/renderer/platform/text/bidi_resolver.h
index e3c8ada..557dde1 100644
--- a/third_party/blink/renderer/platform/text/bidi_resolver.h
+++ b/third_party/blink/renderer/platform/text/bidi_resolver.h
@@ -289,7 +289,7 @@
   // It's unclear if this is still needed.
   void MarkCurrentRunEmpty() { empty_run_ = true; }
 
-  HeapVector<IsolatedRun>& IsolatedRuns() { return isolated_runs_; }
+  Vector<IsolatedRun>& IsolatedRuns() { return isolated_runs_; }
 
   bool IsEndOfLine(const Iterator& end) {
     return current_ == end || current_.AtEnd();
@@ -353,7 +353,7 @@
   MidpointState<Iterator> midpoint_state_;
 
   unsigned nested_isolate_count_ = 0;
-  HeapVector<IsolatedRun> isolated_runs_;
+  Vector<IsolatedRun> isolated_runs_;
   Run* trailing_space_run_;
   bool needs_trailing_space_;
   TextDirection paragraph_directionality_;
@@ -379,8 +379,7 @@
       bool* has_strong_directionality);
 
   Vector<BidiEmbedding, 8> current_explicit_embedding_sequence_;
-  HeapHashMap<Member<Run>, MidpointState<Iterator>>
-      midpoint_state_for_isolated_run_;
+  HashMap<Run*, MidpointState<Iterator>> midpoint_state_for_isolated_run_;
 
   DISALLOW_COPY_AND_ASSIGN(BidiResolver);
 };
@@ -419,9 +418,8 @@
           USHRT_MAX;  // InlineTextBox stores text length as unsigned short.
       if (end - start_offset > kLimit)
         end = start_offset + kLimit;
-      runs.AddRun(MakeGarbageCollected<Run>(Context()->Override(),
-                                            Context()->Level(), start_offset,
-                                            end, direction_, Context()->Dir()));
+      runs.AddRun(new Run(Context()->Override(), Context()->Level(),
+                          start_offset, end, direction_, Context()->Dir()));
       start_offset = end;
     }
 
diff --git a/third_party/blink/renderer/platform/text/bidi_resolver_test.cc b/third_party/blink/renderer/platform/text/bidi_resolver_test.cc
index c632da9f..0990041 100644
--- a/third_party/blink/renderer/platform/text/bidi_resolver_test.cc
+++ b/third_party/blink/renderer/platform/text/bidi_resolver_test.cc
@@ -261,7 +261,7 @@
       break;
     }
   }
-  runs.ClearRuns();
+  runs.DeleteRuns();
 }
 
 TEST(BidiResolver, DISABLED_BidiTest_txt) {
diff --git a/third_party/blink/renderer/platform/text/bidi_run_list.h b/third_party/blink/renderer/platform/text/bidi_run_list.h
index c505e6a..27aa5db7 100644
--- a/third_party/blink/renderer/platform/text/bidi_run_list.h
+++ b/third_party/blink/renderer/platform/text/bidi_run_list.h
@@ -52,7 +52,7 @@
   void MoveRunToEnd(Run*);
   void MoveRunToBeginning(Run*);
 
-  void ClearRuns();
+  void DeleteRuns();
   void ReverseRuns(unsigned start, unsigned end);
   void ReorderRunsFromLevels();
 
@@ -61,6 +61,8 @@
   void ReplaceRunWithRuns(Run* to_replace, BidiRunList<Run>& new_runs);
 
  private:
+  void ClearWithoutDestroyingRuns();
+
   Run* first_run_;
   Run* last_run_;
   Run* logically_last_run_;
@@ -163,11 +165,12 @@
   run_count_ +=
       new_runs.RunCount() - 1;  // We added the new runs and removed toReplace.
 
-  new_runs.ClearRuns();
+  delete to_replace;
+  new_runs.ClearWithoutDestroyingRuns();
 }
 
 template <class Run>
-void BidiRunList<Run>::ClearRuns() {
+void BidiRunList<Run>::ClearWithoutDestroyingRuns() {
   first_run_ = nullptr;
   last_run_ = nullptr;
   logically_last_run_ = nullptr;
@@ -175,6 +178,21 @@
 }
 
 template <class Run>
+void BidiRunList<Run>::DeleteRuns() {
+  if (!first_run_)
+    return;
+
+  Run* curr = first_run_;
+  while (curr) {
+    Run* s = curr->Next();
+    delete curr;
+    curr = s;
+  }
+
+  ClearWithoutDestroyingRuns();
+}
+
+template <class Run>
 void BidiRunList<Run>::ReverseRuns(unsigned start, unsigned end) {
   DCHECK(run_count_);
   if (start >= end)
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-light-dismiss.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-light-dismiss.tentative-expected.txt
deleted file mode 100644
index 6c38937..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-light-dismiss.tentative-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-This is a testharness.js-based test.
-PASS Clicking outside a popup will dismiss the popup
-PASS Clicking inside a popup does not close that popup
-PASS Clicking inside a child popup shouldn't close either popup
-PASS Clicking inside a parent popup should close child popup
-PASS Clicking on anchor element shouldn't close its popup
-PASS An invoking element should be part of the ancestor chain
-PASS An invoking element that was not used to invoke the popup should NOT be part of the ancestor chain
-FAIL Dragging from an open popup outside an open popup should leave the popup open assert_true: popup1 should be open expected true got false
-PASS Scrolling within a popup should not close the popup
-PASS Popup should be closed by an explicit resize of the popup
-PASS Popup should be closed by an implicit resize of the popup
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-light-dismiss.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-light-dismiss.tentative.html
index e3b904e..649b594c 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-light-dismiss.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-light-dismiss.tentative.html
@@ -159,13 +159,14 @@
     },'An invoking element that was not used to invoke the popup should NOT be part of the ancestor chain');
 
     popup1.show();
-    popup2.show();
+    popup2.show(); // Popup1 is an ancestral element for popup2.
     assert_true(popup1.open);
     assert_true(popup2.open);
     const drag_actions = new test_driver.Actions();
-    await drag_actions.pointerMove(0,0,{origin: popup1})
+    // Drag *from* popup2 *to* popup1 (its ancestor).
+    await drag_actions.pointerMove(0,0,{origin: popup2})
       .pointerDown({button: drag_actions.ButtonType.LEFT})
-      .pointerMove(0,0,{origin: popup2})
+      .pointerMove(0,0,{origin: popup1})
       .pointerUp({button: drag_actions.ButtonType.LEFT})
       .send();
     test(t => {
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-shadow-dom.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-shadow-dom.tentative.html
index 516b6ead..99a6523 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-shadow-dom.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-popup-element/popup-shadow-dom.tentative.html
@@ -100,7 +100,7 @@
     <template shadowroot=open>
       <button id=t3b1 onclick='showPopup("test3",0)'>Test 3 Popup 1</button>
       <popup anchor=t3b1>
-        <p>This popup will be hidden when popup2 shows.</p>
+        <p>This popup will stay open when popup2 shows.</p>
         <slot></slot>
       </popup>
     </template>
@@ -115,15 +115,17 @@
     popup1.show();
     assert_true(popup1.open);
     assert_true(popupVisible(popup1));
-    // Showing popup2 will close popup1, since it is not a DOM
+    // Showing popup2 should not close popup1, since it is a flat
     // tree ancestor of popup2's anchor button.
     popup2.show();
     assert_true(popup2.open);
     assert_true(popupVisible(popup2));
+    assert_true(popup1.open);
+    assert_true(popupVisible(popup1));
+    popup1.hide();
+    assert_false(popup2.open);
     assert_false(popup1.open);
-    assert_false(popupVisible(popup1));
-    popup2.hide();
-  }, "anchor references use the DOM tree not the flat tree");
+  }, "anchor references use the flat tree not the DOM tree");
 </script>
 
 
diff --git a/third_party/blink/web_tests/external/wpt/url/toascii.window-expected.txt b/third_party/blink/web_tests/external/wpt/url/toascii.window-expected.txt
index 7264236..597c806 100644
--- a/third_party/blink/web_tests/external/wpt/url/toascii.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/url/toascii.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 343 tests; 144 PASS, 199 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 343 tests; 224 PASS, 119 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Loading data…
 PASS aa-- (using URL)
 PASS aa-- (using URL.host)
@@ -10,15 +10,15 @@
 PASS aa-- (using <area>)
 PASS aa-- (using <area>.host)
 PASS aa-- (using <area>.hostname)
-FAIL a†-- (using URL) Failed to construct 'URL': Invalid URL
-FAIL a†-- (using URL.host) assert_equals: expected "xn--a---kp0a" but got ""
-FAIL a†-- (using URL.hostname) assert_equals: expected "xn--a---kp0a" but got ""
-FAIL a†-- (using <a>) Failed to construct 'URL': Invalid URL
-FAIL a†-- (using <a>.host) assert_equals: expected "xn--a---kp0a" but got ""
-FAIL a†-- (using <a>.hostname) assert_equals: expected "xn--a---kp0a" but got ""
-FAIL a†-- (using <area>) Failed to construct 'URL': Invalid URL
-FAIL a†-- (using <area>.host) assert_equals: expected "xn--a---kp0a" but got ""
-FAIL a†-- (using <area>.hostname) assert_equals: expected "xn--a---kp0a" but got ""
+PASS a†-- (using URL)
+PASS a†-- (using URL.host)
+PASS a†-- (using URL.hostname)
+PASS a†-- (using <a>)
+PASS a†-- (using <a>.host)
+PASS a†-- (using <a>.hostname)
+PASS a†-- (using <area>)
+PASS a†-- (using <area>.host)
+PASS a†-- (using <area>.hostname)
 PASS ab--c (using URL)
 PASS ab--c (using URL.host)
 PASS ab--c (using URL.hostname)
@@ -37,15 +37,15 @@
 PASS -x (using <area>)
 PASS -x (using <area>.host)
 PASS -x (using <area>.hostname)
-FAIL -† (using URL) Failed to construct 'URL': Invalid URL
-FAIL -† (using URL.host) assert_equals: expected "xn----xhn" but got ""
-FAIL -† (using URL.hostname) assert_equals: expected "xn----xhn" but got ""
-FAIL -† (using <a>) Failed to construct 'URL': Invalid URL
-FAIL -† (using <a>.host) assert_equals: expected "xn----xhn" but got ""
-FAIL -† (using <a>.hostname) assert_equals: expected "xn----xhn" but got ""
-FAIL -† (using <area>) Failed to construct 'URL': Invalid URL
-FAIL -† (using <area>.host) assert_equals: expected "xn----xhn" but got ""
-FAIL -† (using <area>.hostname) assert_equals: expected "xn----xhn" but got ""
+PASS -† (using URL)
+PASS -† (using URL.host)
+PASS -† (using URL.hostname)
+PASS -† (using <a>)
+PASS -† (using <a>.host)
+PASS -† (using <a>.hostname)
+PASS -† (using <area>)
+PASS -† (using <area>.host)
+PASS -† (using <area>.hostname)
 PASS -x.xn--nxa (using URL)
 PASS -x.xn--nxa (using URL.host)
 PASS -x.xn--nxa (using URL.hostname)
@@ -55,15 +55,15 @@
 PASS -x.xn--nxa (using <area>)
 PASS -x.xn--nxa (using <area>.host)
 PASS -x.xn--nxa (using <area>.hostname)
-FAIL -x.β (using URL) Failed to construct 'URL': Invalid URL
-FAIL -x.β (using URL.host) assert_equals: expected "-x.xn--nxa" but got ""
-FAIL -x.β (using URL.hostname) assert_equals: expected "-x.xn--nxa" but got ""
-FAIL -x.β (using <a>) Failed to construct 'URL': Invalid URL
-FAIL -x.β (using <a>.host) assert_equals: expected "-x.xn--nxa" but got ""
-FAIL -x.β (using <a>.hostname) assert_equals: expected "-x.xn--nxa" but got ""
-FAIL -x.β (using <area>) Failed to construct 'URL': Invalid URL
-FAIL -x.β (using <area>.host) assert_equals: expected "-x.xn--nxa" but got ""
-FAIL -x.β (using <area>.hostname) assert_equals: expected "-x.xn--nxa" but got ""
+PASS -x.β (using URL)
+PASS -x.β (using URL.host)
+PASS -x.β (using URL.hostname)
+PASS -x.β (using <a>)
+PASS -x.β (using <a>.host)
+PASS -x.β (using <a>.hostname)
+PASS -x.β (using <area>)
+PASS -x.β (using <area>.host)
+PASS -x.β (using <area>.hostname)
 PASS x-.xn--nxa (using URL)
 PASS x-.xn--nxa (using URL.host)
 PASS x-.xn--nxa (using URL.hostname)
@@ -73,15 +73,15 @@
 PASS x-.xn--nxa (using <area>)
 PASS x-.xn--nxa (using <area>.host)
 PASS x-.xn--nxa (using <area>.hostname)
-FAIL x-.β (using URL) Failed to construct 'URL': Invalid URL
-FAIL x-.β (using URL.host) assert_equals: expected "x-.xn--nxa" but got ""
-FAIL x-.β (using URL.hostname) assert_equals: expected "x-.xn--nxa" but got ""
-FAIL x-.β (using <a>) Failed to construct 'URL': Invalid URL
-FAIL x-.β (using <a>.host) assert_equals: expected "x-.xn--nxa" but got ""
-FAIL x-.β (using <a>.hostname) assert_equals: expected "x-.xn--nxa" but got ""
-FAIL x-.β (using <area>) Failed to construct 'URL': Invalid URL
-FAIL x-.β (using <area>.host) assert_equals: expected "x-.xn--nxa" but got ""
-FAIL x-.β (using <area>.hostname) assert_equals: expected "x-.xn--nxa" but got ""
+PASS x-.β (using URL)
+PASS x-.β (using URL.host)
+PASS x-.β (using URL.hostname)
+PASS x-.β (using <a>)
+PASS x-.β (using <a>.host)
+PASS x-.β (using <a>.hostname)
+PASS x-.β (using <area>)
+PASS x-.β (using <area>.host)
+PASS x-.β (using <area>.hostname)
 PASS x..xn--nxa (using URL)
 PASS x..xn--nxa (using URL.host)
 PASS x..xn--nxa (using URL.hostname)
@@ -91,15 +91,15 @@
 PASS x..xn--nxa (using <area>)
 PASS x..xn--nxa (using <area>.host)
 PASS x..xn--nxa (using <area>.hostname)
-FAIL x..β (using URL) Failed to construct 'URL': Invalid URL
-FAIL x..β (using URL.host) assert_equals: expected "x..xn--nxa" but got ""
-FAIL x..β (using URL.hostname) assert_equals: expected "x..xn--nxa" but got ""
-FAIL x..β (using <a>) Failed to construct 'URL': Invalid URL
-FAIL x..β (using <a>.host) assert_equals: expected "x..xn--nxa" but got ""
-FAIL x..β (using <a>.hostname) assert_equals: expected "x..xn--nxa" but got ""
-FAIL x..β (using <area>) Failed to construct 'URL': Invalid URL
-FAIL x..β (using <area>.host) assert_equals: expected "x..xn--nxa" but got ""
-FAIL x..β (using <area>.hostname) assert_equals: expected "x..xn--nxa" but got ""
+PASS x..β (using URL)
+PASS x..β (using URL.host)
+PASS x..β (using URL.hostname)
+PASS x..β (using <a>)
+PASS x..β (using <a>.host)
+PASS x..β (using <a>.hostname)
+PASS x..β (using <area>)
+PASS x..β (using <area>.host)
+PASS x..β (using <area>.hostname)
 FAIL xn--a (using URL) assert_throws_js: function "() => makeURL("url", hostTest.input)" did not throw
 FAIL xn--a (using URL.host) assert_equals: expected "x" but got "xn--a"
 FAIL xn--a (using URL.hostname) assert_equals: expected "x" but got "xn--a"
@@ -154,24 +154,24 @@
 PASS ab--c.xn--nxa (using <area>)
 PASS ab--c.xn--nxa (using <area>.host)
 PASS ab--c.xn--nxa (using <area>.hostname)
-FAIL ab--c.β (using URL) Failed to construct 'URL': Invalid URL
-FAIL ab--c.β (using URL.host) assert_equals: expected "ab--c.xn--nxa" but got ""
-FAIL ab--c.β (using URL.hostname) assert_equals: expected "ab--c.xn--nxa" but got ""
-FAIL ab--c.β (using <a>) Failed to construct 'URL': Invalid URL
-FAIL ab--c.β (using <a>.host) assert_equals: expected "ab--c.xn--nxa" but got ""
-FAIL ab--c.β (using <a>.hostname) assert_equals: expected "ab--c.xn--nxa" but got ""
-FAIL ab--c.β (using <area>) Failed to construct 'URL': Invalid URL
-FAIL ab--c.β (using <area>.host) assert_equals: expected "ab--c.xn--nxa" but got ""
-FAIL ab--c.β (using <area>.hostname) assert_equals: expected "ab--c.xn--nxa" but got ""
-PASS ‍.example (using URL)
-FAIL ‍.example (using URL.host) assert_equals: expected "x" but got ""
-FAIL ‍.example (using URL.hostname) assert_equals: expected "x" but got ""
-FAIL ‍.example (using <a>) assert_equals: expected "https://‍.example/x" but got "https://%E2%80%8D.example/x"
-FAIL ‍.example (using <a>.host) assert_equals: expected "x" but got ""
-FAIL ‍.example (using <a>.hostname) assert_equals: expected "x" but got ""
-FAIL ‍.example (using <area>) assert_equals: expected "https://‍.example/x" but got "https://%E2%80%8D.example/x"
-FAIL ‍.example (using <area>.host) assert_equals: expected "x" but got ""
-FAIL ‍.example (using <area>.hostname) assert_equals: expected "x" but got ""
+PASS ab--c.β (using URL)
+PASS ab--c.β (using URL.host)
+PASS ab--c.β (using URL.hostname)
+PASS ab--c.β (using <a>)
+PASS ab--c.β (using <a>.host)
+PASS ab--c.β (using <a>.hostname)
+PASS ab--c.β (using <area>)
+PASS ab--c.β (using <area>.host)
+PASS ab--c.β (using <area>.hostname)
+FAIL ‍.example (using URL) assert_throws_js: function "() => makeURL("url", hostTest.input)" did not throw
+FAIL ‍.example (using URL.host) assert_equals: expected "x" but got ".example"
+FAIL ‍.example (using URL.hostname) assert_equals: expected "x" but got ".example"
+FAIL ‍.example (using <a>) assert_equals: expected "" but got ".example"
+FAIL ‍.example (using <a>.host) assert_equals: expected "x" but got ".example"
+FAIL ‍.example (using <a>.hostname) assert_equals: expected "x" but got ".example"
+FAIL ‍.example (using <area>) assert_equals: expected "" but got ".example"
+FAIL ‍.example (using <area>.host) assert_equals: expected "x" but got ".example"
+FAIL ‍.example (using <area>.hostname) assert_equals: expected "x" but got ".example"
 FAIL xn--1ug.example (using URL) assert_throws_js: function "() => makeURL("url", hostTest.input)" did not throw
 FAIL xn--1ug.example (using URL.host) assert_equals: expected "x" but got "xn--1ug.example"
 FAIL xn--1ug.example (using URL.hostname) assert_equals: expected "x" but got "xn--1ug.example"
@@ -244,15 +244,15 @@
 PASS x01234567890123456789012345678901234567890123456789012345678901x (using <area>)
 PASS x01234567890123456789012345678901234567890123456789012345678901x (using <area>.host)
 PASS x01234567890123456789012345678901234567890123456789012345678901x (using <area>.hostname)
-FAIL x01234567890123456789012345678901234567890123456789012345678901† (using URL) Failed to construct 'URL': Invalid URL
-FAIL x01234567890123456789012345678901234567890123456789012345678901† (using URL.host) assert_equals: expected "xn--x01234567890123456789012345678901234567890123456789012345678901-6963b" but got ""
-FAIL x01234567890123456789012345678901234567890123456789012345678901† (using URL.hostname) assert_equals: expected "xn--x01234567890123456789012345678901234567890123456789012345678901-6963b" but got ""
-FAIL x01234567890123456789012345678901234567890123456789012345678901† (using <a>) Failed to construct 'URL': Invalid URL
-FAIL x01234567890123456789012345678901234567890123456789012345678901† (using <a>.host) assert_equals: expected "xn--x01234567890123456789012345678901234567890123456789012345678901-6963b" but got ""
-FAIL x01234567890123456789012345678901234567890123456789012345678901† (using <a>.hostname) assert_equals: expected "xn--x01234567890123456789012345678901234567890123456789012345678901-6963b" but got ""
-FAIL x01234567890123456789012345678901234567890123456789012345678901† (using <area>) Failed to construct 'URL': Invalid URL
-FAIL x01234567890123456789012345678901234567890123456789012345678901† (using <area>.host) assert_equals: expected "xn--x01234567890123456789012345678901234567890123456789012345678901-6963b" but got ""
-FAIL x01234567890123456789012345678901234567890123456789012345678901† (using <area>.hostname) assert_equals: expected "xn--x01234567890123456789012345678901234567890123456789012345678901-6963b" but got ""
+PASS x01234567890123456789012345678901234567890123456789012345678901† (using URL)
+PASS x01234567890123456789012345678901234567890123456789012345678901† (using URL.host)
+PASS x01234567890123456789012345678901234567890123456789012345678901† (using URL.hostname)
+PASS x01234567890123456789012345678901234567890123456789012345678901† (using <a>)
+PASS x01234567890123456789012345678901234567890123456789012345678901† (using <a>.host)
+PASS x01234567890123456789012345678901234567890123456789012345678901† (using <a>.hostname)
+PASS x01234567890123456789012345678901234567890123456789012345678901† (using <area>)
+PASS x01234567890123456789012345678901234567890123456789012345678901† (using <area>.host)
+PASS x01234567890123456789012345678901234567890123456789012345678901† (using <area>.hostname)
 PASS x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa (using URL)
 PASS x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa (using URL.host)
 PASS x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa (using URL.hostname)
@@ -262,15 +262,15 @@
 PASS x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa (using <area>)
 PASS x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa (using <area>.host)
 PASS x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa (using <area>.hostname)
-FAIL x01234567890123456789012345678901234567890123456789012345678901x.β (using URL) Failed to construct 'URL': Invalid URL
-FAIL x01234567890123456789012345678901234567890123456789012345678901x.β (using URL.host) assert_equals: expected "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" but got ""
-FAIL x01234567890123456789012345678901234567890123456789012345678901x.β (using URL.hostname) assert_equals: expected "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" but got ""
-FAIL x01234567890123456789012345678901234567890123456789012345678901x.β (using <a>) Failed to construct 'URL': Invalid URL
-FAIL x01234567890123456789012345678901234567890123456789012345678901x.β (using <a>.host) assert_equals: expected "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" but got ""
-FAIL x01234567890123456789012345678901234567890123456789012345678901x.β (using <a>.hostname) assert_equals: expected "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" but got ""
-FAIL x01234567890123456789012345678901234567890123456789012345678901x.β (using <area>) Failed to construct 'URL': Invalid URL
-FAIL x01234567890123456789012345678901234567890123456789012345678901x.β (using <area>.host) assert_equals: expected "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" but got ""
-FAIL x01234567890123456789012345678901234567890123456789012345678901x.β (using <area>.hostname) assert_equals: expected "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" but got ""
+PASS x01234567890123456789012345678901234567890123456789012345678901x.β (using URL)
+PASS x01234567890123456789012345678901234567890123456789012345678901x.β (using URL.host)
+PASS x01234567890123456789012345678901234567890123456789012345678901x.β (using URL.hostname)
+PASS x01234567890123456789012345678901234567890123456789012345678901x.β (using <a>)
+PASS x01234567890123456789012345678901234567890123456789012345678901x.β (using <a>.host)
+PASS x01234567890123456789012345678901234567890123456789012345678901x.β (using <a>.hostname)
+PASS x01234567890123456789012345678901234567890123456789012345678901x.β (using <area>)
+PASS x01234567890123456789012345678901234567890123456789012345678901x.β (using <area>.host)
+PASS x01234567890123456789012345678901234567890123456789012345678901x.β (using <area>.hostname)
 PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.x (using URL)
 PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.x (using URL.host)
 PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.x (using URL.hostname)
@@ -289,15 +289,15 @@
 PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa (using <area>)
 PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa (using <area>.host)
 PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa (using <area>.hostname)
-FAIL 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using URL) Failed to construct 'URL': Invalid URL
-FAIL 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using URL.host) assert_equals: expected "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" but got ""
-FAIL 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using URL.hostname) assert_equals: expected "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" but got ""
-FAIL 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <a>) Failed to construct 'URL': Invalid URL
-FAIL 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <a>.host) assert_equals: expected "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" but got ""
-FAIL 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <a>.hostname) assert_equals: expected "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" but got ""
-FAIL 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <area>) Failed to construct 'URL': Invalid URL
-FAIL 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <area>.host) assert_equals: expected "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" but got ""
-FAIL 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <area>.hostname) assert_equals: expected "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" but got ""
+PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using URL)
+PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using URL.host)
+PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using URL.hostname)
+PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <a>)
+PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <a>.host)
+PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <a>.hostname)
+PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <area>)
+PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <area>.host)
+PASS 01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β (using <area>.hostname)
 PASS a­b (using URL)
 PASS a­b (using URL.host)
 PASS a­b (using URL.hostname)
diff --git a/third_party/blink/web_tests/fast/css/zero-font-size-crash-expected.txt b/third_party/blink/web_tests/fast/css/zero-font-size-crash-expected.txt
deleted file mode 100644
index 203b15f..0000000
--- a/third_party/blink/web_tests/fast/css/zero-font-size-crash-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Test for bug 564698.
-
-Zero size font should not crash.
-
-Font size is 0in.
diff --git a/third_party/blink/web_tests/fast/css/zero-font-size-crash.html b/third_party/blink/web_tests/fast/css/zero-font-size-crash.html
index 6f0f573..a457c29e 100644
--- a/third_party/blink/web_tests/fast/css/zero-font-size-crash.html
+++ b/third_party/blink/web_tests/fast/css/zero-font-size-crash.html
@@ -1,8 +1,8 @@
 <!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
 <style>
-The test PASSES if it did not crash.</p>
-div {word-spacing: 94vw;}
-* {
+p {
     writing-mode:vertical-lr;
     text-combine-upright:all;
     font-size: 0in;
@@ -10,11 +10,7 @@
 }
 </style>
 <p>Test for <a href="http://crbug.com/564698">bug 564698</a>.</p>
-<p>Zero size font should not crash.
-<div>
-Font size is 0in.
-</div>
+<p>Zero size font should not crash.</p>
 <script>
-if (window.testRunner)
-    testRunner.dumpAsText();
+test(() => {}, 'text-combine-upright:all with zero font size');
 </script>
diff --git a/third_party/blink/web_tests/fast/parser/preloader-base-invalidurl.html b/third_party/blink/web_tests/fast/parser/preloader-base-invalidurl.html
index 523db31..2a5cc8d 100644
--- a/third_party/blink/web_tests/fast/parser/preloader-base-invalidurl.html
+++ b/third_party/blink/web_tests/fast/parser/preloader-base-invalidurl.html
@@ -9,7 +9,7 @@
     var framedoc = target.document;
 
     framedoc.open();
-    framedoc.write("<base href='ftp:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa♬'></base>");
+    framedoc.write("<base href='ftp:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa:notaport♬'></base>");
     framedoc.write("<script src=':'><\/script>");
     framedoc.close();
 
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/quirks-mode-issue-creation.js b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/quirks-mode-issue-creation.js
index f744543..ea9cc648 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/quirks-mode-issue-creation.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/quirks-mode-issue-creation.js
@@ -3,18 +3,20 @@
 
   await dp.Audits.enable();
 
+  let expectedIssues = 3;
   dp.Audits.onIssueAdded(issue => {
     testRunner.log(issue.params, "Inspector issue: ", ['documentNodeId', 'frameId', 'loaderId']);
+    if (--expectedIssues === 0) {
+      testRunner.completeTest();
+    }
   });
 
-  await page.navigate('../resources/quirks-mode.html');
-
   // Test that going to a no-quirks page does not report QuirksMode issues.
   await page.navigate('../resources/inspector-protocol-page.html');
 
+  await page.navigate('../resources/quirks-mode.html');
+
   await page.navigate('../resources/limited-quirks-mode.html');
 
   await page.navigate('../resources/quirks-mode-in-iframe.html');
-
-  testRunner.completeTest();
 });
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/renderer-cors-issues-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/renderer-cors-issues-expected.txt
new file mode 100644
index 0000000..0e2a290
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/renderer-cors-issues-expected.txt
@@ -0,0 +1,73 @@
+Test to make sure early CORS issues are correctly reported.
+[
+    [0] : {
+        code : CorsIssue
+        details : {
+            corsIssueDetails : {
+                corsErrorStatus : {
+                    corsError : CorsDisabledScheme
+                    failedParameter : file
+                }
+                initiatorOrigin : http://127.0.0.1:8000
+                isWarning : false
+                location : {
+                    columnNumber : 7
+                    lineNumber : 2
+                    scriptId : <string>
+                    url : 
+                }
+                request : {
+                    requestId : <string>
+                    url : file://doesnt.matter/
+                }
+            }
+        }
+    }
+    [1] : {
+        code : CorsIssue
+        details : {
+            corsIssueDetails : {
+                corsErrorStatus : {
+                    corsError : DisallowedByMode
+                    failedParameter : 
+                }
+                initiatorOrigin : http://127.0.0.1:8000
+                isWarning : false
+                location : {
+                    columnNumber : 7
+                    lineNumber : 6
+                    scriptId : <string>
+                    url : 
+                }
+                request : {
+                    requestId : <string>
+                    url : https://devtools-b.oopif.test:8443/index.html
+                }
+            }
+        }
+    }
+    [2] : {
+        code : CorsIssue
+        details : {
+            corsIssueDetails : {
+                corsErrorStatus : {
+                    corsError : NoCorsRedirectModeNotFollow
+                    failedParameter : 
+                }
+                initiatorOrigin : http://127.0.0.1:8000
+                isWarning : false
+                location : {
+                    columnNumber : 7
+                    lineNumber : 11
+                    scriptId : <string>
+                    url : 
+                }
+                request : {
+                    requestId : <string>
+                    url : https://devtools-b.oopif.test:8443/index.html
+                }
+            }
+        }
+    }
+]
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/renderer-cors-issues.js b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/renderer-cors-issues.js
new file mode 100644
index 0000000..344315b1
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/renderer-cors-issues.js
@@ -0,0 +1,35 @@
+(async function(testRunner) {
+  const {page, session, dp} = await testRunner.startBlank(
+      `Test to make sure early CORS issues are correctly reported.`);
+
+  await dp.Audits.enable();
+
+  const result = session.evaluate(`
+    try {
+      fetch('file://doesnt.matter');
+    } catch (e) {}
+
+    try {
+      fetch('https://devtools-b.oopif.test:8443/index.html', {mode:
+    "same-origin"});
+    } catch (e) {}
+
+    try {
+      fetch('https://devtools-b.oopif.test:8443/index.html', {mode:
+    "no-cors", redirect: "error"});
+    } catch (e) {}
+  `);
+
+  const issues = [];
+  for (let i = 0; i < 3; ++i) {
+    const issue = await dp.Audits.onceIssueAdded();
+    issues.push(issue.params.issue);
+  }
+
+  issues.sort(
+      (a, b) =>
+          a.details?.corsIssueDetails?.corsErrorStatus?.corsError.localeCompare(
+              b.details?.corsIssueDetails?.corsErrorStatus?.corsError));
+  testRunner.log(issues);
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/background-fetch.https.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/background-fetch.https.html
index 689b0b4..359230c 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/background-fetch.https.html
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/background-fetch.https.html
@@ -17,7 +17,7 @@
 } else {
   async function loadPrerenderPage() {
     const prerenderEventCollector =
-        new PrerenderEventCollector({supportReadyToActivate: true});
+        new PrerenderEventCollector({customizedReadyToActivate: true});
     const scope = `resources/`;
     const registration = await navigator.serviceWorker.getRegistration(scope);
     const fetch_promise = registration.backgroundFetch.fetch(
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/background-sync.https.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/background-sync.https.html
index ac5cbfb..0d15142 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/background-sync.https.html
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/background-sync.https.html
@@ -17,7 +17,7 @@
 } else {
   async function loadPrerenderPage() {
     const prerenderEventCollector =
-        new PrerenderEventCollector({supportReadyToActivate: true});
+        new PrerenderEventCollector({customizedReadyToActivate: true});
     const scope = `resources/`;
     const registration = await navigator.serviceWorker.getRegistration(scope);
     const register_promise = registration.periodicSync.register(
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/dedicated-worker.https.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/dedicated-worker.https.html
index 22e31d79..6739312 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/dedicated-worker.https.html
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/dedicated-worker.https.html
@@ -15,8 +15,9 @@
 if (!isPrerendering) {
   loadInitiatorPage();
 } else {
-  const prerenderEventCollector = new PrerenderEventCollector();
-  const promise = new Promise(async (resolve, reject) => {
+  const prerenderEventCollector =
+      new PrerenderEventCollector({customizedReadyToActivate: true});
+  const promise = new Promise((resolve, reject) => {
     try {
       const worker = new Worker('dedicated-worker.js');
       worker.addEventListener('message', _ => resolve());
@@ -26,6 +27,7 @@
     }
   });
   prerenderEventCollector.start(promise, 'worker construction');
+  prerenderEventCollector.readyToActivate();
 }
 
 </script>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/dedicated-worker.js b/third_party/blink/web_tests/wpt_internal/prerender/resources/dedicated-worker.js
index 00d716d..d8029556 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/dedicated-worker.js
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/dedicated-worker.js
@@ -1 +1 @@
-postMessage('loaded');
+postMessage('readyToActivate');
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/deferred-promise-utils.js b/third_party/blink/web_tests/wpt_internal/prerender/resources/deferred-promise-utils.js
index e295727..55002888 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/deferred-promise-utils.js
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/deferred-promise-utils.js
@@ -11,7 +11,7 @@
  *  On prerendering page, prerender-promise-test.html?prerendering:
  *    const promise = {a promise that should be deferred during prerendering};
  *    const prerenderEventCollector =
- *        new PrerenderEventCollector({supportReadyToActivate: bool});
+ *        new PrerenderEventCollector({customizedReadyToActivate: bool});
  *    prerenderEventCollector.start(promise, {promise name});
  *
  *  On the initiator page, prerender-promise-test.html:
@@ -26,13 +26,13 @@
 // 3. the promise passed to start() is resolved.
 // 4. addEvent() is called manually.
 class PrerenderEventCollector {
-  constructor(options = { supportReadyToActivate: false }) {
+  constructor(options = { customizedReadyToActivate: false }) {
     // Used to communicate with the initiator page.
     this.prerenderChannel_ = new BroadcastChannel('prerender-channel');
     // Used to communicate with the main test page.
     this.testChannel_ = new BroadcastChannel('test-channel');
     this.eventsSeen_ = [];
-    this.supportReadyToActivate = options.supportReadyToActivate;
+    this.customizedReadyToActivate_ = options.customizedReadyToActivate;
   }
 
   // Adds an event to `eventsSeen_` along with the prerendering state of the
@@ -76,7 +76,7 @@
       this.addEvent('prerendering change');
     });
 
-    if (!this.supportReadyToActivate_) {
+    if (!this.customizedReadyToActivate_) {
       // TODO(crbug.com/1201119): Can we remove this 'load' event listener
       // after all tests send 'readyToActivate' signal explicitly?
       window.addEventListener('load', () => {
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/notification.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/notification.html
index f48af99..f9502dd 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/notification.html
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/notification.html
@@ -18,8 +18,8 @@
   const testChannel = new BroadcastChannel('test-channel');
 
   window.addEventListener('load', () => {
-    // Inform the initiator page that this page was loaded.
-    prerenderChannel.postMessage('loaded');
+    // Inform the initiator page that this page is ready to be activated.
+    prerenderChannel.postMessage('readyToActivate');
     prerenderChannel.close();
   });
 
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/push.https.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/push.https.html
index 6607a5e..5f2f5d23 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/push.https.html
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/push.https.html
@@ -17,7 +17,7 @@
 } else {
   async function loadPrerenderPage() {
     const prerenderEventCollector =
-        new PrerenderEventCollector({supportReadyToActivate: true});
+        new PrerenderEventCollector({customizedReadyToActivate: true});
     const scope = `resources/`;
     const registration = await navigator.serviceWorker.getRegistration(scope);
     const subscribe_promise = registration.pushManager.subscribe({
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/utils.js b/third_party/blink/web_tests/wpt_internal/prerender/resources/utils.js
index 5797f3a..fc04bd71 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/utils.js
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/utils.js
@@ -50,7 +50,7 @@
 }
 
 // Loads the initiator page, and navigates to the prerendered page after it
-// receives a message('loaded' or 'readyToActivate' message).
+// receives the 'readyToActivate' message.
 function loadInitiatorPage() {
   // Used to communicate with the prerendering page.
   const prerenderChannel = new BroadcastChannel('prerender-channel');
@@ -58,15 +58,13 @@
     prerenderChannel.close();
   });
 
-  // We need to wait for 'loaded' or 'readyToActivate' message before navigation
+  // We need to wait for the 'readyToActivate' message before navigation
   // since the prerendering implementation in Chromium can only activate if the
   // response for the prerendering navigation has already been received and the
   // prerendering document was created.
-  // TODO(crbug.com/1201119): The tests that use 'loaded' should be migrated to
-  // use 'readyToActivate'.
   const readyToActivate = new Promise((resolve, reject) => {
     prerenderChannel.addEventListener('message', e => {
-      if (e.data != 'loaded' && e.data != 'readyToActivate')
+      if (e.data != 'readyToActivate')
         reject(`The initiator page receives an unsupported message: ${e.data}`);
       resolve(e.data);
     });
@@ -74,13 +72,12 @@
 
   const url = new URL(document.URL);
   url.searchParams.append('prerendering', '');
-  // Prerender a page that notifies the initiator page of page load via
-  // `loaded`.
+  // Prerender a page that notifies the initiator page of the page's ready to be
+  // activated via the 'readyToActivate'.
   startPrerendering(url.toString());
 
   // Navigate to the prerendered page after being informed.
   readyToActivate.then(() => {
-    // navigate to the prerenderered page.
     window.location = url.toString();
   }).catch(e => {
     const testChannel = new BroadcastChannel('test-channel');
diff --git a/third_party/closure_compiler/compiler.py b/third_party/closure_compiler/compiler.py
index 75690ceb..f09b7dd7a 100755
--- a/third_party/closure_compiler/compiler.py
+++ b/third_party/closure_compiler/compiler.py
@@ -60,7 +60,8 @@
     self._log_debug("Running jar: %s" % shell_command)
 
     devnull = open(os.devnull, "w")
-    kwargs = {"stdout": devnull, "stderr": subprocess.PIPE, "shell": True}
-    process = subprocess.Popen(shell_command, **kwargs)
+    process = subprocess.Popen(shell_command, universal_newlines=True,
+                               shell=True, stdout=devnull,
+                               stderr=subprocess.PIPE)
     _, stderr = process.communicate()
     return process.returncode, stderr
diff --git a/third_party/closure_compiler/externs/file_manager_private.js b/third_party/closure_compiler/externs/file_manager_private.js
index 1741d19..512f5c8 100644
--- a/third_party/closure_compiler/externs/file_manager_private.js
+++ b/third_party/closure_compiler/externs/file_manager_private.js
@@ -107,10 +107,12 @@
 };
 
 /** @enum {string} */
-chrome.fileManagerPrivate.CopyProgressStatusType = {
-  BEGIN_COPY_ENTRY: 'begin_copy_entry',
-  END_COPY_ENTRY: 'end_copy_entry',
+chrome.fileManagerPrivate.CopyOrMoveProgressStatusType = {
+  BEGIN: 'begin',
   PROGRESS: 'progress',
+  END_COPY: 'end_copy',
+  END_MOVE: 'end_move',
+  END_REMOVE_SOURCE: 'end_remove_source',
   SUCCESS: 'success',
   ERROR: 'error',
 };
@@ -432,14 +434,14 @@
 
 /**
  * @typedef {{
- *   type: !chrome.fileManagerPrivate.CopyProgressStatusType,
+ *   type: !chrome.fileManagerPrivate.CopyOrMoveProgressStatusType,
  *   sourceUrl: (string|undefined),
  *   destinationUrl: (string|undefined),
  *   size: (number|undefined),
  *   error: (string|undefined)
  * }}
  */
-chrome.fileManagerPrivate.CopyProgressStatus;
+chrome.fileManagerPrivate.CopyOrMoveProgressStatus;
 
 /**
  * @typedef {{
diff --git a/third_party/zlib/google/zip.cc b/third_party/zlib/google/zip.cc
index 907e5da..c71c738 100644
--- a/third_party/zlib/google/zip.cc
+++ b/third_party/zlib/google/zip.cc
@@ -4,7 +4,7 @@
 
 #include "third_party/zlib/google/zip.h"
 
-#include <list>
+#include <queue>
 #include <string>
 #include <vector>
 
@@ -100,76 +100,67 @@
 
 }  // namespace
 
-ZipParams::ZipParams(const base::FilePath& src_dir,
-                     const base::FilePath& dest_file)
-    : src_dir_(src_dir),
-      dest_file_(dest_file),
-      file_accessor_(new DirectFileAccessor(src_dir)) {}
-
-#if defined(OS_POSIX)
-// Does not take ownership of |fd|.
-ZipParams::ZipParams(const base::FilePath& src_dir, int dest_fd)
-    : src_dir_(src_dir),
-      dest_fd_(dest_fd),
-      file_accessor_(new DirectFileAccessor(src_dir)) {}
-#endif
+std::ostream& operator<<(std::ostream& out, const Progress& progress) {
+  return out << progress.bytes << " bytes, " << progress.files << " files, "
+             << progress.directories << " dirs";
+}
 
 bool Zip(const ZipParams& params) {
-  // Using a pointer to avoid copies of a potentially large array.
-  const std::vector<base::FilePath>* files_to_add = &params.files_to_zip();
+  DirectFileAccessor default_accessor(params.src_dir);
+  FileAccessor* const file_accessor = params.file_accessor ?: &default_accessor;
+
+  Paths files_to_add = params.src_files;
+
   std::vector<base::FilePath> all_files;
-  if (files_to_add->empty()) {
-    // Include all files from the src_dir (modulo the src_dir itself and
-    // filtered and hidden files).
+  if (files_to_add.empty()) {
+    // Perform a Breadth First Search (BFS) of the source tree. Note that the
+    // BFS order might not be optimal when storing files in a ZIP (either for
+    // the storing side, or for the program that will extract this ZIP).
+    for (std::queue<base::FilePath> q({params.src_dir}); !q.empty(); q.pop()) {
+      for (FileAccessor::DirectoryContentEntry& entry :
+           file_accessor->ListDirectoryContent(q.front())) {
+        // Skip hidden and filtered files.
+        if ((!params.include_hidden_files && IsHiddenFile(entry.path)) ||
+            (params.filter_callback && !params.filter_callback.Run(entry.path)))
+          continue;
 
-    files_to_add = &all_files;
-    // Using a list so we can call push_back while iterating.
-    std::list<FileAccessor::DirectoryContentEntry> entries;
-    entries.push_back(FileAccessor::DirectoryContentEntry(
-        params.src_dir(), true /* is directory*/));
-    const FilterCallback& filter_callback = params.filter_callback();
-    for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
-      const base::FilePath& entry_path = iter->path;
-      if (iter != entries.begin() &&  // Don't filter the root dir.
-          ((!params.include_hidden_files() && IsHiddenFile(entry_path)) ||
-           (filter_callback && !filter_callback.Run(entry_path)))) {
-        continue;
-      }
-
-      if (iter != entries.begin()) {  // Exclude the root dir from the ZIP file.
-        // Make the path relative for AddEntryToZip.
-        base::FilePath relative_path;
-        bool success =
-            params.src_dir().AppendRelativePath(entry_path, &relative_path);
+        // Store relative path.
+        all_files.emplace_back();
+        const bool success =
+            params.src_dir.AppendRelativePath(entry.path, &all_files.back());
         DCHECK(success);
-        all_files.push_back(relative_path);
-      }
 
-      if (iter->is_directory) {
-        std::vector<FileAccessor::DirectoryContentEntry> subentries =
-            params.file_accessor()->ListDirectoryContent(entry_path);
-        entries.insert(entries.end(), subentries.begin(), subentries.end());
+        if (entry.is_directory)
+          q.push(std::move(entry.path));
       }
     }
+
+    files_to_add = all_files;
   }
 
   std::unique_ptr<internal::ZipWriter> zip_writer;
+
 #if defined(OS_POSIX)
-  if (params.dest_fd() != base::kInvalidPlatformFile) {
-    DCHECK(params.dest_file().empty());
+  if (params.dest_fd != base::kInvalidPlatformFile) {
+    DCHECK(params.dest_file.empty());
     zip_writer = internal::ZipWriter::CreateWithFd(
-        params.dest_fd(), params.src_dir(), params.file_accessor());
+        params.dest_fd, params.src_dir, file_accessor);
     if (!zip_writer)
       return false;
   }
 #endif
+
   if (!zip_writer) {
-    zip_writer = internal::ZipWriter::Create(
-        params.dest_file(), params.src_dir(), params.file_accessor());
+    zip_writer = internal::ZipWriter::Create(params.dest_file, params.src_dir,
+                                             file_accessor);
     if (!zip_writer)
       return false;
   }
-  return zip_writer->WriteEntries(*files_to_add);
+
+  zip_writer->SetProgressCallback(params.progress_callback,
+                                  params.progress_period);
+
+  return zip_writer->WriteEntries(files_to_add);
 }
 
 bool Unzip(const base::FilePath& src_file, const base::FilePath& dest_dir) {
@@ -179,7 +170,7 @@
 
 bool UnzipWithFilterCallback(const base::FilePath& src_file,
                              const base::FilePath& dest_dir,
-                             const FilterCallback& filter_cb,
+                             FilterCallback filter_cb,
                              bool log_skipped_files) {
   base::File file(src_file, base::File::FLAG_OPEN | base::File::FLAG_READ);
   if (!file.IsValid()) {
@@ -189,14 +180,14 @@
   return UnzipWithFilterAndWriters(
       file.GetPlatformFile(),
       base::BindRepeating(&CreateFilePathWriterDelegate, dest_dir),
-      base::BindRepeating(&CreateDirectory, dest_dir), filter_cb,
+      base::BindRepeating(&CreateDirectory, dest_dir), std::move(filter_cb),
       log_skipped_files);
 }
 
 bool UnzipWithFilterAndWriters(const base::PlatformFile& src_file,
-                               const WriterFactory& writer_factory,
-                               const DirectoryCreator& directory_creator,
-                               const FilterCallback& filter_cb,
+                               WriterFactory writer_factory,
+                               DirectoryCreator directory_creator,
+                               FilterCallback filter_cb,
                                bool log_skipped_files) {
   ZipReader reader;
   if (!reader.OpenFromPlatformFile(src_file)) {
@@ -239,14 +230,15 @@
 
 bool ZipWithFilterCallback(const base::FilePath& src_dir,
                            const base::FilePath& dest_file,
-                           const FilterCallback& filter_cb) {
+                           FilterCallback filter_cb) {
   DCHECK(base::DirectoryExists(src_dir));
-  ZipParams params(src_dir, dest_file);
-  params.set_filter_callback(filter_cb);
-  return Zip(params);
+  return Zip({.src_dir = src_dir,
+              .dest_file = dest_file,
+              .filter_callback = std::move(filter_cb)});
 }
 
-bool Zip(const base::FilePath& src_dir, const base::FilePath& dest_file,
+bool Zip(const base::FilePath& src_dir,
+         const base::FilePath& dest_file,
          bool include_hidden_files) {
   if (include_hidden_files) {
     return ZipWithFilterCallback(src_dir, dest_file,
@@ -259,12 +251,12 @@
 
 #if defined(OS_POSIX)
 bool ZipFiles(const base::FilePath& src_dir,
-              const std::vector<base::FilePath>& src_relative_paths,
+              Paths src_relative_paths,
               int dest_fd) {
   DCHECK(base::DirectoryExists(src_dir));
-  ZipParams params(src_dir, dest_fd);
-  params.set_files_to_zip(src_relative_paths);
-  return Zip(params);
+  return Zip({.src_dir = src_dir,
+              .dest_fd = dest_fd,
+              .src_files = src_relative_paths});
 }
 #endif  // defined(OS_POSIX)
 
diff --git a/third_party/zlib/google/zip.h b/third_party/zlib/google/zip.h
index 4f64a8ac..2c2ef7ae8 100644
--- a/third_party/zlib/google/zip.h
+++ b/third_party/zlib/google/zip.h
@@ -5,9 +5,13 @@
 #ifndef THIRD_PARTY_ZLIB_GOOGLE_ZIP_H_
 #define THIRD_PARTY_ZLIB_GOOGLE_ZIP_H_
 
+#include <cstdint>
+#include <ostream>
+#include <utility>
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/span.h"
 #include "base/files/file_path.h"
 #include "base/files/platform_file.h"
 #include "base/time/time.h"
@@ -48,72 +52,75 @@
   virtual base::Time GetLastModifiedTime(const base::FilePath& path) = 0;
 };
 
-class ZipParams {
- public:
-  ZipParams(const base::FilePath& src_dir, const base::FilePath& dest_file);
-#if defined(OS_POSIX)
-  // Does not take ownership of |dest_fd|.
-  ZipParams(const base::FilePath& src_dir, int dest_fd);
+// Progress of a ZIP creation operation.
+struct Progress {
+  // Total number of bytes read from files getting zipped so far.
+  std::int64_t bytes = 0;
 
-  int dest_fd() const { return dest_fd_; }
+  // Number of file entries added to the ZIP so far.
+  // A file entry is added after its bytes have been processed.
+  int files = 0;
+
+  // Number of directory entries added to the ZIP so far.
+  // A directory entry is added before items in it.
+  int directories = 0;
+};
+
+// Prints Progress to output stream.
+std::ostream& operator<<(std::ostream& out, const Progress& progress);
+
+// Callback reporting the progress of a ZIP creation operation.
+//
+// This callback returns a boolean indicating whether the ZIP creation operation
+// should continue. If it returns false once, then the ZIP creation operation is
+// immediately cancelled and the callback won't be called again.
+using ProgressCallback = base::RepeatingCallback<bool(const Progress&)>;
+
+using FilterCallback = base::RepeatingCallback<bool(const base::FilePath&)>;
+
+using Paths = base::span<const base::FilePath>;
+
+// ZIP creation parameters and options.
+struct ZipParams {
+  // Source directory.
+  base::FilePath src_dir;
+
+  // Destination file path.
+  // Either dest_file or dest_fd should be set, but not both.
+  base::FilePath dest_file;
+
+#if defined(OS_POSIX)
+  // Destination file passed a file descriptor.
+  // Either dest_file or dest_fd should be set, but not both.
+  int dest_fd = base::kInvalidPlatformFile;
 #endif
 
-  const base::FilePath& src_dir() const { return src_dir_; }
-
-  const base::FilePath& dest_file() const { return dest_file_; }
-
-  // Restricts the files actually zipped to the paths listed in
-  // |src_relative_paths|. They must be relative to the |src_dir| passed in the
-  // constructor and will be used as the file names in the created zip file. All
-  // source paths must be under |src_dir| in the file system hierarchy.
-  void set_files_to_zip(const std::vector<base::FilePath>& src_relative_paths) {
-    src_files_ = src_relative_paths;
-  }
-  const std::vector<base::FilePath>& files_to_zip() const { return src_files_; }
-
-  using FilterCallback = base::RepeatingCallback<bool(const base::FilePath&)>;
-  void set_filter_callback(FilterCallback filter_callback) {
-    filter_callback_ = filter_callback;
-  }
-  const FilterCallback& filter_callback() const { return filter_callback_; }
-
-  void set_include_hidden_files(bool include_hidden_files) {
-    include_hidden_files_ = include_hidden_files;
-  }
-  bool include_hidden_files() const { return include_hidden_files_; }
-
-  // Sets a custom file accessor for file operations. Default is to directly
-  // access the files (with fopen and the rest).
-  // Useful in cases where running in a sandbox process and file access has to
-  // go through IPC, for example.
-  void set_file_accessor(std::unique_ptr<FileAccessor> file_accessor) {
-    file_accessor_ = std::move(file_accessor);
-  }
-  FileAccessor* file_accessor() const { return file_accessor_.get(); }
-
- private:
-  base::FilePath src_dir_;
-
-  base::FilePath dest_file_;
-#if defined(OS_POSIX)
-  int dest_fd_ = base::kInvalidPlatformFile;
-#endif
-
-  // The relative paths to the files that should be included in the zip file. If
-  // this is empty, all files in |src_dir_| are included.
-  std::vector<base::FilePath> src_files_;
+  // The relative paths to the files that should be included in the ZIP file. If
+  // this is empty, all files in |src_dir| are included.
+  //
+  // These paths must be relative to |src_dir| and will be used as the file
+  // names in the created zip file. All files must be under |src_dir| in the
+  // file system hierarchy.
+  Paths src_files;
 
   // Filter used to exclude files from the ZIP file. Only effective when
-  // |src_files_| is empty.
-  FilterCallback filter_callback_;
+  // |src_files| is empty.
+  FilterCallback filter_callback;
+
+  // Optional progress reporting callback.
+  ProgressCallback progress_callback;
+
+  // Progress reporting period. The final callback is always called when the ZIP
+  // creation operation completes.
+  base::TimeDelta progress_period;
 
   // Whether hidden files should be included in the ZIP file. Only effective
-  // when |src_files_| is empty.
-  bool include_hidden_files_ = true;
+  // when |src_files| is empty.
+  bool include_hidden_files = true;
 
-  // Abstraction around file system access used to read files. An implementation
-  // that accesses files directly is provided by default.
-  std::unique_ptr<FileAccessor> file_accessor_;
+  // Abstraction around file system access used to read files. If left null, an
+  // implementation that accesses files directly is used.
+  FileAccessor* file_accessor = nullptr;  // Not owned
 };
 
 // Zip files specified into a ZIP archives. The source files and ZIP destination
@@ -125,15 +132,15 @@
 // of src_dir will be at the root level of the created zip. For each file in
 // src_dir, include it only if the callback |filter_cb| returns true. Otherwise
 // omit it.
-using FilterCallback = base::RepeatingCallback<bool(const base::FilePath&)>;
 bool ZipWithFilterCallback(const base::FilePath& src_dir,
                            const base::FilePath& dest_file,
-                           const FilterCallback& filter_cb);
+                           FilterCallback filter_cb);
 
 // Convenience method for callers who don't need to set up the filter callback.
 // If |include_hidden_files| is true, files starting with "." are included.
 // Otherwise they are omitted.
-bool Zip(const base::FilePath& src_dir, const base::FilePath& dest_file,
+bool Zip(const base::FilePath& src_dir,
+         const base::FilePath& dest_file,
          bool include_hidden_files);
 
 #if defined(OS_POSIX)
@@ -143,7 +150,7 @@
 // file names in the created zip file. All source paths must be under |src_dir|
 // in the file system hierarchy.
 bool ZipFiles(const base::FilePath& src_dir,
-              const std::vector<base::FilePath>& src_relative_paths,
+              Paths src_relative_paths,
               int dest_fd);
 #endif  // defined(OS_POSIX)
 
@@ -152,10 +159,9 @@
 // returns true. Otherwise omit it.
 // If |log_skipped_files| is true, files skipped during extraction are printed
 // to debug log.
-using FilterCallback = base::RepeatingCallback<bool(const base::FilePath&)>;
 bool UnzipWithFilterCallback(const base::FilePath& zip_file,
                              const base::FilePath& dest_dir,
-                             const FilterCallback& filter_cb,
+                             FilterCallback filter_cb,
                              bool log_skipped_files);
 
 // Unzip the contents of zip_file, using the writers provided by writer_factory.
@@ -168,9 +174,9 @@
     WriterFactory;
 typedef base::RepeatingCallback<bool(const base::FilePath&)> DirectoryCreator;
 bool UnzipWithFilterAndWriters(const base::PlatformFile& zip_file,
-                               const WriterFactory& writer_factory,
-                               const DirectoryCreator& directory_creator,
-                               const FilterCallback& filter_cb,
+                               WriterFactory writer_factory,
+                               DirectoryCreator directory_creator,
+                               FilterCallback filter_cb,
                                bool log_skipped_files);
 
 // Unzip the contents of zip_file into dest_dir.
diff --git a/third_party/zlib/google/zip_unittest.cc b/third_party/zlib/google/zip_unittest.cc
index 10f2ef7..8a53ac4 100644
--- a/third_party/zlib/google/zip_unittest.cc
+++ b/third_party/zlib/google/zip_unittest.cc
@@ -535,8 +535,11 @@
 TEST_F(ZipTest, ZipWithFileAccessor) {
   base::FilePath zip_file;
   ASSERT_TRUE(base::CreateTemporaryFile(&zip_file));
-  zip::ZipParams params(base::FilePath(FILE_PATH_LITERAL("/test")), zip_file);
-  params.set_file_accessor(std::make_unique<VirtualFileSystem>());
+  VirtualFileSystem file_accessor;
+  const zip::ZipParams params{
+      .src_dir = base::FilePath(FILE_PATH_LITERAL("/test")),
+      .dest_file = zip_file,
+      .file_accessor = &file_accessor};
   ASSERT_TRUE(zip::Zip(params));
 
   base::ScopedTempDir scoped_temp_dir;
diff --git a/third_party/zlib/google/zip_writer.cc b/third_party/zlib/google/zip_writer.cc
index c151cc8b..9870147 100644
--- a/third_party/zlib/google/zip_writer.cc
+++ b/third_party/zlib/google/zip_writer.cc
@@ -12,9 +12,25 @@
 namespace zip {
 namespace internal {
 
+bool ZipWriter::ShouldContinue() {
+  if (progress_callback_) {
+    const base::TimeTicks now = base::TimeTicks::Now();
+    if (next_progress_report_time_ <= now) {
+      next_progress_report_time_ = now + progress_period_;
+      if (!progress_callback_.Run(progress_)) {
+        LOG(ERROR) << "Cancelling ZIP creation";
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
 bool ZipWriter::AddFileContent(const base::FilePath& path, base::File file) {
   char buf[zip::internal::kZipBufSize];
-  while (true) {
+
+  while (ShouldContinue()) {
     const int num_bytes =
         file.ReadAtCurrentPos(buf, zip::internal::kZipBufSize);
 
@@ -30,7 +46,11 @@
       DLOG(ERROR) << "Cannot write data from file '" << path << "' to ZIP";
       return false;
     }
+
+    progress_.bytes += num_bytes;
   }
+
+  return false;
 }
 
 bool ZipWriter::OpenNewFileEntry(const base::FilePath& path,
@@ -58,17 +78,16 @@
   if (!OpenNewFileEntry(path, /*is_directory=*/false, file_info.last_modified))
     return false;
 
-  bool success = AddFileContent(path, std::move(file));
-  if (!CloseNewFileEntry())
-    return false;
-
-  return success;
+  const bool success = AddFileContent(path, std::move(file));
+  progress_.files++;
+  return CloseNewFileEntry() && success;
 }
 
 bool ZipWriter::AddDirectoryEntry(const base::FilePath& path,
                                   base::Time last_modified) {
+  progress_.directories++;
   return OpenNewFileEntry(path, /*is_directory=*/true, last_modified) &&
-         CloseNewFileEntry();
+         CloseNewFileEntry() && ShouldContinue();
 }
 
 #if defined(OS_POSIX)
@@ -126,6 +145,14 @@
 bool ZipWriter::Close() {
   const bool success = zipClose(zip_file_, nullptr) == ZIP_OK;
   zip_file_ = nullptr;
+
+  // Call the progress callback one last time with the final progress status.
+  //
+  // We don't care about the callback return value (cancellation request), since
+  // we're done anyway.
+  if (progress_callback_)
+    progress_callback_.Run(progress_);
+
   return success;
 }
 
diff --git a/third_party/zlib/google/zip_writer.h b/third_party/zlib/google/zip_writer.h
index 0dc4c6c..489984f 100644
--- a/third_party/zlib/google/zip_writer.h
+++ b/third_party/zlib/google/zip_writer.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/containers/span.h"
 #include "base/files/file_path.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -45,7 +44,13 @@
                                            FileAccessor* file_accessor);
   ~ZipWriter();
 
-  using Paths = base::span<const base::FilePath>;
+  // Sets the optional progress callback. The callback is called once for each
+  // time |period|. The final callback is always called when the ZIP operation
+  // completes.
+  void SetProgressCallback(ProgressCallback callback, base::TimeDelta period) {
+    progress_callback_ = std::move(callback);
+    progress_period_ = std::move(period);
+  }
 
   // Writes the files at |paths| to the ZIP file and closes this ZIP file.
   // The file paths must be relative to |root_dir| specified in the
@@ -59,6 +64,10 @@
             const base::FilePath& root_dir,
             FileAccessor* file_accessor);
 
+  // Regularly called during processing to check whether zipping should continue
+  // or should be cancelled.
+  bool ShouldContinue();
+
   // Adds the files at |paths| to the ZIP file. These FilePaths must be relative
   // to |root_dir| specified in the Create method.
   bool AddEntries(Paths paths);
@@ -94,6 +103,18 @@
   // Abstraction over file access methods used to read files.
   FileAccessor* file_accessor_;
 
+  // Progress stats.
+  Progress progress_;
+
+  // Optional progress callback.
+  ProgressCallback progress_callback_;
+
+  // Optional progress reporting period.
+  base::TimeDelta progress_period_;
+
+  // Next time to report progress.
+  base::TimeTicks next_progress_report_time_ = base::TimeTicks::Now();
+
   DISALLOW_COPY_AND_ASSIGN(ZipWriter);
 };
 
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 7a98865..f7b0a6f 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -45849,6 +45849,7 @@
   <int value="-950384924" label="OmniboxDisableInstantExtendedLimit:enabled"/>
   <int value="-949178861" label="enable-new-avatar-menu"/>
   <int value="-948930847" label="EnableOopPrintDrivers:enabled"/>
+  <int value="-948256052" label="EnableInputInDiagnosticsApp:enabled"/>
   <int value="-946366838" label="MetricsSettingsAndroid:enabled"/>
   <int value="-945806012" label="DownloadsUi:enabled"/>
   <int value="-943304570" label="PaintHolding:enabled"/>
@@ -48584,6 +48585,7 @@
   <int value="1461581256" label="MovablePartialScreenshot:enabled"/>
   <int value="1463230871" label="ArcEnableUsap:enabled"/>
   <int value="1464028544" label="WinUseHybridSpellChecker:disabled"/>
+  <int value="1464053185" label="EnableInputInDiagnosticsApp:disabled"/>
   <int value="1464610065" label="TabbedAppOverflowMenuRegroup:disabled"/>
   <int value="1465624446" label="disable-zero-copy"/>
   <int value="1466380480" label="enable-device-discovery-notifications"/>
diff --git a/tools/metrics/histograms/histograms_xml/android/histograms.xml b/tools/metrics/histograms/histograms_xml/android/histograms.xml
index 21521c2..4cdd1ac 100644
--- a/tools/metrics/histograms/histograms_xml/android/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/android/histograms.xml
@@ -2327,6 +2327,9 @@
 
 <histogram name="Android.ShouldDestroyIncognitoProfileOnStartup"
     units="Boolean" expires_after="2021-10-10">
+  <obsolete>
+    Removed as of 05/2021.
+  </obsolete>
   <owner>rhalavati@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/variations/histograms.xml b/tools/metrics/histograms/histograms_xml/variations/histograms.xml
index cd4b87c3..03b1173 100644
--- a/tools/metrics/histograms/histograms_xml/variations/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/variations/histograms.xml
@@ -307,26 +307,28 @@
 </histogram>
 
 <histogram name="Variations.SafeMode.Streak.Crashes" units="crashes"
-    expires_after="2021-10-25">
+    expires_after="2022-05-09">
   <owner>isherman@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
-    The number of consecutive crashes observed by the VariationsService, without
-    a single intervening successful seed fetch. Recorded during Chrome startup,
-    when the VariationsService is created.
+    The number of consecutive crashes observed by the VariationsService without
+    a single intervening successful seed fetch. Recorded during Chrome startup
+    when the MetricsStateManager's CleanExitBeacon is created.
+
+    Prior to M92, this was recorded when the SafeSeedManager was created.
   </summary>
 </histogram>
 
 <histogram name="Variations.SafeMode.Streak.FetchFailures" units="failures"
-    expires_after="2021-08-22">
+    expires_after="2022-05-09">
   <owner>isherman@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
     The number of consecutive failed attempts to fetch a new seed by the
-    VariationsService. Recorded during Chrome startup, when the
-    VariationsService is created.
+    VariationsService. Recorded during Chrome startup when the SafeSeedManager
+    is created.
   </summary>
 </histogram>
 
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index 9134a42..819002e 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -69,11 +69,6 @@
 # Benchmark: blink_perf.shadow_dom
 crbug.com/702319 [ android-nexus-5x ] blink_perf.shadow_dom/* [ Skip ]
 
-# Benchmark: desktop_ui
-crbug.com/1205850 [ win ] desktop_ui/tab_search:measure_memory* [ Skip ]
-crbug.com/1205850 [ mac ] desktop_ui/tab_search:measure_memory* [ Skip ]
-crbug.com/1205850 [ linux ] desktop_ui/tab_search:measure_memory* [ Skip ]
-
 # Benchmark: dromaeo
 crbug.com/1050065 [ android-pixel-2 ] dromaeo/http://dromaeo.com?dom-modify [ Skip ]
 
diff --git a/tools/v8_context_snapshot/v8_context_snapshot_generator.cc b/tools/v8_context_snapshot/v8_context_snapshot_generator.cc
index 3803ef8..7743ae11 100644
--- a/tools/v8_context_snapshot/v8_context_snapshot_generator.cc
+++ b/tools/v8_context_snapshot/v8_context_snapshot_generator.cc
@@ -12,6 +12,7 @@
 #include "gin/v8_initializer.h"
 #include "mojo/core/embedder/embedder.h"
 #include "mojo/public/cpp/bindings/binder_map.h"
+#include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/web/blink.h"
 #include "third_party/blink/public/web/web_v8_context_snapshot.h"
 #include "v8/include/v8.h"
diff --git a/ui/file_manager/BUILD.gn b/ui/file_manager/BUILD.gn
index ab2966f..68245de7 100644
--- a/ui/file_manager/BUILD.gn
+++ b/ui/file_manager/BUILD.gn
@@ -84,6 +84,7 @@
     "audio_player/js/main.m.js",
     "audio_player/js/main_background.m.js",
     "file_manager/background/js/main_background.m.js",
+    "audio_player/elements/track_info_panel.js",
     "file_manager/foreground/js/deferred_elements.m.js",
     "file_manager/foreground/js/elements_importer.m.js",
     "file_manager/foreground/js/main.m.js",
@@ -118,7 +119,6 @@
     "audio_player/js/audio_player.m.js",
     "audio_player/js/metadata_worker.m.js",
     "audio_player/elements/audio_player.m.js",
-    "audio_player/elements/track_info_panel.m.js",
     "audio_player/elements/track_list.m.js",
     "audio_player/elements/control_panel.m.js",
     "audio_player/elements/repeat_button.m.js",
diff --git a/ui/file_manager/audio_player/elements/BUILD.gn b/ui/file_manager/audio_player/elements/BUILD.gn
index 24316d2f..c3afd60f 100644
--- a/ui/file_manager/audio_player/elements/BUILD.gn
+++ b/ui/file_manager/audio_player/elements/BUILD.gn
@@ -10,7 +10,6 @@
     "//ui/file_manager/audio_player/elements:audio_player_module",
     "//ui/file_manager/audio_player/elements:control_panel_module",
     "//ui/file_manager/audio_player/elements:repeat_button_module",
-    "//ui/file_manager/audio_player/elements:track_info_panel_module",
     "//ui/file_manager/audio_player/elements:track_list_module",
   ]
 }
@@ -28,7 +27,6 @@
     ":audio_player",
     ":control_panel",
     ":repeat_button",
-    ":track_info_panel",
     ":track_list",
   ]
 }
@@ -36,7 +34,6 @@
 js_library("audio_player") {
   deps = [
     ":control_panel",
-    ":track_info_panel",
     ":track_list",
   ]
 }
@@ -60,7 +57,7 @@
   ]
   deps = [
     ":control_panel.m",
-    ":track_info_panel.m",
+    ":track_info_panel",
     ":track_list.m",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
   ]
@@ -106,24 +103,10 @@
 }
 
 js_library("track_info_panel") {
-}
-
-polymer_modulizer("track_info_panel") {
-  js_file = "track_info_panel.js"
-  html_file = "track_info_panel.html"
-  html_type = "dom-module"
-  preserve_url_scheme = true
-}
-
-js_library("track_info_panel.m") {
-  sources = [
-    "$root_gen_dir/ui/file_manager/audio_player/elements/track_info_panel.m.js",
-  ]
   deps = [
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_elements/cr_button:cr_button.m",
   ]
-  extra_deps = [ ":track_info_panel_module" ]
 }
 
 js_library("track_list") {
@@ -183,7 +166,7 @@
     ":audio_player.m",
     ":control_panel.m",
     ":repeat_button.m",
-    ":track_info_panel.m",
+    ":track_info_panel",
     ":track_list.m",
   ]
 }
diff --git a/ui/file_manager/audio_player/elements/track_info_panel.html b/ui/file_manager/audio_player/elements/track_info_panel.html
deleted file mode 100644
index 4615fd1..0000000
--- a/ui/file_manager/audio_player/elements/track_info_panel.html
+++ /dev/null
@@ -1,180 +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.
-  -->
-
-<link rel="import" href="chrome://resources/html/polymer.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-
-<dom-module id="track-info-panel">
-  <template>
-    <style>
-      :host {
-        align-items: center;
-        background: rgb(245, 245, 245);
-        color: rgb(51, 51, 51);
-        cursor: default;
-        font-size: 10pt;
-        overflow: hidden;
-      }
-
-      /* Track item. */
-      .track {
-        align-items: center;
-        background-color: rgba(255, 255, 255, 1.0);
-        display: flex;
-        height: 48px;
-        justify-content: space-between;
-        width: 100%;
-      }
-
-      :host([expanded]) .track {
-        background-color: rgba(255, 255, 255, 0.9);
-        bottom: 0;
-        position: absolute;
-      }
-
-      /* artwork icon(expanded) */
-      .track .icon-wrapper {
-        flex: none;
-        height: 48px;
-        width: 48px;
-      }
-
-      :host([expanded]) .icon {
-        visibility: hidden;
-      }
-
-      :host(:not([expanded])) .icon {
-        background-position: center;
-        background-repeat: no-repeat;
-        background-size: contain;
-        height: 48px;
-        pointer-events: none;
-        position: absolute;
-        width: 48px;
-      }
-
-      /* artwork icon(expanded) */
-
-      .track-wrapper {
-        background-color: rgb(32, 32, 34);
-        position: relative;
-      }
-
-      :host(:not([artwork-available])[expanded]) .track-wrapper {
-        height: 320px;
-        position: relative;
-        width: 100%;
-      }
-
-      .icon-expanded {
-        background-size: 0 0;
-      }
-
-      :host(:not([expanded])) .icon-unavailable-expanded {
-        background-size: 0 0;
-      }
-
-      :host(:not([artwork-available])[expanded]) .icon-unavailable-expanded {
-        background-image: -webkit-image-set(
-            url(../assets/100/player_no_artwork.png) 1x,
-            url(../assets/200/player_no_artwork.png) 2x);
-        background-position: center;
-        background-repeat: no-repeat;
-        height: calc(320px - 48px);
-        margin-left: auto;
-        margin-right: auto;
-        width: 320px;
-      }
-
-      :host([artwork-available][expanded]) .icon-expanded {
-        background-position: center;
-        background-repeat: no-repeat;
-        background-size: contain;
-        height: 320px;
-        margin-left: auto;
-        margin-right: auto;
-        width: 320px;
-      }
-
-      /* expand icon. */
-      .track .expand {
-        --ink-color: rgb(51, 51, 51);
-        background-color: transparent;
-        background-position: center;
-        background-repeat: no-repeat;
-        border: none;
-        border-radius: 0;
-        box-shadow: none;
-        flex: none;
-        height: 48px;
-        width: 48px;
-      }
-
-      :host-context(.focus-outline-visible) .track .expand:focus {
-        background-color: rgba(153, 153, 153, .2);
-      }
-
-      :host(:not([expanded])) .track .expand {
-        background-image: -webkit-image-set(
-            url(../assets/100/player_cover_open.png) 1x,
-            url(../assets/200/player_cover_open.png) 2x);
-      }
-
-      :host([expanded]) .track .expand {
-        background-image: -webkit-image-set(
-            url(../assets/100/player_cover_close.png) 1x,
-            url(../assets/200/player_cover_close.png) 2x);
-      }
-
-      /* Track data. */
-
-      .track .data {
-        display: flex;
-        flex-direction: column;
-        justify-content: space-around;
-        min-width: 0;
-      }
-
-      .track .data .data-title,
-      .track .data .data-artist {
-        flex: auto;
-        overflow: hidden;
-        text-align: center;
-        text-overflow: ellipsis;
-        white-space: nowrap;
-      }
-
-      .track .data .data-title {
-        color: rgb(51, 51, 51);
-        font-size: 13px;
-        font-weight: 500;
-      }
-
-      .track .data .data-artist {
-        color: rgb(100, 100, 100);
-        font-size: 12px;
-      }
-      </style>
-    <div class="track-wrapper">
-      <div class="icon-unavailable-expanded"></div>
-      <div class="icon-expanded" style="background-image: url([[track.artworkUrl]]);"></div>
-      <div class="track">
-        <div class="icon-wrapper">
-          <div class="icon" style="background-image: url([[track.artworkUrl]]);"></div>
-        </div>
-        <div class="data">
-          <div class="data-title">[[track.title]]</div>
-          <div class="data-artist">[[track.artist]]</div>
-        </div>
-        <cr-button id="expand" class="expand" on-click="onExpandClick_"
-            aria-expanded="false" aria-label$="[[ariaExpandArtworkLabel]]">
-        </cr-button>
-      </div>
-    </div>
-  </template>
-  <script src="track_info_panel.js"></script>
-</dom-module>
-
diff --git a/ui/file_manager/audio_player/elements/track_info_panel.js b/ui/file_manager/audio_player/elements/track_info_panel.js
index 4f772a5..3ef965a 100644
--- a/ui/file_manager/audio_player/elements/track_info_panel.js
+++ b/ui/file_manager/audio_player/elements/track_info_panel.js
@@ -2,10 +2,179 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function() {
-/* #ignore */ 'use strict';
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
 
 Polymer({
+  _template: html`<!--_html_template_start_-->
+    <style>
+      :host {
+        align-items: center;
+        background: rgb(245, 245, 245);
+        color: rgb(51, 51, 51);
+        cursor: default;
+        font-size: 10pt;
+        overflow: hidden;
+      }
+
+      /* Track item. */
+      .track {
+        align-items: center;
+        background-color: rgba(255, 255, 255, 1.0);
+        display: flex;
+        height: 48px;
+        justify-content: space-between;
+        width: 100%;
+      }
+
+      :host([expanded]) .track {
+        background-color: rgba(255, 255, 255, 0.9);
+        bottom: 0;
+        position: absolute;
+      }
+
+      /* artwork icon(expanded) */
+      .track .icon-wrapper {
+        flex: none;
+        height: 48px;
+        width: 48px;
+      }
+
+      :host([expanded]) .icon {
+        visibility: hidden;
+      }
+
+      :host(:not([expanded])) .icon {
+        background-position: center;
+        background-repeat: no-repeat;
+        background-size: contain;
+        height: 48px;
+        pointer-events: none;
+        position: absolute;
+        width: 48px;
+      }
+
+      /* artwork icon(expanded) */
+
+      .track-wrapper {
+        background-color: rgb(32, 32, 34);
+        position: relative;
+      }
+
+      :host(:not([artwork-available])[expanded]) .track-wrapper {
+        height: 320px;
+        position: relative;
+        width: 100%;
+      }
+
+      .icon-expanded {
+        background-size: 0 0;
+      }
+
+      :host(:not([expanded])) .icon-unavailable-expanded {
+        background-size: 0 0;
+      }
+
+      :host(:not([artwork-available])[expanded]) .icon-unavailable-expanded {
+        background-image: -webkit-image-set(
+            url(../assets/100/player_no_artwork.png) 1x,
+            url(../assets/200/player_no_artwork.png) 2x);
+        background-position: center;
+        background-repeat: no-repeat;
+        height: calc(320px - 48px);
+        margin-left: auto;
+        margin-right: auto;
+        width: 320px;
+      }
+
+      :host([artwork-available][expanded]) .icon-expanded {
+        background-position: center;
+        background-repeat: no-repeat;
+        background-size: contain;
+        height: 320px;
+        margin-left: auto;
+        margin-right: auto;
+        width: 320px;
+      }
+
+      /* expand icon. */
+      .track .expand {
+        --ink-color: rgb(51, 51, 51);
+        background-color: transparent;
+        background-position: center;
+        background-repeat: no-repeat;
+        border: none;
+        border-radius: 0;
+        box-shadow: none;
+        flex: none;
+        height: 48px;
+        width: 48px;
+      }
+
+      :host-context(.focus-outline-visible) .track .expand:focus {
+        background-color: rgba(153, 153, 153, .2);
+      }
+
+      :host(:not([expanded])) .track .expand {
+        background-image: -webkit-image-set(
+            url(../assets/100/player_cover_open.png) 1x,
+            url(../assets/200/player_cover_open.png) 2x);
+      }
+
+      :host([expanded]) .track .expand {
+        background-image: -webkit-image-set(
+            url(../assets/100/player_cover_close.png) 1x,
+            url(../assets/200/player_cover_close.png) 2x);
+      }
+
+      /* Track data. */
+
+      .track .data {
+        display: flex;
+        flex-direction: column;
+        justify-content: space-around;
+        min-width: 0;
+      }
+
+      .track .data .data-title,
+      .track .data .data-artist {
+        flex: auto;
+        overflow: hidden;
+        text-align: center;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+
+      .track .data .data-title {
+        color: rgb(51, 51, 51);
+        font-size: 13px;
+        font-weight: 500;
+      }
+
+      .track .data .data-artist {
+        color: rgb(100, 100, 100);
+        font-size: 12px;
+      }
+      </style>
+    <div class="track-wrapper">
+      <div class="icon-unavailable-expanded"></div>
+      <div class="icon-expanded" style="background-image: url([[track.artworkUrl]]);"></div>
+      <div class="track">
+        <div class="icon-wrapper">
+          <div class="icon" style="background-image: url([[track.artworkUrl]]);"></div>
+        </div>
+        <div class="data">
+          <div class="data-title">[[track.title]]</div>
+          <div class="data-artist">[[track.artist]]</div>
+        </div>
+        <cr-button id="expand" class="expand" on-click="onExpandClick_"
+            aria-expanded="false" aria-label$="[[ariaExpandArtworkLabel]]">
+        </cr-button>
+      </div>
+    </div>
+<!--_html_template_end_-->`,
   is: 'track-info-panel',
 
   properties: {
@@ -41,4 +210,3 @@
     this.$.expand.setAttribute('aria-expanded', Boolean(this.expanded));
   },
 });
-})();  // Anonymous closure
diff --git a/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.m.js b/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.m.js
index e8c73d3..d4b5932 100644
--- a/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.m.js
+++ b/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.m.js
@@ -133,7 +133,7 @@
       const mockEntry = /** @type {!MockEntry} */ (this.sourceEntry_);
       fileSystem.entries[newPath] =
           /** @type {!MockEntry} */ (mockEntry.clone(newPath));
-      listener(copyId, makeStatus('end_copy_entry'));
+      listener(copyId, makeStatus('end_copy'));
       listener(copyId, makeStatus('success'));
     };
 
@@ -141,7 +141,7 @@
 
     callback(this.startCopyId_);
     const listener = mockChrome.fileManagerPrivate.onCopyProgress.listener_;
-    listener(this.startCopyId_, makeStatus('begin_copy_entry'));
+    listener(this.startCopyId_, makeStatus('begin'));
     listener(this.startCopyId_, makeStatus('progress'));
 
     if (destination.toURL() === this.blockedDestination_) {
@@ -534,14 +534,14 @@
         };
         callback(1);
         const listener = mockChrome.fileManagerPrivate.onCopyProgress.listener_;
-        listener(1, makeStatus('begin_copy_entry'));
+        listener(1, makeStatus('begin'));
         listener(1, makeStatus('progress'));
         const newPath = joinPath('/', newName);
         const entry = /** @type {!MockEntry} */
             (fileSystem.entries['/test.txt']);
         fileSystem.entries[newPath] =
             /** @type {!MockEntry} */ (entry.clone(newPath));
-        listener(1, makeStatus('end_copy_entry'));
+        listener(1, makeStatus('end_copy'));
         listener(1, makeStatus('success'));
       };
 
diff --git a/ui/file_manager/file_manager/background/js/file_operation_util.js b/ui/file_manager/file_manager/background/js/file_operation_util.js
index 7f90fc52..57453ee 100644
--- a/ui/file_manager/file_manager/background/js/file_operation_util.js
+++ b/ui/file_manager/file_manager/background/js/file_operation_util.js
@@ -427,11 +427,16 @@
           }
 
           switch (status.type) {
-            case 'begin_copy_entry':
+            case 'begin':
               callback();
               break;
 
-            case 'end_copy_entry':
+            case 'progress':
+              progressCallback(status.sourceUrl, status.size);
+              callback();
+              break;
+
+            case 'end_copy':
               // TODO(mtomasz): Convert URL to Entry in custom bindings.
               (source.isFile ? parent.getFile : parent.getDirectory)
                   .call(
@@ -446,8 +451,17 @@
                       });
               break;
 
-            case 'progress':
-              progressCallback(status.sourceUrl, status.size);
+            case 'end_move':
+              console.error(
+                  'Unexpected event: ' + status.type +
+                  ' (move not implemented yet)');
+              callback();
+              break;
+
+            case 'end_remove_source':
+              console.error(
+                  'Unexpected event: ' + status.type +
+                  ' (move not implemented yet)');
               callback();
               break;
 
diff --git a/ui/file_manager/file_manager_resources.grd b/ui/file_manager/file_manager_resources.grd
index c199d17..ad44835 100644
--- a/ui/file_manager/file_manager_resources.grd
+++ b/ui/file_manager/file_manager_resources.grd
@@ -133,8 +133,6 @@
       <include name="IDR_AUDIO_PLAYER_ELEMENTS_CONTROL_PANEL_JS" file="audio_player/elements/control_panel.js" type="BINDATA" />
       <include name="IDR_AUDIO_PLAYER_ELEMENTS_REPEAT_BUTTON_HTML" file="audio_player/elements/repeat_button.html" type="BINDATA" />
       <include name="IDR_AUDIO_PLAYER_ELEMENTS_REPEAT_BUTTON_JS" file="audio_player/elements/repeat_button.js" type="BINDATA" />
-      <include name="IDR_AUDIO_PLAYER_ELEMENTS_TRACK_INFO_PANEL_HTML" file="audio_player/elements/track_info_panel.html" type="BINDATA" />
-      <include name="IDR_AUDIO_PLAYER_ELEMENTS_TRACK_INFO_PANEL_JS" file="audio_player/elements/track_info_panel.js" type="BINDATA" />
       <include name="IDR_AUDIO_PLAYER_ELEMENTS_TRACK_LIST_HTML" file="audio_player/elements/track_list.html" type="BINDATA" />
       <include name="IDR_AUDIO_PLAYER_ELEMENTS_TRACK_LIST_JS" file="audio_player/elements/track_list.js" type="BINDATA" />
       <include name="IDR_AUDIO_PLAYER_METADATA_WORKER_JS" file="audio_player/js/metadata_worker.js" type="BINDATA" />
diff --git a/ui/gl/init/gl_factory.cc b/ui/gl/init/gl_factory.cc
index ddb538a..c7c0733 100644
--- a/ui/gl/init/gl_factory.cc
+++ b/ui/gl/init/gl_factory.cc
@@ -92,6 +92,13 @@
                (requested_implementation_gl_name ==
                 kGLImplementationSwiftShaderForWebGLName)) {
       impl = GLImplementationParts(kGLImplementationSwiftShaderGL);
+    } else if ((requested_implementation_gl_name ==
+                kGLImplementationANGLEName) &&
+               ((requested_implementation_angle_name ==
+                 kANGLEImplementationSwiftShaderName) ||
+                (requested_implementation_angle_name ==
+                 kANGLEImplementationSwiftShaderForWebGLName))) {
+      impl = GLImplementationParts(ANGLEImplementation::kSwiftShader);
     } else {
       impl = GetNamedGLImplementation(requested_implementation_gl_name,
                                       requested_implementation_angle_name);
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
index 34fc2ec0..43c9c79 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
@@ -92,7 +92,7 @@
 }
 
 void FakeFenceFD::Signal() const {
-  base::WriteFileDescriptor(write_fd.get(), "a", 1);
+  base::WriteFileDescriptor(write_fd.get(), "a");
 }
 
 class HardwareDisplayControllerTest : public testing::Test {
@@ -213,7 +213,7 @@
 
         plane.properties.push_back(
             {/* .id = */ pair.first, /*.value = */ value});
-      };
+      }
 
       drm_->SetPropertyBlob(ui::MockDrmDevice::AllocateInFormatsBlob(
           kInFormatsBlobPropId, {DRM_FORMAT_XRGB8888}, {}));
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
index 5c4d90f..cd01a6ce 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
@@ -187,7 +187,7 @@
         }
         plane_prop.properties.push_back(
             {/* .id = */ pair.first, /* .value = */ value});
-      };
+      }
 
       plane_properties_.emplace_back(std::move(plane_prop));
     }
@@ -1213,7 +1213,7 @@
 }
 
 void FakeFenceFD::Signal() const {
-  base::WriteFileDescriptor(write_fd.get(), "a", 1);
+  base::WriteFileDescriptor(write_fd.get(), "a");
 }
 
 class HardwareDisplayPlaneManagerPlanesReadyTest : public testing::Test {
diff --git a/ui/ozone/platform/wayland/host/wayland_clipboard.cc b/ui/ozone/platform/wayland/host/wayland_clipboard.cc
index a426f47..f998562 100644
--- a/ui/ozone/platform/wayland/host/wayland_clipboard.cc
+++ b/ui/ozone/platform/wayland/host/wayland_clipboard.cc
@@ -120,9 +120,7 @@
 
   void SetClipboardDataChangedCallback(
       ClipboardDataChangedCallback callback) final {
-    CHECK(clipboard_changed_callback_.is_null())
-        << "The callback can be installed only once.";
-    clipboard_changed_callback_ = callback;
+    clipboard_changed_callback_ = std::move(callback);
   }
 
  private:
diff --git a/ui/ozone/platform/wayland/host/wayland_data_source.cc b/ui/ozone/platform/wayland/host/wayland_data_source.cc
index 2788c04..3c199a27 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_source.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_source.cc
@@ -37,7 +37,7 @@
 void DataSource<T>::HandleSendEvent(const std::string& mime_type, int32_t fd) {
   std::string contents;
   delegate_->OnDataSourceSend(mime_type, &contents);
-  bool done = base::WriteFileDescriptor(fd, contents.data(), contents.length());
+  bool done = base::WriteFileDescriptor(fd, contents);
   DCHECK(done);
   close(fd);
 }
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.cc b/ui/ozone/platform/wayland/host/wayland_event_source.cc
index 526f0e0..82939b4a 100644
--- a/ui/ozone/platform/wayland/host/wayland_event_source.cc
+++ b/ui/ozone/platform/wayland/host/wayland_event_source.cc
@@ -24,6 +24,7 @@
 #include "ui/events/pointer_details.h"
 #include "ui/events/types/event_type.h"
 #include "ui/gfx/geometry/point_f.h"
+#include "ui/gfx/geometry/vector2d.h"
 #include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/ozone/platform/wayland/host/wayland_connection.h"
 #include "ui/ozone/platform/wayland/host/wayland_event_watcher.h"
@@ -221,18 +222,10 @@
     DispatchEvent(&event);
     recent_pointer_frames_.clear();
   } else {
-    if (current_pointer_frame_.axis_source == WL_POINTER_AXIS_SOURCE_WHEEL) {
-      MouseWheelEvent event(
-          gfx::Vector2d(current_pointer_frame_.dx, current_pointer_frame_.dy),
-          pointer_location_, pointer_location_, EventTimeForNow(), flags, 0);
-      DispatchEvent(&event);
-    } else {
-      ScrollEvent event(ET_SCROLL, pointer_location_, pointer_location_,
-                        EventTimeForNow(), flags, current_pointer_frame_.dx,
-                        current_pointer_frame_.dy, current_pointer_frame_.dx,
-                        current_pointer_frame_.dy, kGestureScrollFingerCount);
-      DispatchEvent(&event);
-    }
+    MouseWheelEvent event(
+        gfx::Vector2d(current_pointer_frame_.dx, current_pointer_frame_.dy),
+        pointer_location_, pointer_location_, EventTimeForNow(), flags, 0);
+    DispatchEvent(&event);
 
     if (recent_pointer_frames_.size() + 1 > kRecentPointerFrameMaxSize)
       recent_pointer_frames_.pop_back();
diff --git a/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc b/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc
index 22c6625..1ac8aac 100644
--- a/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc
@@ -339,9 +339,9 @@
 
   // Usual axis events should follow before the fling event.
   ASSERT_TRUE(event1);
-  ASSERT_TRUE(event1->IsScrollEvent());
+  ASSERT_TRUE(event1->IsMouseWheelEvent());
   ASSERT_TRUE(event2);
-  ASSERT_TRUE(event2->IsScrollEvent());
+  ASSERT_TRUE(event2->IsMouseWheelEvent());
 
   // The third dispatched event should be FLING_START.
   ASSERT_TRUE(event3);
@@ -393,9 +393,9 @@
 
   // Usual axis events should follow before the fling event.
   ASSERT_TRUE(event1);
-  ASSERT_TRUE(event1->IsScrollEvent());
+  ASSERT_TRUE(event1->IsMouseWheelEvent());
   ASSERT_TRUE(event2);
-  ASSERT_TRUE(event2->IsScrollEvent());
+  ASSERT_TRUE(event2->IsMouseWheelEvent());
 
   // The third dispatched event should be FLING_START.
   ASSERT_TRUE(event3);
@@ -455,16 +455,15 @@
 
   // Usual axis events should follow before the fling event.
   ASSERT_TRUE(event1);
-  ASSERT_TRUE(event1->IsScrollEvent());
+  ASSERT_TRUE(event1->IsMouseWheelEvent());
   ASSERT_TRUE(event2);
-  ASSERT_TRUE(event2->IsScrollEvent());
+  ASSERT_TRUE(event2->IsMouseWheelEvent());
 
   // The 3rd axis event's offset is 0.
   ASSERT_TRUE(event3);
-  ASSERT_TRUE(event3->IsScrollEvent());
-  auto* scroll_event0 = event3->AsScrollEvent();
-  EXPECT_EQ(gfx::Vector2dF(0., 0.), gfx::Vector2dF(scroll_event0->x_offset(),
-                                                   scroll_event0->y_offset()));
+  ASSERT_TRUE(event3->IsMouseWheelEvent());
+  auto* mouse_wheel_event = event3->AsMouseWheelEvent();
+  EXPECT_EQ(gfx::Vector2d(0, 0), mouse_wheel_event->offset());
 
   // The 4th event should be FLING_CANCEL.
   ASSERT_TRUE(event4);
@@ -513,9 +512,9 @@
 
   // Usual axis events should follow before the fling event.
   ASSERT_TRUE(event1);
-  ASSERT_TRUE(event1->IsScrollEvent());
+  ASSERT_TRUE(event1->IsMouseWheelEvent());
   ASSERT_TRUE(event2);
-  ASSERT_TRUE(event2->IsScrollEvent());
+  ASSERT_TRUE(event2->IsMouseWheelEvent());
 
   // The third dispatched event should be FLING_START.
   ASSERT_TRUE(event3);
diff --git a/ui/ozone/platform/wayland/test/test_data_offer.cc b/ui/ozone/platform/wayland/test/test_data_offer.cc
index 861e685..acedb732 100644
--- a/ui/ozone/platform/wayland/test/test_data_offer.cc
+++ b/ui/ozone/platform/wayland/test/test_data_offer.cc
@@ -21,8 +21,7 @@
 
 void WriteDataOnWorkerThread(base::ScopedFD fd,
                              ui::PlatformClipboard::Data data) {
-  if (!base::WriteFileDescriptor(fd.get(), data->front_as<char>(),
-                                 data->size())) {
+  if (!base::WriteFileDescriptor(fd.get(), data->data())) {
     LOG(ERROR) << "Failed to write selection data to clipboard.";
   }
 }
diff --git a/url/url_idna_icu.cc b/url/url_idna_icu.cc
index 4bd6a88..48e53a9 100644
--- a/url/url_idna_icu.cc
+++ b/url/url_idna_icu.cc
@@ -21,7 +21,7 @@
 
 namespace {
 
-// A wrapper to use LazyInstance<>::Leaky with ICU's UIDNA, a C pointer to
+// A wrapper to use base::NoDestructor with ICU's UIDNA, a C pointer to
 // a UTS46/IDNA 2008 handling object opened with uidna_openUTS46().
 //
 // We use UTS46 with BiDiCheck to migrate from IDNA 2003 (with unassigned
@@ -92,13 +92,39 @@
     UIDNAInfo info = UIDNA_INFO_INITIALIZER;
     int output_length = uidna_nameToASCII(uidna, src, src_len, output->data(),
                                           output->capacity(), &info, &err);
+
+    // Ignore various errors for web compatibility. The options are specified
+    // by the WHATWG URL Standard. See
+    //  - https://unicode.org/reports/tr46/
+    //  - https://url.spec.whatwg.org/#concept-domain-to-ascii
+    //    (we set beStrict to false)
+
+    // Disable the "CheckHyphens" option in UTS #46. See
+    //  - https://crbug.com/804688
+    //  - https://github.com/whatwg/url/issues/267
+    info.errors &= ~UIDNA_ERROR_HYPHEN_3_4;
+    info.errors &= ~UIDNA_ERROR_LEADING_HYPHEN;
+    info.errors &= ~UIDNA_ERROR_TRAILING_HYPHEN;
+
+    // Disable the "VerifyDnsLength" option in UTS #46.
+    info.errors &= ~UIDNA_ERROR_EMPTY_LABEL;
+    info.errors &= ~UIDNA_ERROR_LABEL_TOO_LONG;
+    info.errors &= ~UIDNA_ERROR_DOMAIN_NAME_TOO_LONG;
+
     if (U_SUCCESS(err) && info.errors == 0) {
+      // Per WHATWG URL, it is a failure if the ToASCII output is empty.
+      //
+      // ICU would usually return UIDNA_ERROR_EMPTY_LABEL in this case, but we
+      // want to continue allowing http://abc..def/ while forbidding http:///.
+      //
+      if (output_length == 0) {
+        return false;
+      }
+
       output->set_length(output_length);
       return true;
     }
 
-    // TODO(jungshik): Look at info.errors to handle them case-by-case basis
-    // if necessary.
     if (err != U_BUFFER_OVERFLOW_ERROR || info.errors != 0)
       return false;  // Unknown error, give up.
 
diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc
index 7e8c9eb..8ab00a3 100644
--- a/weblayer/browser/content_browser_client_impl.cc
+++ b/weblayer/browser/content_browser_client_impl.cc
@@ -29,6 +29,7 @@
 #include "components/error_page/common/error.h"
 #include "components/error_page/common/localized_error.h"
 #include "components/error_page/content/browser/net_error_auto_reloader.h"
+#include "components/metrics/metrics_service.h"
 #include "components/network_time/network_time_tracker.h"
 #include "components/no_state_prefetch/browser/no_state_prefetch_manager.h"
 #include "components/no_state_prefetch/common/prerender_url_loader_throttle.h"
@@ -265,6 +266,14 @@
   pref_registry->RegisterIntegerPref(kDownloadNextIDPref, 0);
 #if defined(OS_ANDROID)
   metrics::AndroidMetricsServiceClient::RegisterPrefs(pref_registry);
+#else
+  // Call MetricsService::RegisterPrefs() as VariationsService::RegisterPrefs()
+  // CHECKs that kVariationsCrashStreak has already been registered.
+  //
+  // Note that the above call to AndroidMetricsServiceClient::RegisterPrefs()
+  // implicitly calls MetricsService::RegisterPrefs(), so the below call is
+  // necessary only on non-Android platforms.
+  metrics::MetricsService::RegisterPrefs(pref_registry);
 #endif
   variations::VariationsService::RegisterPrefs(pref_registry);
   subresource_filter::IndexedRulesetVersion::RegisterPrefs(pref_registry);
@@ -1152,7 +1161,7 @@
   DCHECK(browser_context);
 
   content::PermissionController* permission_controller =
-      content::BrowserContext::GetPermissionController(browser_context);
+      browser_context->GetPermissionController();
   blink::mojom::PermissionStatus status =
       permission_controller->GetPermissionStatusForFrame(
           content::PermissionType::CLIPBOARD_READ_WRITE, render_frame_host,