diff --git a/.gitignore b/.gitignore
index f50a151..79990a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -72,8 +72,9 @@
 /base/base_unittests_run.xml
 # See build/.gitignore for entries covering src/build.
 
-# The Chrome OS build creates a /c symlink due to http://crbug.com/54866.
+# The Chrome OS build creates a /c and /c_icu symlink due to http://crbug.com/54866.
 /c
+/c_icu
 /cdm
 /ceee/internal/
 /chrome/android/profiles/afdo.prof
@@ -327,4 +328,3 @@
 
 # Ignore the default results output directory for tools/run-swarmed.py
 /results
-
diff --git a/DEPS b/DEPS
index fb7744e..d0d37fd9 100644
--- a/DEPS
+++ b/DEPS
@@ -195,11 +195,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'a5f3c3149033dffc4d706fe34eb40714fc63d8c0',
+  'skia_revision': '3eb813e0cc134767a10e9efd4811fc519eccb280',
   # 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': '7b2a8dea4181d991083b4e4ade123aeffb1a66df',
+  'v8_revision': 'e0d5b2a8208346a0c10ac96bfef2a78311b7f7a0',
   # 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.
@@ -207,7 +207,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': 'b44af6625286df933a688779d139ec33cd3e492a',
+  'angle_revision': 'ee7ae7aba2c91034b6304dcad1df5823ff3d5702',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -901,7 +901,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '407b5a54a9b5a96fcd6ec33717782fb2f1dd6447',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'd1580d53b7bc1f244d4eaf797aca0d066fad166c',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1032,7 +1032,7 @@
     Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '18e09b9197a3b1d771c077c530d1a4ebad04c167',
 
   'src/third_party/icu':
-    Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '79326efe26e5440f530963704c3c0ff965b3a4ac',
+    Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'aef20f06d47ba76fdf13abcdb033e2a408b5a94d',
 
   'src/third_party/icu4j': {
       'packages': [
@@ -1544,7 +1544,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/mac-amd64',
-          'version': 'nLiRBOlDnLpGaONe3dMmjU3S8K3bfjiA0p4VZkqV2IEC',
+          'version': 'McQX6w7ojyNaDcWISrmicbt00IsXxTSvxjuEPfPLiIEC',
         },
       ],
       'dep_type': 'cipd',
@@ -1558,7 +1558,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@9bcb0cadf78f889a0eca925b2f38efd420b206e4',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@aad83522fd172502e4b3783190db56538bb706bd',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/java/src/org/chromium/android_webview/common/crash/SystemWideCrashDirectories.java b/android_webview/java/src/org/chromium/android_webview/common/crash/SystemWideCrashDirectories.java
index fe3bc09c..a020efed0 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/crash/SystemWideCrashDirectories.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/crash/SystemWideCrashDirectories.java
@@ -17,6 +17,7 @@
     private static final String WEBVIEW_CRASH_LOG_DIR = "crash_logs";
     private static final String WEBVIEW_CRASH_DIR = "WebView_Crashes";
     private static final String WEBVIEW_TMP_CRASH_DIR = "WebView_Crashes_Tmp";
+    private static final String WEBVIEW_CRASH_LOG_SUFFIX = "_log.json";
 
     /**
      * Create the directory in which WebView will log crashes info.
@@ -61,6 +62,14 @@
         return new File(ContextUtils.getApplicationContext().getCacheDir(), WEBVIEW_TMP_CRASH_DIR);
     }
 
+    /**
+     * Create Crash json log file in the crash log directory.
+     * @return a File pointing to the created crash json log file.
+     */
+    public static File createCrashJsonLogFile(String logFileName) {
+        return new File(getOrCreateWebViewCrashLogDir(), logFileName + WEBVIEW_CRASH_LOG_SUFFIX);
+    }
+
     private static File getOrCreateDir(File dir) {
         // Call mkdir before isDirectory to ensure that if another thread created the directory
         // just before the call to mkdir, the current thread fails mkdir, but passes isDirectory.
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
index a078f7c..9c2f2fb 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
@@ -1238,12 +1238,13 @@
     }
 
     /**
-     * This test is verifying the session is still alive after navigation.
+     * This test is verifying that a navigation occurring while there is a probably-submitted
+     * form will trigger commit of the current autofill session.
      */
     @Test
     @SmallTest
     @Feature({"AndroidWebView"})
-    public void testSessionAliveAfterNavigation() throws Throwable {
+    public void testNavigationAfterProbableSubmitResultsInSessionCommit() throws Throwable {
         int cnt = 0;
         final String data = "<!DOCTYPE html>"
                 + "<html>"
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/devui/CrashesListFragmentTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/devui/CrashesListFragmentTest.java
index b3b9220..71aa218 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/devui/CrashesListFragmentTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/devui/CrashesListFragmentTest.java
@@ -268,9 +268,36 @@
      */
     private static DataInteraction checkUnknownPackageCrashItemHeader(
             DataInteraction headerDataInteraction, CrashInfo crashInfo) {
+        return checkPackageCrashItemHeader(headerDataInteraction, crashInfo, FAKE_APP_PACKAGE_NAME);
+    }
+
+    /**
+     * Check that the given crash item header shows the "unknown app" package name, capture date and
+     * icon for the given {@code crashInfo}.
+     *
+     * @param {@link DataInteraction} represents the crash item header.
+     * @param {@link CrashInfo} to match.
+     * @return the same {@code headerDataInteraction} passed for the convenience of chaining.
+     */
+    private static DataInteraction checkMissingPackageInfoCrashItemHeader(
+            DataInteraction headerDataInteraction, CrashInfo crashInfo) {
+        return checkPackageCrashItemHeader(headerDataInteraction, crashInfo, "unknown app");
+    }
+
+    /**
+     * Check that the given crash item header shows the given package name, capture date and
+     * icon for the given {@code crashInfo}.
+     *
+     * @param {@link DataInteraction} represents the crash item header.
+     * @param {@link CrashInfo} to match.
+     * @param packageName to match.
+     * @return the same {@code headerDataInteraction} passed for the convenience of chaining.
+     */
+    private static DataInteraction checkPackageCrashItemHeader(
+            DataInteraction headerDataInteraction, CrashInfo crashInfo, String packageName) {
         String captureDate = new Date(crashInfo.captureTime).toString();
         headerDataInteraction.onChildView(withId(android.R.id.text1))
-                .check(matches(withText(FAKE_APP_PACKAGE_NAME)));
+                .check(matches(withText(packageName)));
         headerDataInteraction.onChildView(withId(android.R.id.text2))
                 .check(matches(withText(captureDate)));
         // There should not be an app with FAKE_APP_PACKAGE_NAME so system default icon should be
@@ -282,6 +309,19 @@
     }
 
     /**
+     * Perform click on hide crash button by checking the required conditions for the button.
+     *
+     * @param {@link DataInteraction} represents the crash item body.
+     */
+    private static void clickHideCrashButton(DataInteraction bodyDataInteraction) {
+        bodyDataInteraction.onChildView(withId(R.id.crash_hide_button))
+                .check(matches(isDisplayed()))
+                .check(matches(isEnabled()))
+                .check(matches(withDrawable(R.drawable.ic_delete)))
+                .perform(click());
+    }
+
+    /**
      * Check that the given crash item body shows the correct uploadState, uploadId and uploadDate.
      *
      * @param {@link DataInteraction} represents the crash item body.
@@ -701,11 +741,44 @@
 
         onView(withId(R.id.crashes_list)).check(matches(withCount(1)));
 
-        DataInteraction headerDataInteraction = onData(anything()).atPosition(0);
-        headerDataInteraction.onChildView(withId(android.R.id.text1))
-                .check(matches(withText("unknown app")));
-        headerDataInteraction.onChildView(withId(R.id.crash_package_icon))
-                .check(matches(withDrawable(android.R.drawable.sym_def_app_icon)));
+        checkMissingPackageInfoCrashItemHeader(onData(anything()).atPosition(0), crashInfo);
+    }
+
+    @Test
+    @Feature({"AndroidWebView"})
+    // Test when crash is missing json, but has upload log file and minidump.
+    public void testShowingSingleCrashReport_uploaded_missingJson() throws Throwable {
+        CrashInfo crashInfo = createCrashInfo("123456", -1, null, 1000, null, UploadState.UPLOADED);
+
+        assertThat("temp minidump file should exist", createMinidumpFile(crashInfo).exists());
+        assertThat("upload log file should exist", appendUploadedEntryToLog(crashInfo).exists());
+
+        CallbackHelper helper = getCrashListLoadedListener();
+        int crashListLoadInitCount = helper.getCallCount();
+        launchCrashesFragment();
+        helper.waitForCallback(crashListLoadInitCount, 1);
+
+        onView(withId(R.id.crashes_list)).check(matches(withCount(1)));
+
+        checkMissingPackageInfoCrashItemHeader(onData(anything()).atPosition(0), crashInfo);
+    }
+
+    @Test
+    @Feature({"AndroidWebView"})
+    // Test when crash is missing json, but has upload log file and minidump.
+    public void testShowingSingleCrashReport_pending_missingJson() throws Throwable {
+        CrashInfo crashInfo = createCrashInfo("123456", -1, null, 1000, null, UploadState.PENDING);
+
+        assertThat("temp minidump file should exist", createMinidumpFile(crashInfo).exists());
+
+        CallbackHelper helper = getCrashListLoadedListener();
+        int crashListLoadInitCount = helper.getCallCount();
+        launchCrashesFragment();
+        helper.waitForCallback(crashListLoadInitCount, 1);
+
+        onView(withId(R.id.crashes_list)).check(matches(withCount(1)));
+
+        checkMissingPackageInfoCrashItemHeader(onData(anything()).atPosition(0), crashInfo);
     }
 
     @Test
@@ -766,13 +839,7 @@
         DataInteraction bodyDataInteraction = onData(anything()).atPosition(1);
 
         crashListLoadInitCount = helper.getCallCount();
-
-        bodyDataInteraction.onChildView(withId(R.id.crash_hide_button))
-                .check(matches(isDisplayed()))
-                .check(matches(isEnabled()))
-                .check(matches(withDrawable(R.drawable.ic_delete)))
-                .perform(click());
-
+        clickHideCrashButton(bodyDataInteraction);
         helper.waitForCallback(crashListLoadInitCount, 1);
 
         onView(withId(R.id.crashes_list)).check(matches(withCount(0)));
@@ -803,13 +870,64 @@
         DataInteraction bodyDataInteraction = onData(anything()).atPosition(1);
 
         crashListLoadInitCount = helper.getCallCount();
+        clickHideCrashButton(bodyDataInteraction);
+        helper.waitForCallback(crashListLoadInitCount, 1);
 
-        bodyDataInteraction.onChildView(withId(R.id.crash_hide_button))
-                .check(matches(isDisplayed()))
-                .check(matches(isEnabled()))
-                .check(matches(withDrawable(R.drawable.ic_delete)))
-                .perform(click());
+        onView(withId(R.id.crashes_list)).check(matches(withCount(0)));
+    }
 
+    @Test
+    @Feature({"AndroidWebView"})
+    public void testHideCrashButton_uploaded_missingJson() throws Throwable {
+        CrashInfo crashInfo = createCrashInfo("123456", -1, null, 1000, null, UploadState.UPLOADED);
+
+        assertThat("temp minidump file should exist", createMinidumpFile(crashInfo).exists());
+        assertThat("upload log file should exist", appendUploadedEntryToLog(crashInfo).exists());
+
+        CallbackHelper helper = getCrashListLoadedListener();
+        int crashListLoadInitCount = helper.getCallCount();
+        launchCrashesFragment();
+        helper.waitForCallback(crashListLoadInitCount, 1);
+
+        onView(withId(R.id.crashes_list)).check(matches(withCount(1)));
+
+        // Check crash item header
+        checkMissingPackageInfoCrashItemHeader(onData(anything()).atPosition(0), crashInfo)
+                .perform(click()); // click to expand it
+        // The body is considered item#2 in the list view after expansion
+        onView(withId(R.id.crashes_list)).check(matches(withCount(2)));
+        DataInteraction bodyDataInteraction = onData(anything()).atPosition(1);
+
+        crashListLoadInitCount = helper.getCallCount();
+        clickHideCrashButton(bodyDataInteraction);
+        helper.waitForCallback(crashListLoadInitCount, 1);
+
+        onView(withId(R.id.crashes_list)).check(matches(withCount(0)));
+    }
+
+    @Test
+    @Feature({"AndroidWebView"})
+    public void testHideCrashButton_pending_missingJson() throws Throwable {
+        CrashInfo crashInfo = createCrashInfo("123456", -1, null, -1, null, UploadState.PENDING);
+
+        assertThat("temp minidump file should exist", createMinidumpFile(crashInfo).exists());
+
+        CallbackHelper helper = getCrashListLoadedListener();
+        int crashListLoadInitCount = helper.getCallCount();
+        launchCrashesFragment();
+        helper.waitForCallback(crashListLoadInitCount, 1);
+
+        onView(withId(R.id.crashes_list)).check(matches(withCount(1)));
+
+        // Check crash item header
+        checkMissingPackageInfoCrashItemHeader(onData(anything()).atPosition(0), crashInfo)
+                .perform(click()); // click to expand it
+        // The body is considered item#2 in the list view after expansion
+        onView(withId(R.id.crashes_list)).check(matches(withCount(2)));
+        DataInteraction bodyDataInteraction = onData(anything()).atPosition(1);
+
+        crashListLoadInitCount = helper.getCallCount();
+        clickHideCrashButton(bodyDataInteraction);
         helper.waitForCallback(crashListLoadInitCount, 1);
 
         onView(withId(R.id.crashes_list)).check(matches(withCount(0)));
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/WebViewCrashInfoCollectorTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/WebViewCrashInfoCollectorTest.java
index 55ba41ce..d391a6c 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/WebViewCrashInfoCollectorTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/WebViewCrashInfoCollectorTest.java
@@ -230,6 +230,6 @@
         WebViewCrashInfoCollector.updateCrashLogFileWithNewCrashInfo(newCrashInfo);
 
         CrashInfo resultCrashInfo = getCrashFromJsonLogFile("xyz123");
-        Assert.assertThat(resultCrashInfo, equalsTo(null));
+        Assert.assertThat(resultCrashInfo, equalsTo(newCrashInfo));
     }
 }
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/util/WebViewCrashInfoCollector.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/util/WebViewCrashInfoCollector.java
index 4f4062f..e965e77 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/util/WebViewCrashInfoCollector.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/util/WebViewCrashInfoCollector.java
@@ -146,28 +146,31 @@
      * Modify WebView crash JSON log file with the new crash info if the JSON file exists
      */
     public static void updateCrashLogFileWithNewCrashInfo(CrashInfo crashInfo) {
-        File logDir = SystemWideCrashDirectories.getWebViewCrashLogDir();
+        File logDir = SystemWideCrashDirectories.getOrCreateWebViewCrashLogDir();
         File[] logFiles = logDir.listFiles();
-        if (logFiles == null) {
-            return;
-        }
         for (File logFile : logFiles) {
             // Ignore non-json files.
             if (!logFile.isFile() || !logFile.getName().endsWith(".json")) continue;
             // Ignore unrelated json files
             if (!logFile.getName().contains(crashInfo.localId)) continue;
-            try {
-                FileWriter writer = new FileWriter(logFile);
-                try {
-                    writer.write(crashInfo.serializeToJson());
-                } finally {
-                    writer.close();
-                }
-            } catch (IOException e) {
-                Log.e(TAG, "failed to modify JSON log entry for crash", e);
-            }
+            tryWritingCrashInfoToLogFile(crashInfo, logFile);
             return;
         }
-        // logfile does not exist
+        // logfile does not exist, so creates and writes to a new logfile
+        File newLogFile = SystemWideCrashDirectories.createCrashJsonLogFile(crashInfo.localId);
+        tryWritingCrashInfoToLogFile(crashInfo, newLogFile);
+    }
+
+    private static void tryWritingCrashInfoToLogFile(CrashInfo crashInfo, File logFile) {
+        try {
+            FileWriter writer = new FileWriter(logFile);
+            try {
+                writer.write(crashInfo.serializeToJson());
+            } finally {
+                writer.close();
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "failed to modify JSON log entry for crash", e);
+        }
     }
 }
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java
index 30378a7..39c7329 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java
@@ -30,7 +30,6 @@
  */
 public class CrashReceiverService extends Service {
     private static final String TAG = "CrashReceiverService";
-    private static final String WEBVIEW_CRASH_LOG_SUFFIX = "_log.json";
 
     private final Object mCopyingLock = new Object();
     private boolean mIsCopying;
@@ -123,9 +122,8 @@
                         copiedAnything = true;
                         if (crashesInfo != null) {
                             Map<String, String> crashInfo = crashesInfo.get(i);
-                            File logFile = new File(
-                                    SystemWideCrashDirectories.getOrCreateWebViewCrashLogDir(),
-                                    copiedFile.getName() + WEBVIEW_CRASH_LOG_SUFFIX);
+                            File logFile = SystemWideCrashDirectories.createCrashJsonLogFile(
+                                    copiedFile.getName());
                             writeCrashInfoToLogFile(logFile, copiedFile, crashInfo);
                         }
                     }
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 15eadfc0..c7863b9 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -926,12 +926,12 @@
     "system/holding_space/holding_space_item_chip_view.h",
     "system/holding_space/holding_space_item_chips_container.cc",
     "system/holding_space/holding_space_item_chips_container.h",
+    "system/holding_space/holding_space_item_context_menu.cc",
+    "system/holding_space/holding_space_item_context_menu.h",
     "system/holding_space/holding_space_item_screenshot_view.cc",
     "system/holding_space/holding_space_item_screenshot_view.h",
     "system/holding_space/holding_space_item_view.cc",
     "system/holding_space/holding_space_item_view.h",
-    "system/holding_space/holding_space_item_view_delegate.cc",
-    "system/holding_space/holding_space_item_view_delegate.h",
     "system/holding_space/holding_space_item_views_container.cc",
     "system/holding_space/holding_space_item_views_container.h",
     "system/holding_space/holding_space_tray.cc",
diff --git a/ash/ambient/ambient_constants.h b/ash/ambient/ambient_constants.h
index fb1959a..8248007 100644
--- a/ash/ambient/ambient_constants.h
+++ b/ash/ambient/ambient_constants.h
@@ -48,6 +48,10 @@
 constexpr base::TimeDelta kTokenUsageTimeBuffer =
     base::TimeDelta::FromMinutes(10);
 
+// PhotoView related constants.
+// Spacing between two portrait images.
+constexpr int kMarginLeftOfRelatedImageDip = 8;
+
 }  // namespace ash
 
 #endif  // ASH_AMBIENT_AMBIENT_CONSTANTS_H_
diff --git a/ash/ambient/ambient_photo_controller.cc b/ash/ambient/ambient_photo_controller.cc
index 5b00b627..b892d22 100644
--- a/ash/ambient/ambient_photo_controller.cc
+++ b/ash/ambient/ambient_photo_controller.cc
@@ -14,6 +14,7 @@
 #include "ash/public/cpp/ambient/ambient_client.h"
 #include "ash/public/cpp/image_downloader.h"
 #include "ash/shell.h"
+#include "base/barrier_closure.h"
 #include "base/base64.h"
 #include "base/base_paths.h"
 #include "base/bind.h"
@@ -324,15 +325,44 @@
   StartDownloadingWeatherConditionIcon(screen_update.weather_info);
 }
 
+void AmbientPhotoController::ResetImageData() {
+  image_data_.reset();
+  related_image_data_.reset();
+  image_details_.reset();
+
+  image_ = gfx::ImageSkia();
+  related_image_ = gfx::ImageSkia();
+}
+
 void AmbientPhotoController::FetchPhotoRawData() {
   const AmbientModeTopic* topic = GetNextTopic();
+  ResetImageData();
+
   if (topic) {
+    const int num_callbacks = (topic->related_image_url) ? 2 : 1;
+    auto on_done = base::BarrierClosure(
+        num_callbacks,
+        base::BindOnce(&AmbientPhotoController::OnAllPhotoRawDataAvailable,
+                       weak_factory_.GetWeakPtr(),
+                       /*from_downloading=*/true));
+
     url_loader_->Download(
-        topic->GetUrl(),
+        topic->url,
         base::BindOnce(&AmbientPhotoController::OnPhotoRawDataAvailable,
                        weak_factory_.GetWeakPtr(),
                        /*from_downloading=*/true,
+                       /*is_related_image=*/false, on_done,
                        std::make_unique<std::string>(topic->details)));
+
+    if (topic->related_image_url) {
+      url_loader_->Download(
+          *(topic->related_image_url),
+          base::BindOnce(&AmbientPhotoController::OnPhotoRawDataAvailable,
+                         weak_factory_.GetWeakPtr(),
+                         /*from_downloading=*/true,
+                         /*is_related_image=*/true, on_done,
+                         std::make_unique<std::string>(topic->details)));
+    }
     return;
   }
 
@@ -367,6 +397,10 @@
 
   auto photo_data = std::make_unique<std::string>();
   auto photo_details = std::make_unique<std::string>();
+  auto on_done =
+      base::BindRepeating(&AmbientPhotoController::OnAllPhotoRawDataAvailable,
+                          weak_factory_.GetWeakPtr(),
+                          /*from_downloading=*/false);
   task_runner_->PostTaskAndReply(
       FROM_HERE,
       base::BindOnce(
@@ -386,14 +420,27 @@
           file_name, photo_data.get(), photo_details.get()),
       base::BindOnce(&AmbientPhotoController::OnPhotoRawDataAvailable,
                      weak_factory_.GetWeakPtr(), /*from_downloading=*/false,
+                     /*is_related_image=*/false, on_done,
                      std::move(photo_details), std::move(photo_data)));
 }
 
 void AmbientPhotoController::OnPhotoRawDataAvailable(
     bool from_downloading,
+    bool is_related_image,
+    base::RepeatingClosure on_done,
     std::unique_ptr<std::string> details,
     std::unique_ptr<std::string> data) {
-  if (!data || data->empty()) {
+  if (is_related_image)
+    related_image_data_ = std::move(data);
+  else {
+    image_data_ = std::move(data);
+    image_details_ = std::move(details);
+  }
+  std::move(on_done).Run();
+}
+
+void AmbientPhotoController::OnAllPhotoRawDataAvailable(bool from_downloading) {
+  if (!image_data_ || image_data_->empty()) {
     if (from_downloading) {
       LOG(ERROR) << "Failed to download image";
       resume_fetch_image_backoff_.InformOfRequest(/*succeeded=*/false);
@@ -414,6 +461,12 @@
   if (cache_index_for_store_ == kMaxNumberOfCachedImages)
     cache_index_for_store_ = 0;
 
+  const int num_callbacks = related_image_data_ ? 2 : 1;
+  auto on_done = base::BarrierClosure(
+      num_callbacks,
+      base::BindOnce(&AmbientPhotoController::OnAllPhotoDecoded,
+                     weak_factory_.GetWeakPtr(), from_downloading));
+
   task_runner_->PostTaskAndReply(
       FROM_HERE,
       base::BindOnce(
@@ -425,28 +478,44 @@
                         details);
             }
           },
-          file_name, from_downloading, *data, *details),
+          file_name, from_downloading, *image_data_, *image_details_),
       base::BindOnce(&AmbientPhotoController::DecodePhotoRawData,
                      weak_factory_.GetWeakPtr(), from_downloading,
-                     std::move(details), std::move(data)));
+                     /*is_related_image=*/false, on_done,
+                     std::move(image_data_)));
+
+  if (related_image_data_) {
+    DecodePhotoRawData(from_downloading, /*is_related_image=*/true, on_done,
+                       std::move(related_image_data_));
+  }
 }
 
 void AmbientPhotoController::DecodePhotoRawData(
     bool from_downloading,
-    std::unique_ptr<std::string> details,
+    bool is_related_image,
+    base::RepeatingClosure on_done,
     std::unique_ptr<std::string> data) {
   std::vector<uint8_t> image_bytes(data->begin(), data->end());
   image_decoder_->Decode(
       image_bytes, base::BindOnce(&AmbientPhotoController::OnPhotoDecoded,
                                   weak_factory_.GetWeakPtr(), from_downloading,
-                                  std::move(details)));
+                                  is_related_image, on_done));
 }
 
-void AmbientPhotoController::OnPhotoDecoded(
-    bool from_downloading,
-    std::unique_ptr<std::string> details,
-    const gfx::ImageSkia& image) {
-  if (image.isNull()) {
+void AmbientPhotoController::OnPhotoDecoded(bool from_downloading,
+                                            bool is_related_image,
+                                            base::RepeatingClosure on_done,
+                                            const gfx::ImageSkia& image) {
+  if (is_related_image)
+    related_image_ = image;
+  else
+    image_ = image;
+
+  std::move(on_done).Run();
+}
+
+void AmbientPhotoController::OnAllPhotoDecoded(bool from_downloading) {
+  if (image_.isNull()) {
     LOG(WARNING) << "Image is null";
     if (from_downloading)
       resume_fetch_image_backoff_.InformOfRequest(/*succeeded=*/false);
@@ -461,8 +530,12 @@
     resume_fetch_image_backoff_.InformOfRequest(/*succeeded=*/true);
 
   PhotoWithDetails detailed_photo;
-  detailed_photo.photo = image;
-  detailed_photo.details = *details;
+  detailed_photo.photo = image_;
+  detailed_photo.related_photo = related_image_;
+  detailed_photo.details = *image_details_;
+
+  ResetImageData();
+
   ambient_backend_model_.AddNextImage(std::move(detailed_photo));
 
   ScheduleRefreshImage();
diff --git a/ash/ambient/ambient_photo_controller.h b/ash/ambient/ambient_photo_controller.h
index 85abd91..256c247 100644
--- a/ash/ambient/ambient_photo_controller.h
+++ b/ash/ambient/ambient_photo_controller.h
@@ -118,6 +118,9 @@
 
   void OnScreenUpdateInfoFetched(const ash::ScreenUpdate& screen_update);
 
+  // Clear temporary image data to prepare next photos.
+  void ResetImageData();
+
   // Fetch photo raw data by downloading or reading from cache.
   void FetchPhotoRawData();
 
@@ -125,17 +128,25 @@
   void TryReadPhotoRawData();
 
   void OnPhotoRawDataAvailable(bool from_downloading,
+                               bool is_related_image,
+                               base::RepeatingClosure on_done,
                                std::unique_ptr<std::string> details,
                                std::unique_ptr<std::string> data);
 
+  void OnAllPhotoRawDataAvailable(bool from_downloading);
+
   void DecodePhotoRawData(bool from_downloading,
-                          std::unique_ptr<std::string> details,
+                          bool is_related_image,
+                          base::RepeatingClosure on_done,
                           std::unique_ptr<std::string> data);
 
   void OnPhotoDecoded(bool from_downloading,
-                      std::unique_ptr<std::string> details,
+                      bool is_related_image,
+                      base::RepeatingClosure on_done,
                       const gfx::ImageSkia& image);
 
+  void OnAllPhotoDecoded(bool from_downloading);
+
   void StartDownloadingWeatherConditionIcon(
       const base::Optional<WeatherInfo>& weather_info);
 
@@ -209,6 +220,13 @@
 
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
+  // Temporary data store when fetching images and details.
+  std::unique_ptr<std::string> image_data_;
+  std::unique_ptr<std::string> related_image_data_;
+  std::unique_ptr<std::string> image_details_;
+  gfx::ImageSkia image_;
+  gfx::ImageSkia related_image_;
+
   base::WeakPtrFactory<AmbientPhotoController> weak_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(AmbientPhotoController);
diff --git a/ash/ambient/backdrop/ambient_backend_controller_impl.cc b/ash/ambient/backdrop/ambient_backend_controller_impl.cc
index 97b4d309..7d3cacc8 100644
--- a/ash/ambient/backdrop/ambient_backend_controller_impl.cc
+++ b/ash/ambient/backdrop/ambient_backend_controller_impl.cc
@@ -127,9 +127,22 @@
     for (auto& backdrop_topic : backdrop_screen_update.next_topics()) {
       AmbientModeTopic ambient_topic;
       DCHECK(backdrop_topic.has_url());
-      ambient_topic.url = backdrop_topic.url();
+
       if (backdrop_topic.has_portrait_image_url())
-        ambient_topic.portrait_image_url = backdrop_topic.portrait_image_url();
+        ambient_topic.url = backdrop_topic.portrait_image_url();
+      else
+        ambient_topic.url = backdrop_topic.url();
+
+      if (backdrop_topic.has_related_topic()) {
+        if (backdrop_topic.related_topic().has_portrait_image_url()) {
+          ambient_topic.related_image_url =
+              backdrop_topic.related_topic().portrait_image_url();
+        } else {
+          ambient_topic.related_image_url =
+              backdrop_topic.related_topic().url();
+        }
+      }
+
       BuildBackdropTopicDetails(backdrop_topic, ambient_topic);
       screen_update.next_topics.emplace_back(ambient_topic);
     }
diff --git a/ash/ambient/model/ambient_backend_model.h b/ash/ambient/model/ambient_backend_model.h
index 7d295f8f..bdad83d 100644
--- a/ash/ambient/model/ambient_backend_model.h
+++ b/ash/ambient/model/ambient_backend_model.h
@@ -34,6 +34,7 @@
   bool IsNull() const;
 
   gfx::ImageSkia photo;
+  gfx::ImageSkia related_photo;
   std::string details;
 };
 
diff --git a/ash/ambient/ui/ambient_background_image_view.cc b/ash/ambient/ui/ambient_background_image_view.cc
index b4d28189..ae4b540 100644
--- a/ash/ambient/ui/ambient_background_image_view.cc
+++ b/ash/ambient/ui/ambient_background_image_view.cc
@@ -6,17 +6,22 @@
 
 #include <memory>
 
+#include "ash/ambient/ambient_constants.h"
 #include "ash/ambient/ui/glanceable_info_view.h"
 #include "ash/ambient/util/ambient_util.h"
 #include "ash/assistant/ui/assistant_view_ids.h"
 #include "base/rand_util.h"
 #include "ui/events/event.h"
 #include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/image/image_skia_operations.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/fill_layout.h"
+#include "ui/views/layout/flex_layout.h"
+#include "ui/views/layout/flex_layout_types.h"
 #include "ui/views/metadata/metadata_impl_macros.h"
+#include "ui/views/view_class_properties.h"
 
 namespace ash {
 
@@ -39,6 +44,37 @@
 int current_x_translation = 0;
 int current_y_translation = 0;
 
+const views::FlexSpecification kUnboundedScaleToZero(
+    views::MinimumFlexSizeRule::kScaleToZero,
+    views::MaximumFlexSizeRule::kUnbounded);
+
+gfx::ImageSkia ResizeImage(const gfx::ImageSkia& image,
+                           const gfx::Size& view_size) {
+  if (image.isNull())
+    return gfx::ImageSkia();
+
+  const double image_width = image.width();
+  const double image_height = image.height();
+  const double view_width = view_size.width();
+  const double view_height = view_size.height();
+  const double horizontal_ratio = view_width / image_width;
+  const double vertical_ratio = view_height / image_height;
+  const double image_ratio = image_height / image_width;
+  const double view_ratio = view_height / view_width;
+
+  // If the image and the container view has the same orientation, e.g. both
+  // portrait, the |scale| will make the image filled the whole view with
+  // possible cropping on one direction. If they are in different orientation,
+  // the |scale| will display the image in the view without any cropping, but
+  // with empty background.
+  const double scale = (image_ratio - 1) * (view_ratio - 1) > 0
+                           ? std::max(horizontal_ratio, vertical_ratio)
+                           : std::min(horizontal_ratio, vertical_ratio);
+  const gfx::Size& resized = gfx::ScaleToCeiledSize(image.size(), scale);
+  return gfx::ImageSkiaOperations::CreateResizedImage(
+      image, skia::ImageOperations::RESIZE_BEST, resized);
+}
+
 }  // namespace
 
 AmbientBackgroundImageView::AmbientBackgroundImageView(
@@ -65,10 +101,43 @@
   }
 }
 
-void AmbientBackgroundImageView::UpdateImage(const gfx::ImageSkia& img) {
-  image_view_->SetImage(img);
+void AmbientBackgroundImageView::OnBoundsChanged(
+    const gfx::Rect& previous_bounds) {
+  if (!GetVisible())
+    return;
+
+  if (width() == 0)
+    return;
+
+  // When bounds changes, recalculate the visibility of related image view.
+  UpdateRelatedImageViewVisibility();
+}
+
+void AmbientBackgroundImageView::OnViewBoundsChanged(
+    views::View* observed_view) {
+  if (observed_view == image_view_)
+    SetResizedImage(image_view_, image_unscaled_);
+  else
+    SetResizedImage(related_image_view_, related_image_unscaled_);
+}
+
+void AmbientBackgroundImageView::UpdateImage(
+    const gfx::ImageSkia& image,
+    const gfx::ImageSkia& related_image) {
+  image_unscaled_ = image;
+  related_image_unscaled_ = related_image;
 
   UpdateGlanceableInfoPosition();
+
+  const bool has_change = UpdateRelatedImageViewVisibility();
+
+  // If there is no change in the visibility of related image view, call
+  // SetResizedImages() directly. Otherwise it will be called from
+  // OnViewBoundsChanged().
+  if (!has_change) {
+    SetResizedImage(image_view_, image_unscaled_);
+    SetResizedImage(related_image_view_, related_image_unscaled_);
+  }
 }
 
 void AmbientBackgroundImageView::UpdateImageDetails(
@@ -80,15 +149,49 @@
   return image_view_->GetImage();
 }
 
-gfx::Rect AmbientBackgroundImageView::GetCurrentImageBoundsForTesting() const {
+gfx::Rect AmbientBackgroundImageView::GetImageBoundsForTesting() const {
   return image_view_->GetImageBounds();
 }
 
+gfx::Rect AmbientBackgroundImageView::GetRelatedImageBoundsForTesting() const {
+  return related_image_view_->GetVisible()
+             ? related_image_view_->GetImageBounds()
+             : gfx::Rect();
+}
+
+void AmbientBackgroundImageView::ResetRelatedImageForTesting() {
+  related_image_unscaled_ = gfx::ImageSkia();
+  UpdateRelatedImageViewVisibility();
+}
+
 void AmbientBackgroundImageView::InitLayout() {
   SetLayoutManager(std::make_unique<views::FillLayout>());
 
-  // Inits the image view. This view should have the same size of the screen.
-  image_view_ = AddChildView(std::make_unique<views::ImageView>());
+  // Inits container for images.
+  image_container_ = AddChildView(std::make_unique<views::View>());
+  views::FlexLayout* image_layout =
+      image_container_->SetLayoutManager(std::make_unique<views::FlexLayout>());
+  image_layout->SetOrientation(views::LayoutOrientation::kHorizontal);
+  image_layout->SetMainAxisAlignment(views::LayoutAlignment::kCenter);
+  image_layout->SetCrossAxisAlignment(views::LayoutAlignment::kStretch);
+  image_view_ =
+      image_container_->AddChildView(std::make_unique<views::ImageView>());
+  // Set a place holder size for Flex layout to assign bounds.
+  image_view_->SetPreferredSize(gfx::Size(1, 1));
+  image_view_->SetProperty(views::kFlexBehaviorKey, kUnboundedScaleToZero);
+  observed_views_.Add(image_view_);
+
+  related_image_view_ =
+      image_container_->AddChildView(std::make_unique<views::ImageView>());
+  // Set a place holder size for Flex layout to assign bounds.
+  related_image_view_->SetPreferredSize(gfx::Size(1, 1));
+  related_image_view_->SetProperty(views::kFlexBehaviorKey,
+                                   kUnboundedScaleToZero);
+  observed_views_.Add(related_image_view_);
+
+  // Set spacing between two images.
+  related_image_view_->SetProperty(
+      views::kMarginsKey, gfx::Insets(0, kMarginLeftOfRelatedImageDip, 0, 0));
 
   gfx::Insets shadow_insets =
       gfx::ShadowValue::GetMargin(ambient::util::GetTextShadowValues());
@@ -161,6 +264,41 @@
   details_label_->layer()->SetTransform(transform);
 }
 
+bool AmbientBackgroundImageView::UpdateRelatedImageViewVisibility() {
+  const bool did_show_pair = related_image_view_->GetVisible();
+  const bool show_pair = IsLandscapeOrientation() && HasPairedPortraitImages();
+  related_image_view_->SetVisible(show_pair);
+  return did_show_pair != show_pair;
+}
+
+void AmbientBackgroundImageView::SetResizedImage(
+    views::ImageView* image_view,
+    const gfx::ImageSkia& image_unscaled) {
+  if (!image_view->GetVisible())
+    return;
+
+  if (image_unscaled.isNull())
+    return;
+
+  image_view->SetImage(ResizeImage(image_unscaled, image_view->size()));
+
+  // Intend to update the image origin in image view.
+  // There is no bounds change or preferred size change when updating image from
+  // landscape to portrait when device is in portrait orientation because we
+  // only show one photo. Call ResetImageSize() to trigger UpdateImageOrigin().
+  image_view->ResetImageSize();
+}
+
+bool AmbientBackgroundImageView::IsLandscapeOrientation() const {
+  return width() > height();
+}
+
+bool AmbientBackgroundImageView::HasPairedPortraitImages() const {
+  const auto& primary_image = image_unscaled_;
+  return !primary_image.isNull() && !related_image_unscaled_.isNull() &&
+         primary_image.height() > primary_image.width();
+}
+
 BEGIN_METADATA(AmbientBackgroundImageView, views::View)
 END_METADATA
 
diff --git a/ash/ambient/ui/ambient_background_image_view.h b/ash/ambient/ui/ambient_background_image_view.h
index fbbb046e..efffebe 100644
--- a/ash/ambient/ui/ambient_background_image_view.h
+++ b/ash/ambient/ui/ambient_background_image_view.h
@@ -9,9 +9,11 @@
 
 #include "ash/ambient/ui/ambient_view_delegate.h"
 #include "ash/ash_export.h"
+#include "base/scoped_observer.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/metadata/metadata_header_macros.h"
 #include "ui/views/view.h"
+#include "ui/views/view_observer.h"
 
 namespace views {
 class Label;
@@ -25,7 +27,8 @@
 // A custom ImageView to display photo image and details information on ambient.
 // It also handles specific mouse/gesture events to dismiss ambient when user
 // interacts with the background photos.
-class ASH_EXPORT AmbientBackgroundImageView : public views::View {
+class ASH_EXPORT AmbientBackgroundImageView : public views::View,
+                                              public views::ViewObserver {
  public:
   METADATA_HEADER(AmbientBackgroundImageView);
 
@@ -34,36 +37,60 @@
   AmbientBackgroundImageView& operator=(AmbientBackgroundImageView&) = delete;
   ~AmbientBackgroundImageView() override;
 
-  // views::View
+  // views::View:
   bool OnMousePressed(const ui::MouseEvent& event) override;
   void OnGestureEvent(ui::GestureEvent* event) override;
+  void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
 
-  // Updates the display image.
-  void UpdateImage(const gfx::ImageSkia& img);
+  // views::ViewObserver:
+  void OnViewBoundsChanged(views::View* observed_view) override;
+
+  // Updates the display images.
+  void UpdateImage(const gfx::ImageSkia& image,
+                   const gfx::ImageSkia& related_image);
 
   // Updates the details for the currently displayed image.
   void UpdateImageDetails(const base::string16& details);
 
   const gfx::ImageSkia& GetCurrentImage();
 
-  gfx::Rect GetCurrentImageBoundsForTesting() const;
+  gfx::Rect GetImageBoundsForTesting() const;
+  gfx::Rect GetRelatedImageBoundsForTesting() const;
+  void ResetRelatedImageForTesting();
 
  private:
   void InitLayout();
 
   void UpdateGlanceableInfoPosition();
 
+  bool UpdateRelatedImageViewVisibility();
+  void SetResizedImage(views::ImageView* image_view,
+                       const gfx::ImageSkia& image_unscaled);
+
+  // Whether the device is in landscape orientation.
+  bool IsLandscapeOrientation() const;
+
+  bool HasPairedPortraitImages() const;
+
   // Owned by |AmbientController| and should always outlive |this|.
   AmbientViewDelegate* delegate_ = nullptr;
 
-  // View to display the current image on ambient. Owned by the view hierarchy.
+  // View to display current image(s) on ambient. Owned by the view hierarchy.
+  views::View* image_container_ = nullptr;
   views::ImageView* image_view_ = nullptr;
+  views::ImageView* related_image_view_ = nullptr;
+
+  // The unscaled images used for scaling and displaying in different bounds.
+  gfx::ImageSkia image_unscaled_;
+  gfx::ImageSkia related_image_unscaled_;
 
   GlanceableInfoView* glanceable_info_view_ = nullptr;
 
   // Label to show details text, i.e. attribution, to be displayed for the
   // current image. Owned by the view hierarchy.
   views::Label* details_label_ = nullptr;
+
+  ScopedObserver<views::View, views::ViewObserver> observed_views_{this};
 };
 }  // namespace ash
 
diff --git a/ash/ambient/ui/photo_view.cc b/ash/ambient/ui/photo_view.cc
index 95e23cae7..6b5cd5a 100644
--- a/ash/ambient/ui/photo_view.cc
+++ b/ash/ambient/ui/photo_view.cc
@@ -21,7 +21,6 @@
 #include "ui/compositor/animation_throughput_reporter.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
-#include "ui/gfx/image/image_skia_operations.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/layout/fill_layout.h"
 
@@ -36,32 +35,6 @@
   base::UmaHistogramPercentage(kPhotoTransitionSmoothness, value);
 }
 
-gfx::ImageSkia ResizeImage(const gfx::ImageSkia& image,
-                           const gfx::Size& view_size) {
-  if (image.isNull())
-    return gfx::ImageSkia();
-
-  const double image_width = image.width();
-  const double image_height = image.height();
-  const double view_width = view_size.width();
-  const double view_height = view_size.height();
-  const double horizontal_ratio = view_width / image_width;
-  const double vertical_ratio = view_height / image_height;
-  const double image_ratio = image_height / image_width;
-  const double view_ratio = view_height / view_width;
-
-  // If the image and the container view has the same orientation, e.g. both
-  // portrait, the |scale| will make the image filled the whole view with
-  // possible cropping on one direction. If they are in different orientation,
-  // the |scale| will display the image in the view without any cropping, but
-  // with empty background.
-  const double scale = (image_ratio - 1) * (view_ratio - 1) > 0
-                           ? std::max(horizontal_ratio, vertical_ratio)
-                           : std::min(horizontal_ratio, vertical_ratio);
-  const gfx::Size& resized = gfx::ScaleToCeiledSize(image.size(), scale);
-  return gfx::ImageSkiaOperations::CreateResizedImage(
-      image, skia::ImageOperations::RESIZE_BEST, resized);
-}
 
 }  // namespace
 
@@ -80,14 +53,6 @@
   return "PhotoView";
 }
 
-void PhotoView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
-  for (const int index : {0, 1}) {
-    auto image = images_unscaled_[index];
-    auto image_resized = ResizeImage(image, size());
-    image_views_[index]->UpdateImage(image_resized);
-  }
-}
-
 void PhotoView::OnImagesChanged() {
   // If NeedToAnimate() is true, will start transition animation and
   // UpdateImages() when animation completes. Otherwise, update images
@@ -123,12 +88,11 @@
 void PhotoView::UpdateImages() {
   auto* model = delegate_->GetAmbientBackendModel();
   auto& next_image = model->GetNextImage();
-  images_unscaled_[image_index_] = next_image.photo;
-  if (images_unscaled_[image_index_].isNull())
+  if (next_image.photo.isNull())
     return;
 
-  auto next_resized = ResizeImage(images_unscaled_[image_index_], size());
-  image_views_[image_index_]->UpdateImage(next_resized);
+  image_views_[image_index_]->UpdateImage(next_image.photo,
+                                          next_image.related_photo);
   image_views_[image_index_]->UpdateImageDetails(
       base::UTF8ToUTF16(next_image.details));
   image_index_ = 1 - image_index_;
@@ -178,7 +142,7 @@
 bool PhotoView::NeedToAnimateTransition() const {
   // Can do transition animation if both two images in |images_unscaled_| are
   // not nullptr. Check the image index 1 is enough.
-  return !images_unscaled_[1].isNull();
+  return !image_views_[1]->GetCurrentImage().isNull();
 }
 
 const gfx::ImageSkia& PhotoView::GetCurrentImagesForTesting() {
diff --git a/ash/ambient/ui/photo_view.h b/ash/ambient/ui/photo_view.h
index f35af10..457b043 100644
--- a/ash/ambient/ui/photo_view.h
+++ b/ash/ambient/ui/photo_view.h
@@ -35,7 +35,6 @@
 
   // views::View:
   const char* GetClassName() const override;
-  void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
 
   // AmbientBackendModelObserver:
   void OnImagesChanged() override;
@@ -47,7 +46,9 @@
   friend class AmbientAshTestBase;
 
   void Init();
+
   void UpdateImages();
+
   void StartTransitionAnimation();
 
   // Return if can start transition animation.
@@ -62,9 +63,6 @@
   // Image containers used for animation. Owned by view hierarchy.
   AmbientBackgroundImageView* image_views_[2]{nullptr, nullptr};
 
-  // The unscaled images used for scaling and displaying in different bounds.
-  gfx::ImageSkia images_unscaled_[2];
-
   // The index of |image_views_| to update the next image.
   int image_index_ = 0;
 };
diff --git a/ash/ambient/ui/photo_view_unittest.cc b/ash/ambient/ui/photo_view_unittest.cc
index c1dd844..9663844 100644
--- a/ash/ambient/ui/photo_view_unittest.cc
+++ b/ash/ambient/ui/photo_view_unittest.cc
@@ -32,8 +32,9 @@
 
   // Image should be full width. Image height should extend above and below the
   // visible part of the screen.
-  ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(),
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
             gfx::Rect(/*x=*/0, /*y=*/-200, /*width=*/600, /*height=*/1200));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(), gfx::Rect());
 }
 
 // Test that image is scaled to fill screen width when the image is landscape
@@ -52,14 +53,92 @@
 
   // Image should be full width. Image should have equal empty space top and
   // bottom.
-  ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(),
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
             gfx::Rect(/*x=*/0, /*y=*/200, /*width=*/600, /*height=*/400));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(), gfx::Rect());
 }
 
-// Test that image is scaled to fill screen height when the image is portrait
-// and screen is landscape. There will be black bars to the left and right of
-// the image, as the width of the image is less than the width of the screen.
-TEST_F(AmbientPhotoViewTest, ShouldResizePortraitImageForLandscapeScreen) {
+// Test that two portrait images are scaled and tiled to fill screen when the
+// screen is landscape.
+TEST_F(AmbientPhotoViewTest, ShouldTileTwoPortraitImagesForLandscapeScreen) {
+  SetPhotoViewImageSize(/*width=*/10, /*height=*/20);
+
+  UpdateDisplay("808x600");
+
+  ShowAmbientScreen();
+
+  FastForwardToNextImage();
+
+  auto* image_view = GetAmbientBackgroundImageView();
+
+  // Will tile two portrait images. Each image will fill 400x600 area with 8px
+  // spaing in between.
+  // Image should be full width. Image height should extend above and below the
+  // visible part of the view.
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-100, /*width=*/400, /*height=*/800));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-100, /*width=*/400, /*height=*/800));
+}
+
+// Test that two portrait images are scaled and tiled to fill screen when the
+// screen is landscape. For odd screen width, the first image will take one more
+// pixel.
+TEST_F(AmbientPhotoViewTest,
+       ShouldTileTwoPortraitImagesForLandscapeScreenWithOddWidth) {
+  SetPhotoViewImageSize(/*width=*/10, /*height=*/20);
+
+  constexpr int kScreenWidth = 809;
+  constexpr int kScreenHeight = 600;
+  std::string display_size = base::NumberToString(kScreenWidth) + "x" +
+                             base::NumberToString(kScreenHeight);
+  UpdateDisplay(display_size);
+
+  ShowAmbientScreen();
+
+  FastForwardToNextImage();
+
+  auto* image_view = GetAmbientBackgroundImageView();
+
+  // Will tile two portrait images.
+  // The first image will fill 401x802 area with 8px spaing in between. Image
+  // should be full width. Image height should extend above and below the
+  // visible part of the view.
+  const int image_width = (kScreenWidth - kMarginLeftOfRelatedImageDip + 1) / 2;
+  const int image_height = 20 * image_width / 10;
+  const int y = (kScreenHeight - image_height) / 2;
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/y, /*width=*/image_width,
+                      /*height=*/image_height));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-100, /*width=*/400, /*height=*/800));
+}
+
+// Test that landscape images will not be tiled when screen is landscape.
+TEST_F(AmbientPhotoViewTest,
+       ShouldNotTileTwoLandscapeImagesForLandscapeScreen) {
+  SetPhotoViewImageSize(/*width=*/20, /*height=*/10);
+
+  UpdateDisplay("808x600");
+
+  ShowAmbientScreen();
+
+  FastForwardToNextImage();
+
+  auto* image_view = GetAmbientBackgroundImageView();
+
+  // Only show one landscape image.
+  // Image should be full height. Image width should extend equally to the left
+  // and right of the visible part of the screen.
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/-196, /*y=*/0, /*width=*/1200, /*height=*/600));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(), gfx::Rect());
+}
+
+// Test that only have one available image will not be tiled when screen is
+// landscape.
+TEST_F(AmbientPhotoViewTest,
+       ShouldNotTileIfRelatedImageIsNullForLandscapeScreen) {
   SetPhotoViewImageSize(/*width=*/10, /*height=*/20);
 
   UpdateDisplay("800x600");
@@ -70,17 +149,25 @@
 
   auto* image_view = GetAmbientBackgroundImageView();
 
-  // Image should be full height. Image width should have equal empty space on
-  // left and right.
-  ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(),
-            gfx::Rect(/*x=*/250, /*y=*/0, /*width=*/300, /*height=*/600));
+  // Remove the related image.
+  image_view->ResetRelatedImageForTesting();
+
+  // Trigger layout.
+  UpdateDisplay("808x600");
+
+  // Only show one portrait image.
+  // Image should be full height. Image should have equal empty space left and
+  // right.
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/254, /*y=*/0, /*width=*/300, /*height=*/600));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(), gfx::Rect());
 }
 
 // Test that image is scaled to fill screen height when the image is landscape
 // and the screen is landscape. The image will be zoomed in and the left and
 // right will be cut off, as the width of the image is greater than the width of
 // the screen.
-TEST_F(AmbientPhotoViewTest, ShouldResizeLandscapeImageForFillLandscapeScreen) {
+TEST_F(AmbientPhotoViewTest, ShouldResizeLandscapeImageForLandscapeScreen) {
   SetPhotoViewImageSize(/*width=*/30, /*height=*/20);
 
   UpdateDisplay("800x600");
@@ -93,8 +180,131 @@
 
   // Image should be full height. Image width should extend equally to the left
   // and right of the visible part of the screen.
-  ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(),
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
             gfx::Rect(/*x=*/-50, /*y=*/0, /*width=*/900, /*height=*/600));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(), gfx::Rect());
+}
+
+// Test that when rotates to portrait screen, will dynamically only show one
+// portrait image.
+TEST_F(AmbientPhotoViewTest, ShouldNotTileWhenRotateToPortraitScreen) {
+  SetPhotoViewImageSize(/*width=*/10, /*height=*/20);
+
+  UpdateDisplay("808x600");
+
+  ShowAmbientScreen();
+
+  FastForwardToNextImage();
+
+  auto* image_view = GetAmbientBackgroundImageView();
+
+  // Will tile two portrait images. Each image will fill 400x600 area with 8px
+  // spaing in between.
+  // Image should be full width. Image height should extend above and below the
+  // visible part of the view.
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-100, /*width=*/400, /*height=*/800));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-100, /*width=*/400, /*height=*/800));
+
+  // Rotate screen.
+  UpdateDisplay("600x808");
+  // Only one image will show.
+  // Image should be full width. Image height should extend above and below the
+  // visible part of the screen.
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-196, /*width=*/600, /*height=*/1200));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(), gfx::Rect());
+}
+
+// Test that when rotates to landscape screen, will dynamically tile two
+// portrait images.
+TEST_F(AmbientPhotoViewTest, ShouldTileWhenRotateToLandscapeScreen) {
+  SetPhotoViewImageSize(/*width=*/10, /*height=*/20);
+
+  UpdateDisplay("600x808");
+
+  ShowAmbientScreen();
+
+  FastForwardToNextImage();
+
+  auto* image_view = GetAmbientBackgroundImageView();
+
+  // Only one image will show.
+  // Image should be full width. Image height should extend above and below the
+  // visible part of the screen.
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-196, /*width=*/600, /*height=*/1200));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(), gfx::Rect());
+
+  // Rotate screen.
+  UpdateDisplay("808x600");
+
+  // Will tile two portrait images. Each image will fill 400x600 area with 8px
+  // spaing in between.
+  // Image should be full width. Image height should extend above and below the
+  // visible part of the view.
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-100, /*width=*/400, /*height=*/800));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-100, /*width=*/400, /*height=*/800));
+}
+
+// Test that two protrat images will resize when bounds changes in landscape.
+TEST_F(AmbientPhotoViewTest, ShouldResizeTiledPortraitImagesWhenBoundsChanged) {
+  SetPhotoViewImageSize(/*width=*/10, /*height=*/20);
+
+  UpdateDisplay("808x600");
+
+  ShowAmbientScreen();
+
+  FastForwardToNextImage();
+
+  auto* image_view = GetAmbientBackgroundImageView();
+
+  // Will tile two portrait images. Each image will fill 400x600 area with 8px
+  // spaing in between.
+  // Image should be full width. Image height should extend above and below the
+  // visible part of the view.
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-100, /*width=*/400, /*height=*/800));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-100, /*width=*/400, /*height=*/800));
+
+  // Bounds changes so that image will be shown in portrait view.
+  UpdateDisplay("508x200");
+
+  // Will tile two portrait images. Each image will fill 250x200 area with 8px
+  // spaing in between.
+  // Image should be full height. Image should have equal empty space left and
+  // right.
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/75, /*y=*/0, /*width=*/100, /*height=*/200));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(),
+            gfx::Rect(/*x=*/75, /*y=*/0, /*width=*/100, /*height=*/200));
+
+  // Bounds changes so that image will be shown in portrait view.
+  UpdateDisplay("308x200");
+
+  // Will tile two portrait images. Each image will fill 150x200 area with 8px
+  // spaing in between.
+  // Image should be full width. Image height should extend above and below the
+  // visible part of the view.
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-50, /*width=*/150, /*height=*/300));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-50, /*width=*/150, /*height=*/300));
+
+  // Bounds changes to exact aspect ratio of the image.
+  UpdateDisplay("208x200");
+
+  // Will tile two portrait images. Each image will fill 100x200 area with 8px
+  // spaing in between.
+  // Image should be full width and height.
+  ASSERT_EQ(image_view->GetImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/0, /*width=*/100, /*height=*/200));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/0, /*width=*/100, /*height=*/200));
 }
 
 }  // namespace ash
diff --git a/ash/public/cpp/ambient/ambient_backend_controller.cc b/ash/public/cpp/ambient/ambient_backend_controller.cc
index f08b7bda..2d1a1be 100644
--- a/ash/public/cpp/ambient/ambient_backend_controller.cc
+++ b/ash/public/cpp/ambient/ambient_backend_controller.cc
@@ -31,10 +31,6 @@
 
 AmbientModeTopic::~AmbientModeTopic() = default;
 
-std::string AmbientModeTopic::GetUrl() const {
-  return portrait_image_url.value_or(url);
-}
-
 // WeatherInfo------------------------------------------------------------------
 WeatherInfo::WeatherInfo() = default;
 
diff --git a/ash/public/cpp/ambient/ambient_backend_controller.h b/ash/public/cpp/ambient/ambient_backend_controller.h
index 8811751c..9edbc4c 100644
--- a/ash/public/cpp/ambient/ambient_backend_controller.h
+++ b/ash/public/cpp/ambient/ambient_backend_controller.h
@@ -27,9 +27,6 @@
   AmbientModeTopic& operator=(const AmbientModeTopic&);
   ~AmbientModeTopic();
 
-  // Returns a non-empty url to load the landscape or portrait image.
-  std::string GetUrl() const;
-
   // Details, i.e. the attribution, to be displayed for the current photo on
   // ambient.
   std::string details;
@@ -37,9 +34,8 @@
   // Image url.
   std::string url;
 
-  // Optional for non-cropped portrait style images. The same image as in
-  // |url| but it is not cropped and is better for portrait displaying.
-  base::Optional<std::string> portrait_image_url;
+  // Only support portrait image tiling in landscape orientation.
+  base::Optional<std::string> related_image_url;
 };
 
 // WeatherInfo contains the weather information we need for rendering a
diff --git a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc
index 228325b..251e826 100644
--- a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc
+++ b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc
@@ -81,6 +81,7 @@
   ash::AmbientModeTopic topic;
   topic.url = kFakeUrl;
   topic.details = kFakeDetails;
+  topic.related_image_url = kFakeUrl;
 
   ash::WeatherInfo weather_info;
   weather_info.temp_f = .0f;
diff --git a/ash/system/holding_space/holding_space_item_chip_view.cc b/ash/system/holding_space/holding_space_item_chip_view.cc
index e15ddc0..959b61d 100644
--- a/ash/system/holding_space/holding_space_item_chip_view.cc
+++ b/ash/system/holding_space/holding_space_item_chip_view.cc
@@ -30,10 +30,8 @@
 
 namespace ash {
 
-HoldingSpaceItemChipView::HoldingSpaceItemChipView(
-    HoldingSpaceItemViewDelegate* delegate,
-    const HoldingSpaceItem* item)
-    : HoldingSpaceItemView(delegate, item) {
+HoldingSpaceItemChipView::HoldingSpaceItemChipView(const HoldingSpaceItem* item)
+    : HoldingSpaceItemView(item) {
   auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::Orientation::kHorizontal,
       gfx::Insets(kHoldingSpaceChipPadding), kHoldingSpaceChipChildSpacing));
diff --git a/ash/system/holding_space/holding_space_item_chip_view.h b/ash/system/holding_space/holding_space_item_chip_view.h
index 71479cd9e..c2ca9d6 100644
--- a/ash/system/holding_space/holding_space_item_chip_view.h
+++ b/ash/system/holding_space/holding_space_item_chip_view.h
@@ -21,7 +21,6 @@
 namespace ash {
 
 class HoldingSpaceItem;
-class HoldingSpaceItemViewDelegate;
 
 namespace tray {
 class RoundedImageView;
@@ -34,8 +33,7 @@
  public:
   METADATA_HEADER(HoldingSpaceItemChipView);
 
-  HoldingSpaceItemChipView(HoldingSpaceItemViewDelegate* delegate,
-                           const HoldingSpaceItem* item);
+  explicit HoldingSpaceItemChipView(const HoldingSpaceItem* item);
   HoldingSpaceItemChipView(const HoldingSpaceItemChipView&) = delete;
   HoldingSpaceItemChipView& operator=(const HoldingSpaceItemChipView&) = delete;
   ~HoldingSpaceItemChipView() override;
diff --git a/ash/system/holding_space/holding_space_item_chips_container.cc b/ash/system/holding_space/holding_space_item_chips_container.cc
index 7ca8638..0890800 100644
--- a/ash/system/holding_space/holding_space_item_chips_container.cc
+++ b/ash/system/holding_space/holding_space_item_chips_container.cc
@@ -5,6 +5,9 @@
 #include "ash/system/holding_space/holding_space_item_chips_container.h"
 
 #include "ash/public/cpp/holding_space/holding_space_constants.h"
+#include "ash/public/cpp/holding_space/holding_space_item.h"
+#include "ash/system/holding_space/holding_space_item_chip_view.h"
+#include "base/debug/stack_trace.h"
 #include "ui/views/layout/layout_manager_base.h"
 #include "ui/views/layout/proposed_layout.h"
 
diff --git a/ash/system/holding_space/holding_space_item_chips_container.h b/ash/system/holding_space/holding_space_item_chips_container.h
index e7c3ffe..ac7b352 100644
--- a/ash/system/holding_space/holding_space_item_chips_container.h
+++ b/ash/system/holding_space/holding_space_item_chips_container.h
@@ -10,7 +10,8 @@
 
 namespace ash {
 
-// A container view which arranges item chips into a 2 column grid.
+// A container view which automatically arranges item chips into a 2 column
+// grid.
 class HoldingSpaceItemChipsContainer : public views::View {
  public:
   HoldingSpaceItemChipsContainer();
diff --git a/ash/system/holding_space/holding_space_item_context_menu.cc b/ash/system/holding_space/holding_space_item_context_menu.cc
new file mode 100644
index 0000000..bf7974f
--- /dev/null
+++ b/ash/system/holding_space/holding_space_item_context_menu.cc
@@ -0,0 +1,106 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/system/holding_space/holding_space_item_context_menu.h"
+
+#include "ash/public/cpp/holding_space/holding_space_client.h"
+#include "ash/public/cpp/holding_space/holding_space_constants.h"
+#include "ash/public/cpp/holding_space/holding_space_controller.h"
+#include "ash/public/cpp/holding_space/holding_space_model.h"
+#include "ash/resources/vector_icons/vector_icons.h"
+#include "ash/strings/grit/ash_strings.h"
+#include "ash/system/holding_space/holding_space_item_view.h"
+#include "base/bind.h"
+#include "net/base/mime_util.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/simple_menu_model.h"
+#include "ui/views/controls/menu/menu_runner.h"
+#include "ui/views/vector_icons.h"
+#include "ui/views/view.h"
+
+namespace ash {
+
+HoldingSpaceItemContextMenu::HoldingSpaceItemContextMenu(
+    const HoldingSpaceItem* item)
+    : item_(item) {}
+
+HoldingSpaceItemContextMenu::~HoldingSpaceItemContextMenu() = default;
+
+void HoldingSpaceItemContextMenu::ShowContextMenuForViewImpl(
+    views::View* source,
+    const gfx::Point& point,
+    ui::MenuSourceType source_type) {
+  int run_types = views::MenuRunner::USE_TOUCHABLE_LAYOUT |
+                  views::MenuRunner::CONTEXT_MENU |
+                  views::MenuRunner::FIXED_ANCHOR;
+
+  context_menu_runner_ =
+      std::make_unique<views::MenuRunner>(BuildMenuModel(), run_types);
+
+  context_menu_runner_->RunMenuAt(
+      source->GetWidget(), nullptr /*button_controller*/,
+      source->GetBoundsInScreen(), views::MenuAnchorPosition::kBubbleRight,
+      source_type);
+}
+
+void HoldingSpaceItemContextMenu::ExecuteCommand(int command_id,
+                                                 int event_flags) {
+  switch (command_id) {
+    case HoldingSpaceCommandId::kCopyImageToClipboard:
+      HoldingSpaceController::Get()->client()->CopyImageToClipboard(
+          *item_, base::DoNothing());
+      break;
+    case HoldingSpaceCommandId::kPinItem:
+      HoldingSpaceController::Get()->client()->PinItem(*item_);
+      break;
+    case HoldingSpaceCommandId::kShowInFolder:
+      HoldingSpaceController::Get()->client()->ShowItemInFolder(
+          *item_, base::DoNothing());
+      break;
+    case HoldingSpaceCommandId::kUnpinItem:
+      HoldingSpaceController::Get()->client()->UnpinItem(*item_);
+      break;
+  }
+}
+
+ui::SimpleMenuModel* HoldingSpaceItemContextMenu::BuildMenuModel() {
+  context_menu_model_ = std::make_unique<ui::SimpleMenuModel>(this);
+  context_menu_model_->AddItemWithIcon(
+      HoldingSpaceCommandId::kShowInFolder,
+      l10n_util::GetStringUTF16(
+          IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_SHOW_IN_FOLDER),
+      ui::ImageModel::FromVectorIcon(kFolderIcon));
+
+  std::string mime_type;
+  const bool is_image =
+      net::GetMimeTypeFromFile(item_->file_path(), &mime_type) &&
+      net::MatchesMimeType(kMimeTypeImage, mime_type);
+
+  if (is_image) {
+    context_menu_model_->AddItemWithIcon(
+        HoldingSpaceCommandId::kCopyImageToClipboard,
+        l10n_util::GetStringUTF16(
+            IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_COPY_IMAGE_TO_CLIPBOARD),
+        ui::ImageModel::FromVectorIcon(kCopyIcon));
+  }
+
+  const bool is_pinned = HoldingSpaceController::Get()->model()->GetItem(
+      HoldingSpaceItem::GetFileBackedItemId(HoldingSpaceItem::Type::kPinnedFile,
+                                            item_->file_path()));
+  if (!is_pinned) {
+    context_menu_model_->AddItemWithIcon(
+        HoldingSpaceCommandId::kPinItem,
+        l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_PIN),
+        ui::ImageModel::FromVectorIcon(views::kPinIcon));
+  } else {
+    context_menu_model_->AddItemWithIcon(
+        HoldingSpaceCommandId::kUnpinItem,
+        l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_UNPIN),
+        ui::ImageModel::FromVectorIcon(views::kUnpinIcon));
+  }
+
+  return context_menu_model_.get();
+}
+
+}  // namespace ash
diff --git a/ash/system/holding_space/holding_space_item_context_menu.h b/ash/system/holding_space/holding_space_item_context_menu.h
new file mode 100644
index 0000000..5371f67
--- /dev/null
+++ b/ash/system/holding_space/holding_space_item_context_menu.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 ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_CONTEXT_MENU_H_
+#define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_CONTEXT_MENU_H_
+
+#include <memory>
+
+#include "ash/ash_export.h"
+#include "ash/public/cpp/holding_space/holding_space_item.h"
+#include "ui/base/models/simple_menu_model.h"
+#include "ui/views/context_menu_controller.h"
+
+namespace views {
+class MenuRunner;
+}  // namespace views
+
+namespace ash {
+
+// This class handles creation of the context menu view and handling
+// commands available in the menu.
+class ASH_EXPORT HoldingSpaceItemContextMenu
+    : public views::ContextMenuController,
+      public ui::SimpleMenuModel::Delegate {
+ public:
+  explicit HoldingSpaceItemContextMenu(const HoldingSpaceItem* item);
+  HoldingSpaceItemContextMenu(const HoldingSpaceItemContextMenu&) = delete;
+  HoldingSpaceItemContextMenu& operator=(const HoldingSpaceItemContextMenu&) =
+      delete;
+  ~HoldingSpaceItemContextMenu() override;
+
+  // views::ContextMenuController:
+  void ShowContextMenuForViewImpl(views::View* source,
+                                  const gfx::Point& point,
+                                  ui::MenuSourceType source_type) override;
+
+  // SimpleMenuModel::Delegate:
+  void ExecuteCommand(int command_id, int event_flags) override;
+
+ private:
+  ui::SimpleMenuModel* BuildMenuModel();
+
+  std::unique_ptr<ui::SimpleMenuModel> context_menu_model_;
+  std::unique_ptr<views::MenuRunner> context_menu_runner_;
+
+  // The holding space item that this context menu's actions will effect.
+  const HoldingSpaceItem* const item_;
+};
+
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_CONTEXT_MENU_H_
diff --git a/ash/system/holding_space/holding_space_item_screenshot_view.cc b/ash/system/holding_space/holding_space_item_screenshot_view.cc
index 233f739..39e07b0 100644
--- a/ash/system/holding_space/holding_space_item_screenshot_view.cc
+++ b/ash/system/holding_space/holding_space_item_screenshot_view.cc
@@ -16,9 +16,8 @@
 namespace ash {
 
 HoldingSpaceItemScreenshotView::HoldingSpaceItemScreenshotView(
-    HoldingSpaceItemViewDelegate* delegate,
     const HoldingSpaceItem* item)
-    : HoldingSpaceItemView(delegate, item) {
+    : HoldingSpaceItemView(item) {
   SetLayoutManager(std::make_unique<views::FillLayout>());
 
   image_ = AddChildView(
diff --git a/ash/system/holding_space/holding_space_item_screenshot_view.h b/ash/system/holding_space/holding_space_item_screenshot_view.h
index 3f6e72f..ec5f8f1 100644
--- a/ash/system/holding_space/holding_space_item_screenshot_view.h
+++ b/ash/system/holding_space/holding_space_item_screenshot_view.h
@@ -13,7 +13,6 @@
 namespace ash {
 
 class HoldingSpaceItem;
-class HoldingSpaceItemViewDelegate;
 
 namespace tray {
 class RoundedImageView;
@@ -23,8 +22,7 @@
  public:
   METADATA_HEADER(HoldingSpaceItemScreenshotView);
 
-  HoldingSpaceItemScreenshotView(HoldingSpaceItemViewDelegate* delegate,
-                                 const HoldingSpaceItem* item);
+  explicit HoldingSpaceItemScreenshotView(const HoldingSpaceItem* item);
   HoldingSpaceItemScreenshotView(const HoldingSpaceItemScreenshotView&) =
       delete;
   HoldingSpaceItemScreenshotView& operator=(
diff --git a/ash/system/holding_space/holding_space_item_view.cc b/ash/system/holding_space/holding_space_item_view.cc
index 6508d51..e91cd9d 100644
--- a/ash/system/holding_space/holding_space_item_view.cc
+++ b/ash/system/holding_space/holding_space_item_view.cc
@@ -4,36 +4,41 @@
 
 #include "ash/system/holding_space/holding_space_item_view.h"
 
+#include "ash/public/cpp/holding_space/holding_space_client.h"
 #include "ash/public/cpp/holding_space/holding_space_constants.h"
+#include "ash/public/cpp/holding_space/holding_space_controller.h"
 #include "ash/public/cpp/holding_space/holding_space_item.h"
 #include "ash/public/cpp/shelf_config.h"
-#include "ash/system/holding_space/holding_space_item_view_delegate.h"
-#include "ui/base/class_property.h"
+#include "ash/strings/grit/ash_strings.h"
+#include "ash/system/holding_space/holding_space_item_context_menu.h"
+#include "base/bind_helpers.h"
+#include "ui/base/dragdrop/drag_drop_types.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/text_constants.h"
 #include "ui/views/accessibility/view_accessibility.h"
 #include "ui/views/controls/focus_ring.h"
 #include "ui/views/controls/highlight_path_generator.h"
+#include "ui/views/controls/menu/menu_runner.h"
 
 namespace ash {
 
 namespace {
 
-// A UI class property used to identify if a view is an instance of
-// `HoldingSpaceItemView`. Class name is not an adequate identifier as it may be
-// overridden by subclasses.
-DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIsHoldingSpaceItemViewProperty, false)
+// Helpers ---------------------------------------------------------------------
+
+// Attempts to open the specified holding space `item`.
+void OpenItem(const HoldingSpaceItem& item) {
+  HoldingSpaceController::Get()->client()->OpenItem(item, base::DoNothing());
+}
 
 }  // namespace
 
 // HoldingSpaceItemView --------------------------------------------------------
 
-HoldingSpaceItemView::HoldingSpaceItemView(
-    HoldingSpaceItemViewDelegate* delegate,
-    const HoldingSpaceItem* item)
-    : delegate_(delegate), item_(item) {
-  SetProperty(kIsHoldingSpaceItemViewProperty, true);
-
-  set_context_menu_controller(delegate_);
-  set_drag_controller(delegate_);
+HoldingSpaceItemView::HoldingSpaceItemView(const HoldingSpaceItem* item)
+    : item_(item),
+      context_menu_(std::make_unique<HoldingSpaceItemContextMenu>(item_)) {
+  set_context_menu_controller(context_menu_.get());
 
   SetPaintToLayer();
   layer()->SetFillsBoundsOpaquely(false);
@@ -49,14 +54,10 @@
                                                 kHoldingSpaceCornerRadius);
 }
 
-HoldingSpaceItemView::~HoldingSpaceItemView() {
-  delegate_->OnHoldingSpaceItemViewDestroyed(this);
-}
+HoldingSpaceItemView::~HoldingSpaceItemView() = default;
 
-// static
-HoldingSpaceItemView* HoldingSpaceItemView::Cast(views::View* view) {
-  DCHECK(view->GetProperty(kIsHoldingSpaceItemViewProperty));
-  return static_cast<HoldingSpaceItemView*>(view);
+int HoldingSpaceItemView::GetDragOperations(const gfx::Point& point) {
+  return ui::DragDropTypes::DRAG_COPY;
 }
 
 SkColor HoldingSpaceItemView::GetInkDropBaseColor() const {
@@ -64,15 +65,29 @@
 }
 
 void HoldingSpaceItemView::OnGestureEvent(ui::GestureEvent* event) {
-  delegate_->OnHoldingSpaceItemViewGestureEvent(this, *event);
+  if (event->type() == ui::ET_GESTURE_TAP)
+    OpenItem(*item());
 }
 
 bool HoldingSpaceItemView::OnKeyPressed(const ui::KeyEvent& event) {
-  return delegate_->OnHoldingSpaceItemViewKeyPressed(this, event);
+  if (event.key_code() == ui::KeyboardCode::VKEY_RETURN) {
+    OpenItem(*item());
+    return true;
+  }
+  return false;
 }
 
 bool HoldingSpaceItemView::OnMousePressed(const ui::MouseEvent& event) {
-  return delegate_->OnHoldingSpaceItemViewMousePressed(this, event);
+  if (event.flags() & ui::EF_IS_DOUBLE_CLICK) {
+    OpenItem(*item());
+    return true;
+  }
+  return false;
+}
+
+void HoldingSpaceItemView::WriteDragData(const gfx::Point& point,
+                                         ui::OSExchangeData* data) {
+  data->SetFilename(item_->file_path());
 }
 
 }  // namespace ash
diff --git a/ash/system/holding_space/holding_space_item_view.h b/ash/system/holding_space/holding_space_item_view.h
index 94c8067..9b6c7985 100644
--- a/ash/system/holding_space/holding_space_item_view.h
+++ b/ash/system/holding_space/holding_space_item_view.h
@@ -5,37 +5,38 @@
 #ifndef ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_VIEW_H_
 #define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_VIEW_H_
 
+#include <memory>
+
 #include "ash/ash_export.h"
+#include "ui/base/dragdrop/drag_drop_types.h"
 #include "ui/views/animation/ink_drop_host_view.h"
 
 namespace ash {
 
 class HoldingSpaceItem;
-class HoldingSpaceItemViewDelegate;
+class HoldingSpaceItemContextMenu;
 
 // Base class for HoldingSpaceItemChipView and HoldingSpaceItemScreenshotView.
 class ASH_EXPORT HoldingSpaceItemView : public views::InkDropHostView {
  public:
-  HoldingSpaceItemView(HoldingSpaceItemViewDelegate*, const HoldingSpaceItem*);
+  explicit HoldingSpaceItemView(const HoldingSpaceItem* item);
   HoldingSpaceItemView(const HoldingSpaceItemView&) = delete;
   HoldingSpaceItemView& operator=(const HoldingSpaceItemView&) = delete;
   ~HoldingSpaceItemView() override;
 
-  // Returns `view` cast as a `HoldingSpaceItemView`. Note that this performs a
-  // DCHECK to assert that `view` is in fact a `HoldingSpaceItemView` instance.
-  static HoldingSpaceItemView* Cast(views::View* view);
-
   // views::InkDropHostView:
+  int GetDragOperations(const gfx::Point& point) override;
   SkColor GetInkDropBaseColor() const override;
   void OnGestureEvent(ui::GestureEvent* event) override;
   bool OnKeyPressed(const ui::KeyEvent& event) override;
   bool OnMousePressed(const ui::MouseEvent& event) override;
+  void WriteDragData(const gfx::Point& point, ui::OSExchangeData*) override;
 
   const HoldingSpaceItem* item() const { return item_; }
 
  private:
-  HoldingSpaceItemViewDelegate* delegate_;
   const HoldingSpaceItem* const item_;
+  std::unique_ptr<HoldingSpaceItemContextMenu> const context_menu_;
 };
 
 }  // namespace ash
diff --git a/ash/system/holding_space/holding_space_item_view_delegate.cc b/ash/system/holding_space/holding_space_item_view_delegate.cc
deleted file mode 100644
index e98b61d7..0000000
--- a/ash/system/holding_space/holding_space_item_view_delegate.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/system/holding_space/holding_space_item_view_delegate.h"
-
-#include "ash/public/cpp/holding_space/holding_space_client.h"
-#include "ash/public/cpp/holding_space/holding_space_constants.h"
-#include "ash/public/cpp/holding_space/holding_space_controller.h"
-#include "ash/public/cpp/holding_space/holding_space_item.h"
-#include "ash/public/cpp/holding_space/holding_space_model.h"
-#include "ash/resources/vector_icons/vector_icons.h"
-#include "ash/strings/grit/ash_strings.h"
-#include "ash/system/holding_space/holding_space_item_view.h"
-#include "base/bind.h"
-#include "net/base/mime_util.h"
-#include "ui/base/dragdrop/drag_drop_types.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/models/simple_menu_model.h"
-#include "ui/views/controls/menu/menu_runner.h"
-#include "ui/views/vector_icons.h"
-#include "ui/views/view.h"
-
-namespace ash {
-
-namespace {
-
-// It is expected that all `HoldingSpaceItemView`s share the same delegate in
-// order to support multiple selections. We cache the singleton `instance` in
-// order to enforce this requirement.
-HoldingSpaceItemViewDelegate* instance = nullptr;
-
-// Helpers ---------------------------------------------------------------------
-
-// Attempts to open the specified holding space `item`.
-void OpenItem(const HoldingSpaceItem& item) {
-  HoldingSpaceController::Get()->client()->OpenItem(item, base::DoNothing());
-}
-
-}  // namespace
-
-// HoldingSpaceItemViewDelegate ------------------------------------------------
-
-HoldingSpaceItemViewDelegate::HoldingSpaceItemViewDelegate() {
-  DCHECK_EQ(nullptr, instance);
-  instance = this;
-}
-
-HoldingSpaceItemViewDelegate::~HoldingSpaceItemViewDelegate() {
-  DCHECK_EQ(instance, this);
-  instance = nullptr;
-}
-
-// TODO(dmblack): Implement multiple selection.
-void HoldingSpaceItemViewDelegate::OnHoldingSpaceItemViewGestureEvent(
-    HoldingSpaceItemView* view,
-    const ui::GestureEvent& event) {
-  if (event.type() == ui::ET_GESTURE_TAP)
-    OpenItem(*view->item());
-}
-
-// TODO(dmblack): Handle multiple selection.
-bool HoldingSpaceItemViewDelegate::OnHoldingSpaceItemViewKeyPressed(
-    HoldingSpaceItemView* view,
-    const ui::KeyEvent& event) {
-  if (event.key_code() == ui::KeyboardCode::VKEY_RETURN) {
-    OpenItem(*view->item());
-    return true;
-  }
-  return false;
-}
-
-// TODO(dmblack): Handle multiple selection.
-bool HoldingSpaceItemViewDelegate::OnHoldingSpaceItemViewMousePressed(
-    HoldingSpaceItemView* view,
-    const ui::MouseEvent& event) {
-  if (event.flags() & ui::EF_IS_DOUBLE_CLICK) {
-    OpenItem(*view->item());
-    return true;
-  }
-  return false;
-}
-
-void HoldingSpaceItemViewDelegate::OnHoldingSpaceItemViewDestroyed(
-    HoldingSpaceItemView* view) {
-  selected_views_by_item_id_.erase(view->item()->id());
-}
-
-// TODO(dmblack): Handle multiple selection.
-void HoldingSpaceItemViewDelegate::ShowContextMenuForViewImpl(
-    views::View* source,
-    const gfx::Point& point,
-    ui::MenuSourceType source_type) {
-  selected_views_by_item_id_.clear();
-
-  HoldingSpaceItemView* selected_view = HoldingSpaceItemView::Cast(source);
-  selected_views_by_item_id_[selected_view->item()->id()] = selected_view;
-
-  int run_types = views::MenuRunner::USE_TOUCHABLE_LAYOUT |
-                  views::MenuRunner::CONTEXT_MENU |
-                  views::MenuRunner::FIXED_ANCHOR;
-
-  context_menu_runner_ =
-      std::make_unique<views::MenuRunner>(BuildMenuModel(), run_types);
-
-  context_menu_runner_->RunMenuAt(
-      source->GetWidget(), nullptr /*button_controller*/,
-      source->GetBoundsInScreen(), views::MenuAnchorPosition::kBubbleRight,
-      source_type);
-}
-
-// TODO(dmblack): Handle multiple selection.
-bool HoldingSpaceItemViewDelegate::CanStartDragForView(
-    views::View* sender,
-    const gfx::Point& press_pt,
-    const gfx::Point& current_pt) {
-  selected_views_by_item_id_.clear();
-
-  HoldingSpaceItemView* selected_view = HoldingSpaceItemView::Cast(sender);
-  selected_views_by_item_id_[selected_view->item()->id()] = selected_view;
-
-  return true;
-}
-
-int HoldingSpaceItemViewDelegate::GetDragOperationsForView(
-    views::View* sender,
-    const gfx::Point& press_pt) {
-  return ui::DragDropTypes::DRAG_COPY;
-}
-
-// TODO(dmblack): Handle multiple selection.
-void HoldingSpaceItemViewDelegate::WriteDragDataForView(
-    views::View* sender,
-    const gfx::Point& press_pt,
-    ui::OSExchangeData* data) {
-  DCHECK_EQ(1u, selected_views_by_item_id_.size());
-  auto* selected_view = selected_views_by_item_id_.begin()->second;
-  data->SetFilename(selected_view->item()->file_path());
-}
-
-// TODO(dmblack): Handle multiple selection.
-void HoldingSpaceItemViewDelegate::ExecuteCommand(int command_id,
-                                                  int event_flags) {
-  DCHECK_EQ(1u, selected_views_by_item_id_.size());
-  auto* selected_view = selected_views_by_item_id_.begin()->second;
-
-  switch (command_id) {
-    case HoldingSpaceCommandId::kCopyImageToClipboard:
-      HoldingSpaceController::Get()->client()->CopyImageToClipboard(
-          *selected_view->item(), base::DoNothing());
-      break;
-    case HoldingSpaceCommandId::kPinItem:
-      HoldingSpaceController::Get()->client()->PinItem(*selected_view->item());
-      break;
-    case HoldingSpaceCommandId::kShowInFolder:
-      HoldingSpaceController::Get()->client()->ShowItemInFolder(
-          *selected_view->item(), base::DoNothing());
-      break;
-    case HoldingSpaceCommandId::kUnpinItem:
-      HoldingSpaceController::Get()->client()->UnpinItem(
-          *selected_view->item());
-      break;
-  }
-}
-
-// TODO(dmblack): Handle multiple selection.
-ui::SimpleMenuModel* HoldingSpaceItemViewDelegate::BuildMenuModel() {
-  DCHECK_EQ(1u, selected_views_by_item_id_.size());
-  auto* selected_view = selected_views_by_item_id_.begin()->second;
-
-  context_menu_model_ = std::make_unique<ui::SimpleMenuModel>(this);
-  context_menu_model_->AddItemWithIcon(
-      HoldingSpaceCommandId::kShowInFolder,
-      l10n_util::GetStringUTF16(
-          IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_SHOW_IN_FOLDER),
-      ui::ImageModel::FromVectorIcon(kFolderIcon));
-
-  std::string mime_type;
-  const bool is_image = net::GetMimeTypeFromFile(
-                            selected_view->item()->file_path(), &mime_type) &&
-                        net::MatchesMimeType(kMimeTypeImage, mime_type);
-
-  if (is_image) {
-    context_menu_model_->AddItemWithIcon(
-        HoldingSpaceCommandId::kCopyImageToClipboard,
-        l10n_util::GetStringUTF16(
-            IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_COPY_IMAGE_TO_CLIPBOARD),
-        ui::ImageModel::FromVectorIcon(kCopyIcon));
-  }
-
-  const bool is_pinned = HoldingSpaceController::Get()->model()->GetItem(
-      HoldingSpaceItem::GetFileBackedItemId(
-          HoldingSpaceItem::Type::kPinnedFile,
-          selected_view->item()->file_path()));
-
-  if (!is_pinned) {
-    context_menu_model_->AddItemWithIcon(
-        HoldingSpaceCommandId::kPinItem,
-        l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_PIN),
-        ui::ImageModel::FromVectorIcon(views::kPinIcon));
-  } else {
-    context_menu_model_->AddItemWithIcon(
-        HoldingSpaceCommandId::kUnpinItem,
-        l10n_util::GetStringUTF16(IDS_ASH_HOLDING_SPACE_CONTEXT_MENU_UNPIN),
-        ui::ImageModel::FromVectorIcon(views::kUnpinIcon));
-  }
-
-  return context_menu_model_.get();
-}
-
-}  // namespace ash
diff --git a/ash/system/holding_space/holding_space_item_view_delegate.h b/ash/system/holding_space/holding_space_item_view_delegate.h
deleted file mode 100644
index 5d3c4d1..0000000
--- a/ash/system/holding_space/holding_space_item_view_delegate.h
+++ /dev/null
@@ -1,92 +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 ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_VIEW_DELEGATE_H_
-#define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_VIEW_DELEGATE_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include "ash/ash_export.h"
-#include "ui/base/models/simple_menu_model.h"
-#include "ui/views/context_menu_controller.h"
-#include "ui/views/drag_controller.h"
-
-namespace ui {
-class GestureEvent;
-class KeyEvent;
-class MouseEvent;
-}  // namespace ui
-
-namespace views {
-class MenuRunner;
-}  // namespace views
-
-namespace ash {
-
-class HoldingSpaceItemView;
-
-// TODO(dmblack): Implement multiple selection.
-// A delegate for `HoldingSpaceItemView`s which implements context menu,
-// drag-and-drop, and selection functionality. In order to support multiple
-// selections at a time, all `HoldingSpaceItemView`s must share the same
-// `HoldingSpaceItemViewDelegate` instance.
-class ASH_EXPORT HoldingSpaceItemViewDelegate
-    : public views::ContextMenuController,
-      public views::DragController,
-      public ui::SimpleMenuModel::Delegate {
- public:
-  HoldingSpaceItemViewDelegate();
-  HoldingSpaceItemViewDelegate(const HoldingSpaceItemViewDelegate&) = delete;
-  HoldingSpaceItemViewDelegate& operator=(const HoldingSpaceItemViewDelegate&) =
-      delete;
-  ~HoldingSpaceItemViewDelegate() override;
-
-  // Invoked when `view` receives the specified gesture `event`.
-  void OnHoldingSpaceItemViewGestureEvent(HoldingSpaceItemView* view,
-                                          const ui::GestureEvent& event);
-
-  // Invoked when `view` receives the specified key pressed `event`.
-  bool OnHoldingSpaceItemViewKeyPressed(HoldingSpaceItemView* view,
-                                        const ui::KeyEvent& event);
-
-  // Invoked when `view` receives the specified mouse pressed `event`.
-  bool OnHoldingSpaceItemViewMousePressed(HoldingSpaceItemView* view,
-                                          const ui::MouseEvent& event);
-
-  // Invoked when `view` has been destroyed.
-  void OnHoldingSpaceItemViewDestroyed(HoldingSpaceItemView* view);
-
- private:
-  // views::ContextMenuController:
-  void ShowContextMenuForViewImpl(views::View* source,
-                                  const gfx::Point& point,
-                                  ui::MenuSourceType source_type) override;
-
-  // views::DragController:
-  bool CanStartDragForView(views::View* sender,
-                           const gfx::Point& press_pt,
-                           const gfx::Point& current_pt) override;
-  int GetDragOperationsForView(views::View* sender,
-                               const gfx::Point& press_pt) override;
-  void WriteDragDataForView(views::View* sender,
-                            const gfx::Point& press_pt,
-                            ui::OSExchangeData* data) override;
-
-  // SimpleMenuModel::Delegate:
-  void ExecuteCommand(int command_id, int event_flags) override;
-
-  // Builds and returns a raw pointer to `context_menu_model_`.
-  ui::SimpleMenuModel* BuildMenuModel();
-
-  std::unique_ptr<ui::SimpleMenuModel> context_menu_model_;
-  std::unique_ptr<views::MenuRunner> context_menu_runner_;
-
-  std::map<std::string, HoldingSpaceItemView*> selected_views_by_item_id_;
-};
-
-}  // namespace ash
-
-#endif  // ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_ITEM_VIEW_DELEGATE_H_
diff --git a/ash/system/holding_space/holding_space_tray.cc b/ash/system/holding_space/holding_space_tray.cc
index d9335ac..15b6eb2a 100644
--- a/ash/system/holding_space/holding_space_tray.cc
+++ b/ash/system/holding_space/holding_space_tray.cc
@@ -149,8 +149,8 @@
   bubble_view->set_margins(GetSecondaryBubbleInsets());
 
   // Add pinned files container.
-  pinned_files_container_ = bubble_view->AddChildView(
-      std::make_unique<PinnedFilesContainer>(&delegate_));
+  pinned_files_container_ =
+      bubble_view->AddChildView(std::make_unique<PinnedFilesContainer>());
   SetupChildLayer(pinned_files_container_);
 
   // Separator between the two containers, gives illusion of 2 separate bubbles.
@@ -159,8 +159,8 @@
   separator->SetBorder(views::CreateEmptyBorder(
       gfx::Insets(kHoldingSpaceContainerSpacing, 0, 0, 0)));
 
-  recent_files_container_ = bubble_view->AddChildView(
-      std::make_unique<RecentFilesContainer>(&delegate_));
+  recent_files_container_ =
+      bubble_view->AddChildView(std::make_unique<RecentFilesContainer>());
   SetupChildLayer(recent_files_container_);
 
   // Show the bubble.
diff --git a/ash/system/holding_space/holding_space_tray.h b/ash/system/holding_space/holding_space_tray.h
index 223a48a..27eea26 100644
--- a/ash/system/holding_space/holding_space_tray.h
+++ b/ash/system/holding_space/holding_space_tray.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "ash/ash_export.h"
-#include "ash/system/holding_space/holding_space_item_view_delegate.h"
 #include "ash/system/tray/tray_background_view.h"
 #include "base/memory/weak_ptr.h"
 
@@ -61,10 +60,6 @@
 
   std::unique_ptr<TrayBubbleWrapper> bubble_;
 
-  // The singleton delegate for `HoldingSpaceItemView`s that implements support
-  // for context menu, drag-and-drop, and multiple selection.
-  HoldingSpaceItemViewDelegate delegate_;
-
   PinnedFilesContainer* pinned_files_container_ = nullptr;
   RecentFilesContainer* recent_files_container_ = nullptr;
 
diff --git a/ash/system/holding_space/pinned_files_container.cc b/ash/system/holding_space/pinned_files_container.cc
index 37f8e6b..f3161171 100644
--- a/ash/system/holding_space/pinned_files_container.cc
+++ b/ash/system/holding_space/pinned_files_container.cc
@@ -22,9 +22,7 @@
 
 namespace ash {
 
-PinnedFilesContainer::PinnedFilesContainer(
-    HoldingSpaceItemViewDelegate* delegate)
-    : delegate_(delegate) {
+PinnedFilesContainer::PinnedFilesContainer() {
   SetID(kHoldingSpacePinnedFilesContainerId);
 
   SetLayoutManager(std::make_unique<views::BoxLayout>(
@@ -54,8 +52,7 @@
 
   if (item->type() == HoldingSpaceItem::Type::kPinnedFile) {
     views_by_item_id_[item->id()] = item_chips_container_->AddChildViewAt(
-        std::make_unique<HoldingSpaceItemChipView>(delegate_, item),
-        /*index=*/0);
+        std::make_unique<HoldingSpaceItemChipView>(item), 0 /*index*/);
   }
 }
 
diff --git a/ash/system/holding_space/pinned_files_container.h b/ash/system/holding_space/pinned_files_container.h
index d27ef533..f026928 100644
--- a/ash/system/holding_space/pinned_files_container.h
+++ b/ash/system/holding_space/pinned_files_container.h
@@ -12,12 +12,11 @@
 namespace ash {
 
 class HoldingSpaceItemChipsContainer;
-class HoldingSpaceItemViewDelegate;
 
 // Container for pinned files that the user adds to the holding space bubble.
 class PinnedFilesContainer : public HoldingSpaceItemViewsContainer {
  public:
-  explicit PinnedFilesContainer(HoldingSpaceItemViewDelegate* delegate);
+  PinnedFilesContainer();
   PinnedFilesContainer(const PinnedFilesContainer& other) = delete;
   PinnedFilesContainer& operator=(const PinnedFilesContainer& other) = delete;
   ~PinnedFilesContainer() override;
@@ -28,7 +27,6 @@
   void RemoveHoldingSpaceItemView(const HoldingSpaceItem* item) override;
 
  private:
-  HoldingSpaceItemViewDelegate* const delegate_;
   HoldingSpaceItemChipsContainer* item_chips_container_ = nullptr;
 
   std::map<std::string, views::View*> views_by_item_id_;
diff --git a/ash/system/holding_space/recent_files_container.cc b/ash/system/holding_space/recent_files_container.cc
index ce0cd9c..57d4ed4 100644
--- a/ash/system/holding_space/recent_files_container.cc
+++ b/ash/system/holding_space/recent_files_container.cc
@@ -22,9 +22,7 @@
 
 namespace ash {
 
-RecentFilesContainer::RecentFilesContainer(
-    HoldingSpaceItemViewDelegate* delegate)
-    : delegate_(delegate) {
+RecentFilesContainer::RecentFilesContainer() {
   SetID(kHoldingSpaceRecentFilesContainerId);
 
   SetLayoutManager(std::make_unique<views::BoxLayout>(
@@ -68,12 +66,10 @@
   DCHECK(!base::Contains(views_by_item_id_, item->id()));
   if (item->type() == HoldingSpaceItem::Type::kScreenshot) {
     views_by_item_id_[item->id()] = screenshots_container_->AddChildViewAt(
-        std::make_unique<HoldingSpaceItemScreenshotView>(delegate_, item),
-        /*index=*/0);
+        std::make_unique<HoldingSpaceItemScreenshotView>(item), 0 /*index*/);
   } else if (item->type() == HoldingSpaceItem::Type::kDownload) {
     views_by_item_id_[item->id()] = recent_downloads_container_->AddChildViewAt(
-        std::make_unique<HoldingSpaceItemChipView>(delegate_, item),
-        /*index=*/0);
+        std::make_unique<HoldingSpaceItemChipView>(item), 0 /*index*/);
   }
 }
 
@@ -88,13 +84,13 @@
   auto it = views_by_item_id_.find(item->id());
   if (it == views_by_item_id_.end())
     return;
+  views::View* view = it->second;
 
   if (item->type() == HoldingSpaceItem::Type::kScreenshot) {
-    screenshots_container_->RemoveChildViewT(it->second);
+    screenshots_container_->RemoveChildViewT(view);
   } else if (item->type() == HoldingSpaceItem::Type::kDownload) {
-    recent_downloads_container_->RemoveChildViewT(it->second);
+    recent_downloads_container_->RemoveChildViewT(view);
   }
-
   views_by_item_id_.erase(it);
 }
 
diff --git a/ash/system/holding_space/recent_files_container.h b/ash/system/holding_space/recent_files_container.h
index 36befed1..5d906a8 100644
--- a/ash/system/holding_space/recent_files_container.h
+++ b/ash/system/holding_space/recent_files_container.h
@@ -12,12 +12,11 @@
 namespace ash {
 
 class HoldingSpaceItemChipsContainer;
-class HoldingSpaceItemViewDelegate;
 
 // Container for the recent files (Screenshots, downloads etc).
 class RecentFilesContainer : public HoldingSpaceItemViewsContainer {
  public:
-  explicit RecentFilesContainer(HoldingSpaceItemViewDelegate* delegate);
+  RecentFilesContainer();
   RecentFilesContainer(const RecentFilesContainer& other) = delete;
   RecentFilesContainer& operator=(const RecentFilesContainer& other) = delete;
   ~RecentFilesContainer() override;
@@ -28,7 +27,6 @@
   void RemoveHoldingSpaceItemView(const HoldingSpaceItem* item) override;
 
  private:
-  HoldingSpaceItemViewDelegate* const delegate_;
   views::View* screenshots_container_ = nullptr;
   HoldingSpaceItemChipsContainer* recent_downloads_container_ = nullptr;
 
diff --git a/ash/system/media/media_tray.cc b/ash/system/media/media_tray.cc
index e9ba5b4..157e0c2 100644
--- a/ash/system/media/media_tray.cc
+++ b/ash/system/media/media_tray.cc
@@ -65,6 +65,8 @@
   if (MediaNotificationProvider::Get())
     MediaNotificationProvider::Get()->AddObserver(this);
 
+  Shell::Get()->session_controller()->AddObserver(this);
+
   auto icon = std::make_unique<views::ImageView>();
   icon->SetTooltipText(l10n_util::GetStringUTF16(
       IDS_ASH_GLOBAL_MEDIA_CONTROLS_BUTTON_TOOLTIP_TEXT));
@@ -82,6 +84,8 @@
 
   if (MediaNotificationProvider::Get())
     MediaNotificationProvider::Get()->RemoveObserver(this);
+
+  Shell::Get()->session_controller()->RemoveObserver(this);
 }
 
 void MediaTray::OnNotificationListChanged() {
@@ -171,13 +175,18 @@
   CloseBubble();
 }
 
+void MediaTray::OnLockStateChanged(bool locked) {
+  UpdateDisplayState();
+}
+
 void MediaTray::UpdateDisplayState() {
   if (!MediaNotificationProvider::Get())
     return;
 
   bool should_show =
-      MediaNotificationProvider::Get()->HasActiveNotifications() ||
-      MediaNotificationProvider::Get()->HasFrozenNotifications();
+      (MediaNotificationProvider::Get()->HasActiveNotifications() ||
+       MediaNotificationProvider::Get()->HasFrozenNotifications()) &&
+      !Shell::Get()->session_controller()->IsScreenLocked();
 
   if (!should_show && bubble_)
     CloseBubble();
diff --git a/ash/system/media/media_tray.h b/ash/system/media/media_tray.h
index 9131d2a8..dac2a05f 100644
--- a/ash/system/media/media_tray.h
+++ b/ash/system/media/media_tray.h
@@ -6,6 +6,7 @@
 #define ASH_SYSTEM_MEDIA_MEDIA_TRAY_H_
 
 #include "ash/public/cpp/media_notification_provider_observer.h"
+#include "ash/public/cpp/session/session_observer.h"
 #include "ash/system/tray/tray_background_view.h"
 
 namespace views {
@@ -18,7 +19,8 @@
 class TrayBubbleWrapper;
 
 class MediaTray : public MediaNotificationProviderObserver,
-                  public TrayBackgroundView {
+                  public TrayBackgroundView,
+                  public SessionObserver {
  public:
   explicit MediaTray(Shelf* shelf);
   ~MediaTray() override;
@@ -37,6 +39,9 @@
   void HideBubbleWithView(const TrayBubbleView* bubble_view) override;
   void ClickedOutsideBubble() override;
 
+  // SessionObserver implementation.
+  void OnLockStateChanged(bool locked) override;
+
   TrayBubbleWrapper* tray_bubble_wrapper_for_testing() { return bubble_.get(); }
 
  private:
diff --git a/ash/system/media/media_tray_unittest.cc b/ash/system/media/media_tray_unittest.cc
index e8d7914..eef1c9d 100644
--- a/ash/system/media/media_tray_unittest.cc
+++ b/ash/system/media/media_tray_unittest.cc
@@ -28,6 +28,10 @@
             [](auto, auto) { return std::make_unique<views::View>(); });
   }
 
+  ~MockMediaNotificationProvider() override {
+    MediaNotificationProvider::Set(nullptr);
+  }
+
   // Medianotificationprovider implementations.
   MOCK_METHOD2(GetMediaNotificationListView,
                std::unique_ptr<views::View>(SkColor, int));
@@ -111,6 +115,15 @@
   provider()->SetHasFrozenNotifications(true);
   SimulateNotificationListChanged();
   EXPECT_TRUE(media_tray()->GetVisible());
+
+  // Media tray should be hidden when screen is locked.
+  GetSessionControllerClient()->LockScreen();
+  GetSessionControllerClient()->FlushForTest();
+  EXPECT_FALSE(media_tray()->GetVisible());
+
+  // Media tray should be visible again when we unlock the screen.
+  GetSessionControllerClient()->UnlockScreen();
+  EXPECT_TRUE(media_tray()->GetVisible());
 }
 
 TEST_F(MediaTrayTest, ShowAndHideBubbleTest) {
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc
index e9db7093..3f0f01b 100644
--- a/ash/system/unified/unified_system_tray_controller.cc
+++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -133,7 +133,8 @@
   unified_view_ = new UnifiedSystemTrayView(this, model_->IsExpandedOnOpen());
   InitFeaturePods();
 
-  if (base::FeatureList::IsEnabled(media::kGlobalMediaControlsForChromeOS)) {
+  if (base::FeatureList::IsEnabled(media::kGlobalMediaControlsForChromeOS) &&
+      !Shell::Get()->session_controller()->IsScreenLocked()) {
     media_controls_controller_ =
         std::make_unique<UnifiedMediaControlsController>(this);
     unified_view_->AddMediaControlsView(
diff --git a/base/allocator/partition_allocator/spinning_futex_linux.h b/base/allocator/partition_allocator/spinning_futex_linux.h
index c1800bc..b7fd6df 100644
--- a/base/allocator/partition_allocator/spinning_futex_linux.h
+++ b/base/allocator/partition_allocator/spinning_futex_linux.h
@@ -56,8 +56,9 @@
   static constexpr int kLockedUncontended = 1;
   static constexpr int kLockedContended = 2;
 
-  // Same as SpinLock, not scientifically calibrated.
-  static constexpr int kSpinCount = 10;
+  // Same as SpinLock, not scientifically calibrated. Consider lowering later,
+  // as the slow path has better characteristics than SpinLocks's.
+  static constexpr int kSpinCount = 1000;
 
   std::atomic<int32_t> state_{kUnlocked};
 };
@@ -78,7 +79,8 @@
 
 ALWAYS_INLINE bool SpinningFutex::Try() {
   int expected = kUnlocked;
-  return state_.compare_exchange_strong(expected, kLockedUncontended,
+  return (state_.load(std::memory_order_relaxed) == expected) &&
+         state_.compare_exchange_strong(expected, kLockedUncontended,
                                         std::memory_order_acquire,
                                         std::memory_order_relaxed);
 }
diff --git a/base/at_exit.h b/base/at_exit.h
index fa652ac..2a11046 100644
--- a/base/at_exit.h
+++ b/base/at_exit.h
@@ -8,7 +8,6 @@
 #include "base/base_export.h"
 #include "base/callback.h"
 #include "base/containers/stack.h"
-#include "base/macros.h"
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
 
@@ -33,6 +32,8 @@
   typedef void (*AtExitCallbackType)(void*);
 
   AtExitManager();
+  AtExitManager(const AtExitManager&) = delete;
+  AtExitManager& operator=(const AtExitManager&) = delete;
 
   // The dtor calls all the registered callbacks. Do not try to register more
   // callbacks after this point.
@@ -71,8 +72,6 @@
 
   // Stack of managers to allow shadowing.
   AtExitManager* const next_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(AtExitManager);
 };
 
 #if defined(UNIT_TEST)
diff --git a/base/atomic_sequence_num.h b/base/atomic_sequence_num.h
index 717e37a..d0ab9eb4 100644
--- a/base/atomic_sequence_num.h
+++ b/base/atomic_sequence_num.h
@@ -7,8 +7,6 @@
 
 #include <atomic>
 
-#include "base/macros.h"
-
 namespace base {
 
 // AtomicSequenceNumber is a thread safe increasing sequence number generator.
@@ -17,6 +15,8 @@
 class AtomicSequenceNumber {
  public:
   constexpr AtomicSequenceNumber() = default;
+  AtomicSequenceNumber(const AtomicSequenceNumber&) = delete;
+  AtomicSequenceNumber& operator=(const AtomicSequenceNumber&) = delete;
 
   // Returns an increasing sequence number starts from 0 for each call.
   // This function can be called from any thread without data race.
@@ -24,8 +24,6 @@
 
  private:
   std::atomic_int seq_{0};
-
-  DISALLOW_COPY_AND_ASSIGN(AtomicSequenceNumber);
 };
 
 }  // namespace base
diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc
index 36282ac1..7336240 100644
--- a/base/bind_unittest.cc
+++ b/base/bind_unittest.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
@@ -35,6 +34,9 @@
 class NoRef {
  public:
   NoRef() = default;
+  NoRef(const NoRef&) = delete;
+  // Particularly important in this test to ensure no copies are made.
+  NoRef& operator=(const NoRef&) = delete;
 
   MOCK_METHOD0(VoidMethod0, void());
   MOCK_CONST_METHOD0(VoidConstMethod0, void());
@@ -45,22 +47,18 @@
   MOCK_METHOD1(VoidMethodWithIntArg, void(int));
   MOCK_METHOD0(UniquePtrMethod0, std::unique_ptr<int>());
 
- private:
-  // Particularly important in this test to ensure no copies are made.
-  DISALLOW_COPY_AND_ASSIGN(NoRef);
 };
 
 class HasRef : public NoRef {
  public:
   HasRef() = default;
+  HasRef(const HasRef&) = delete;
+  // Particularly important in this test to ensure no copies are made.
+  HasRef& operator=(const HasRef&) = delete;
 
   MOCK_CONST_METHOD0(AddRef, void());
   MOCK_CONST_METHOD0(Release, bool());
   MOCK_CONST_METHOD0(HasAtLeastOneRef, bool());
-
- private:
-  // Particularly important in this test to ensure no copies are made.
-  DISALLOW_COPY_AND_ASSIGN(HasRef);
 };
 
 class HasRefPrivateDtor : public HasRef {
@@ -326,7 +324,8 @@
     const_no_ref_ptr_ = &no_ref_;
     static_func_mock_ptr = &static_func_mock_;
   }
-
+  BindTest(const BindTest&) = delete;
+  BindTest& operator=(const BindTest&) = delete;
   ~BindTest() override = default;
 
   static void VoidFunc0() {
@@ -346,9 +345,6 @@
 
   // Used by the static functions to perform expectations.
   static StrictMock<NoRef>* static_func_mock_ptr;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BindTest);
 };
 
 StrictMock<NoRef>* BindTest::static_func_mock_ptr;
diff --git a/base/callback_helpers.h b/base/callback_helpers.h
index ad3fc32..2ed1011 100644
--- a/base/callback_helpers.h
+++ b/base/callback_helpers.h
@@ -10,6 +10,7 @@
 #ifndef BASE_CALLBACK_HELPERS_H_
 #define BASE_CALLBACK_HELPERS_H_
 
+#include <memory>
 #include <type_traits>
 #include <utility>
 
@@ -17,7 +18,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/compiler_specific.h"
-#include "base/macros.h"
 #include "base/memory/ptr_util.h"
 
 namespace base {
@@ -72,6 +72,10 @@
       : callback_(std::move(callback)) {
     DCHECK(callback_);
   }
+  AdaptCallbackForRepeatingHelper(const AdaptCallbackForRepeatingHelper&) =
+      delete;
+  AdaptCallbackForRepeatingHelper& operator=(
+      const AdaptCallbackForRepeatingHelper&) = delete;
 
   void Run(Args... args) {
     if (subtle::NoBarrier_AtomicExchange(&has_run_, 1))
@@ -83,8 +87,6 @@
  private:
   volatile subtle::Atomic32 has_run_ = 0;
   base::OnceCallback<void(Args...)> callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(AdaptCallbackForRepeatingHelper);
 };
 
 }  // namespace internal
@@ -112,6 +114,8 @@
  public:
   ScopedClosureRunner();
   explicit ScopedClosureRunner(OnceClosure closure);
+  ScopedClosureRunner(const ScopedClosureRunner&) = delete;
+  ScopedClosureRunner& operator=(const ScopedClosureRunner&) = delete;
   ~ScopedClosureRunner();
 
   ScopedClosureRunner(ScopedClosureRunner&& other);
@@ -131,8 +135,6 @@
 
  private:
   OnceClosure closure_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedClosureRunner);
 };
 
 }  // namespace base
diff --git a/base/callback_internal.h b/base/callback_internal.h
index fdfdf7f8..54add71 100644
--- a/base/callback_internal.h
+++ b/base/callback_internal.h
@@ -10,7 +10,6 @@
 
 #include "base/base_export.h"
 #include "base/callback_forward.h"
-#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 
 namespace base {
@@ -61,6 +60,9 @@
 
   using InvokeFuncStorage = void(*)();
 
+  BindStateBase(const BindStateBase&) = delete;
+  BindStateBase& operator=(const BindStateBase&) = delete;
+
  private:
   BindStateBase(InvokeFuncStorage polymorphic_invoke,
                 void (*destructor)(const BindStateBase*));
@@ -100,8 +102,6 @@
   void (*destructor_)(const BindStateBase*);
   bool (*query_cancellation_traits_)(const BindStateBase*,
                                      CancellationQueryMode mode);
-
-  DISALLOW_COPY_AND_ASSIGN(BindStateBase);
 };
 
 // Holds the Callback methods that don't require specialization to reduce
diff --git a/base/callback_list_unittest.nc b/base/callback_list_unittest.nc
index c6af89a..7a0e1c1e 100644
--- a/base/callback_list_unittest.nc
+++ b/base/callback_list_unittest.nc
@@ -12,7 +12,6 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
-#include "base/macros.h"
 
 namespace base {
 
@@ -24,14 +23,13 @@
 
 class FooListener {
  public:
-  FooListener() {}
+  FooListener() = default;
+  FooListener(const FooListener&) = delete;
+  FooListener& operator=(const FooListener&) = delete;
 
   void GotAScopedFoo(std::unique_ptr<Foo> f) { foo_ = std::move(f); }
 
   std::unique_ptr<Foo> foo_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FooListener);
 };
 
 
diff --git a/base/cancelable_callback.h b/base/cancelable_callback.h
index aafa6d75..c19e9a36 100644
--- a/base/cancelable_callback.h
+++ b/base/cancelable_callback.h
@@ -53,7 +53,6 @@
 #include "base/callback_internal.h"
 #include "base/check.h"
 #include "base/compiler_specific.h"
-#include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 
 namespace base {
@@ -62,7 +61,9 @@
 template <typename CallbackType>
 class CancelableCallbackImpl {
  public:
-  CancelableCallbackImpl() {}
+  CancelableCallbackImpl() = default;
+  CancelableCallbackImpl(const CancelableCallbackImpl&) = delete;
+  CancelableCallbackImpl& operator=(const CancelableCallbackImpl&) = delete;
 
   // |callback| must not be null.
   explicit CancelableCallbackImpl(CallbackType callback)
@@ -130,8 +131,6 @@
   // The stored closure that may be cancelled.
   CallbackType callback_;
   mutable base::WeakPtrFactory<CancelableCallbackImpl> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(CancelableCallbackImpl);
 };
 
 }  // namespace internal
diff --git a/base/cpu_affinity_posix_unittest.cc b/base/cpu_affinity_posix_unittest.cc
index 406ccae8..aa476d67 100644
--- a/base/cpu_affinity_posix_unittest.cc
+++ b/base/cpu_affinity_posix_unittest.cc
@@ -6,6 +6,8 @@
 
 #include <sched.h>
 
+#include <string>
+
 #include "base/synchronization/waitable_event.h"
 #include "base/system/sys_info.h"
 #include "base/threading/platform_thread.h"
@@ -24,6 +26,8 @@
                            WaitableEvent::InitialState::NOT_SIGNALED),
         terminate_thread_(WaitableEvent::ResetPolicy::MANUAL,
                           WaitableEvent::InitialState::NOT_SIGNALED) {}
+  TestThread(const TestThread&) = delete;
+  TestThread& operator=(const TestThread&) = delete;
   ~TestThread() override {
     EXPECT_TRUE(terminate_thread_.IsSignaled())
         << "Need to mark thread for termination and join the underlying thread "
@@ -66,8 +70,6 @@
   mutable WaitableEvent termination_ready_;
   WaitableEvent terminate_thread_;
   bool done_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(TestThread);
 };
 
 }  // namespace
diff --git a/base/critical_closure.h b/base/critical_closure.h
index 0eb6a3e..d47442d 100644
--- a/base/critical_closure.h
+++ b/base/critical_closure.h
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "base/callback.h"
-#include "base/macros.h"
 #include "base/strings/string_piece.h"
 #include "build/build_config.h"
 
@@ -31,14 +30,14 @@
 class CriticalClosure {
  public:
   explicit CriticalClosure(StringPiece task_name, OnceClosure closure);
+  CriticalClosure(const CriticalClosure&) = delete;
+  CriticalClosure& operator=(const CriticalClosure&) = delete;
   ~CriticalClosure();
   void Run();
 
  private:
   ios::ScopedCriticalAction critical_action_;
   OnceClosure closure_;
-
-  DISALLOW_COPY_AND_ASSIGN(CriticalClosure);
 };
 #endif  // defined(OS_IOS)
 
diff --git a/base/deferred_sequenced_task_runner.h b/base/deferred_sequenced_task_runner.h
index c5fb57b7..864b8d5 100644
--- a/base/deferred_sequenced_task_runner.h
+++ b/base/deferred_sequenced_task_runner.h
@@ -10,7 +10,6 @@
 #include "base/base_export.h"
 #include "base/callback.h"
 #include "base/compiler_specific.h"
-#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequenced_task_runner.h"
 #include "base/synchronization/lock.h"
@@ -33,6 +32,9 @@
   // Use this constructor when you don't have the target SequencedTaskRunner.
   // When using this call StartWithTaskRunner().
   DeferredSequencedTaskRunner();
+  DeferredSequencedTaskRunner(const DeferredSequencedTaskRunner&) = delete;
+  DeferredSequencedTaskRunner& operator=(const DeferredSequencedTaskRunner&) =
+      delete;
 
   // TaskRunner implementation
   bool PostDelayedTask(const Location& from_here,
@@ -87,8 +89,6 @@
   bool started_ GUARDED_BY(lock_) = false;
   scoped_refptr<SequencedTaskRunner> target_task_runner_ GUARDED_BY(lock_);
   std::vector<DeferredTask> deferred_tasks_queue_ GUARDED_BY(lock_);
-
-  DISALLOW_COPY_AND_ASSIGN(DeferredSequencedTaskRunner);
 };
 
 }  // namespace base
diff --git a/base/feature_list.h b/base/feature_list.h
index 4618d02..4474b510 100644
--- a/base/feature_list.h
+++ b/base/feature_list.h
@@ -9,11 +9,11 @@
 #include <map>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/base_export.h"
 #include "base/gtest_prod_util.h"
-#include "base/macros.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/persistent_memory_allocator.h"
 #include "base/strings/string_piece.h"
@@ -99,6 +99,8 @@
 class BASE_EXPORT FeatureList {
  public:
   FeatureList();
+  FeatureList(const FeatureList&) = delete;
+  FeatureList& operator=(const FeatureList&) = delete;
   ~FeatureList();
 
   // Used by common test fixture classes to prevent abuse of ScopedFeatureList
@@ -106,14 +108,14 @@
   class BASE_EXPORT ScopedDisallowOverrides {
    public:
     explicit ScopedDisallowOverrides(const char* reason);
+    ScopedDisallowOverrides(const ScopedDisallowOverrides&) = delete;
+    ScopedDisallowOverrides& operator=(const ScopedDisallowOverrides&) = delete;
     ~ScopedDisallowOverrides();
 
    private:
 #if DCHECK_IS_ON()
     const char* const previous_reason_;
 #endif
-
-    DISALLOW_COPY_AND_ASSIGN(ScopedDisallowOverrides);
   };
 
   // Specifies whether a feature override enables or disables the feature.
@@ -370,8 +372,6 @@
 
   // Whether this object has been initialized from command line.
   bool initialized_from_command_line_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(FeatureList);
 };
 
 }  // namespace base
diff --git a/base/feature_list_unittest.cc b/base/feature_list_unittest.cc
index 9aae7d0..86dcfc0 100644
--- a/base/feature_list_unittest.cc
+++ b/base/feature_list_unittest.cc
@@ -51,12 +51,12 @@
     // Provide an empty FeatureList to each test by default.
     scoped_feature_list_.InitWithFeatureList(std::make_unique<FeatureList>());
   }
+  FeatureListTest(const FeatureListTest&) = delete;
+  FeatureListTest& operator=(const FeatureListTest&) = delete;
   ~FeatureListTest() override = default;
 
  private:
   test::ScopedFeatureList scoped_feature_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(FeatureListTest);
 };
 
 TEST_F(FeatureListTest, DefaultStates) {
diff --git a/base/file_descriptor_store.h b/base/file_descriptor_store.h
index b6bd079..f22e124 100644
--- a/base/file_descriptor_store.h
+++ b/base/file_descriptor_store.h
@@ -10,7 +10,6 @@
 
 #include "base/files/memory_mapped_file.h"
 #include "base/files/scoped_file.h"
-#include "base/macros.h"
 
 namespace base {
 
@@ -19,6 +18,8 @@
 // It is used to share file descriptors from a process to its child.
 class BASE_EXPORT FileDescriptorStore {
  public:
+  FileDescriptorStore(const FileDescriptorStore&) = delete;
+  FileDescriptorStore& operator=(const FileDescriptorStore&) = delete;
   struct Descriptor {
     Descriptor(const std::string& key, base::ScopedFD fd);
     Descriptor(const std::string& key,
@@ -64,8 +65,6 @@
   ~FileDescriptorStore();
 
   Mapping descriptors_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileDescriptorStore);
 };
 
 }  // namespace base
diff --git a/base/file_version_info_mac.h b/base/file_version_info_mac.h
index cd10a9c..0ac2b41 100644
--- a/base/file_version_info_mac.h
+++ b/base/file_version_info_mac.h
@@ -10,13 +10,14 @@
 
 #include "base/file_version_info.h"
 #include "base/mac/scoped_nsobject.h"
-#include "base/macros.h"
 
 @class NSBundle;
 
 class FileVersionInfoMac : public FileVersionInfo {
  public:
   explicit FileVersionInfoMac(NSBundle *bundle);
+  FileVersionInfoMac(const FileVersionInfoMac&) = delete;
+  FileVersionInfoMac& operator=(const FileVersionInfoMac&) = delete;
   ~FileVersionInfoMac() override;
 
   // Accessors to the different version properties.
@@ -38,8 +39,6 @@
   base::string16 GetString16Value(CFStringRef name);
 
   base::scoped_nsobject<NSBundle> bundle_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileVersionInfoMac);
 };
 
 #endif  // BASE_FILE_VERSION_INFO_MAC_H_
diff --git a/base/file_version_info_win.h b/base/file_version_info_win.h
index f0dbde8..7fd4d20 100644
--- a/base/file_version_info_win.h
+++ b/base/file_version_info_win.h
@@ -15,7 +15,6 @@
 
 #include "base/base_export.h"
 #include "base/file_version_info.h"
-#include "base/macros.h"
 #include "base/version.h"
 
 struct tagVS_FIXEDFILEINFO;
@@ -23,6 +22,8 @@
 
 class BASE_EXPORT FileVersionInfoWin : public FileVersionInfo {
  public:
+  FileVersionInfoWin(const FileVersionInfoWin&) = delete;
+  FileVersionInfoWin& operator=(const FileVersionInfoWin&) = delete;
   ~FileVersionInfoWin() override;
 
   // Accessors to the different version properties.
@@ -70,8 +71,6 @@
 
   // This is a reference for a portion of |data_|.
   const VS_FIXEDFILEINFO& fixed_file_info_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileVersionInfoWin);
 };
 
 #endif  // BASE_FILE_VERSION_INFO_WIN_H_
diff --git a/base/file_version_info_win_unittest.cc b/base/file_version_info_win_unittest.cc
index 4886896..dea983b 100644
--- a/base/file_version_info_win_unittest.cc
+++ b/base/file_version_info_win_unittest.cc
@@ -12,7 +12,6 @@
 
 #include "base/file_version_info.h"
 #include "base/files/file_path.h"
-#include "base/macros.h"
 #include "base/path_service.h"
 #include "base/scoped_native_library.h"
 #include "base/strings/string_util.h"
@@ -35,6 +34,8 @@
 class FileVersionInfoFactory {
  public:
   explicit FileVersionInfoFactory(const FilePath& path) : path_(path) {}
+  FileVersionInfoFactory(const FileVersionInfoFactory&) = delete;
+  FileVersionInfoFactory& operator=(const FileVersionInfoFactory&) = delete;
 
   std::unique_ptr<FileVersionInfo> Create() const {
     return FileVersionInfo::CreateFileVersionInfo(path_);
@@ -42,8 +43,6 @@
 
  private:
   const FilePath path_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileVersionInfoFactory);
 };
 
 class FileVersionInfoForModuleFactory {
@@ -56,6 +55,10 @@
                                  LOAD_LIBRARY_AS_IMAGE_RESOURCE)) {
     EXPECT_TRUE(library_.is_valid());
   }
+  FileVersionInfoForModuleFactory(const FileVersionInfoForModuleFactory&) =
+      delete;
+  FileVersionInfoForModuleFactory& operator=(
+      const FileVersionInfoForModuleFactory&) = delete;
 
   std::unique_ptr<FileVersionInfo> Create() const {
     return FileVersionInfo::CreateFileVersionInfoForModule(library_.get());
@@ -63,8 +66,6 @@
 
  private:
   const base::ScopedNativeLibrary library_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileVersionInfoForModuleFactory);
 };
 
 template <typename T>
diff --git a/base/lazy_instance_unittest.cc b/base/lazy_instance_unittest.cc
index ad1f0eb..bc990b0 100644
--- a/base/lazy_instance_unittest.cc
+++ b/base/lazy_instance_unittest.cc
@@ -32,12 +32,12 @@
   ConstructAndDestructLogger() {
     constructed_seq_.GetNext();
   }
+  ConstructAndDestructLogger(const ConstructAndDestructLogger&) = delete;
+  ConstructAndDestructLogger& operator=(const ConstructAndDestructLogger&) =
+      delete;
   ~ConstructAndDestructLogger() {
     destructed_seq_.GetNext();
   }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ConstructAndDestructLogger);
 };
 
 class SlowConstructor {
@@ -48,13 +48,13 @@
     ++constructed;
     some_int_ = 12;
   }
+  SlowConstructor(const SlowConstructor&) = delete;
+  SlowConstructor& operator=(const SlowConstructor&) = delete;
   int some_int() const { return some_int_; }
 
   static int constructed;
  private:
   int some_int_;
-
-  DISALLOW_COPY_AND_ASSIGN(SlowConstructor);
 };
 
 // static
@@ -65,6 +65,8 @@
   explicit SlowDelegate(
       base::LazyInstance<SlowConstructor>::DestructorAtExit* lazy)
       : lazy_(lazy) {}
+  SlowDelegate(const SlowDelegate&) = delete;
+  SlowDelegate& operator=(const SlowDelegate&) = delete;
 
   void Run() override {
     EXPECT_EQ(12, lazy_->Get().some_int());
@@ -73,8 +75,6 @@
 
  private:
   base::LazyInstance<SlowConstructor>::DestructorAtExit* lazy_;
-
-  DISALLOW_COPY_AND_ASSIGN(SlowDelegate);
 };
 
 }  // namespace
@@ -212,7 +212,8 @@
       base::PlatformThread::YieldCurrentThread();
     done_construction_ = true;
   }
-
+  BlockingConstructor(const BlockingConstructor&) = delete;
+  BlockingConstructor& operator=(const BlockingConstructor&) = delete;
   ~BlockingConstructor() {
     // Restore static state for the next test.
     base::subtle::NoBarrier_Store(&constructor_called_, 0);
@@ -229,7 +230,7 @@
     base::subtle::NoBarrier_Store(&complete_construction_, 1);
   }
 
-  bool done_construction() { return done_construction_; }
+  bool done_construction() const { return done_construction_; }
 
  private:
   // Use Atomic32 instead of AtomicFlag for them to be trivially initialized.
@@ -237,8 +238,6 @@
   static base::subtle::Atomic32 complete_construction_;
 
   bool done_construction_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(BlockingConstructor);
 };
 
 // A SimpleThread running at |thread_priority| which invokes |before_get|
@@ -252,6 +251,9 @@
       : SimpleThread("BlockingConstructorThread", Options(thread_priority)),
         lazy_(lazy),
         before_get_(std::move(before_get)) {}
+  BlockingConstructorThread(const BlockingConstructorThread&) = delete;
+  BlockingConstructorThread& operator=(const BlockingConstructorThread&) =
+      delete;
 
   void Run() override {
     if (before_get_)
@@ -262,8 +264,6 @@
  private:
   base::LazyInstance<BlockingConstructor>::DestructorAtExit* lazy_;
   base::OnceClosure before_get_;
-
-  DISALLOW_COPY_AND_ASSIGN(BlockingConstructorThread);
 };
 
 // static
diff --git a/base/logging.cc b/base/logging.cc
index 3ced75a20..2696c0e 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -18,6 +18,8 @@
 #include <limits.h>
 #include <stdint.h>
 
+#include <vector>
+
 #include "base/pending_task.h"
 #include "base/stl_util.h"
 #include "base/task/common/task_annotator.h"
@@ -635,26 +637,28 @@
        public:
         explicit ASLClient(const std::string& facility)
             : client_(asl_open(nullptr, facility.c_str(), ASL_OPT_NO_DELAY)) {}
+        ASLClient(const ASLClient&) = delete;
+        ASLClient& operator=(const ASLClient&) = delete;
         ~ASLClient() { asl_close(client_); }
 
         aslclient get() const { return client_; }
 
        private:
         aslclient client_;
-        DISALLOW_COPY_AND_ASSIGN(ASLClient);
       } asl_client(main_bundle_id.empty() ? main_bundle_id
                                           : "com.apple.console");
 
       const class ASLMessage {
        public:
         ASLMessage() : message_(asl_new(ASL_TYPE_MSG)) {}
+        ASLMessage(const ASLMessage&) = delete;
+        ASLMessage& operator=(const ASLMessage&) = delete;
         ~ASLMessage() { asl_free(message_); }
 
         aslmsg get() const { return message_; }
 
        private:
         aslmsg message_;
-        DISALLOW_COPY_AND_ASSIGN(ASLMessage);
       } asl_message;
 
       // By default, messages are only readable by the admin group. Explicitly
@@ -697,6 +701,8 @@
         explicit OSLog(const char* subsystem)
             : os_log_(subsystem ? os_log_create(subsystem, "chromium_logging")
                                 : OS_LOG_DEFAULT) {}
+        OSLog(const OSLog&) = delete;
+        OSLog& operator=(const OSLog&) = delete;
         ~OSLog() {
           if (os_log_ != OS_LOG_DEFAULT) {
             os_release(os_log_);
@@ -706,7 +712,6 @@
 
        private:
         os_log_t os_log_;
-        DISALLOW_COPY_AND_ASSIGN(OSLog);
       } log(main_bundle_id.empty() ? nullptr : main_bundle_id.c_str());
       const os_log_type_t os_log_type = [](LogSeverity severity) {
         switch (severity) {
diff --git a/base/logging.h b/base/logging.h
index cbf6da4..9e06ae9 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -16,7 +16,6 @@
 #include "base/callback_forward.h"
 #include "base/compiler_specific.h"
 #include "base/dcheck_is_on.h"
-#include "base/macros.h"
 #include "base/scoped_clear_last_error.h"
 #include "base/strings/string_piece_forward.h"
 
@@ -336,10 +335,9 @@
 class BASE_EXPORT ScopedLogAssertHandler {
  public:
   explicit ScopedLogAssertHandler(LogAssertHandlerFunction handler);
+  ScopedLogAssertHandler(const ScopedLogAssertHandler&) = delete;
+  ScopedLogAssertHandler& operator=(const ScopedLogAssertHandler&) = delete;
   ~ScopedLogAssertHandler();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ScopedLogAssertHandler);
 };
 
 // Sets the Log Message Handler that gets passed every log message before
@@ -580,7 +578,8 @@
 
   // Used for CHECK().  Implied severity = LOG_FATAL.
   LogMessage(const char* file, int line, const char* condition);
-
+  LogMessage(const LogMessage&) = delete;
+  LogMessage& operator=(const LogMessage&) = delete;
   virtual ~LogMessage();
 
   std::ostream& stream() { return stream_; }
@@ -616,8 +615,6 @@
                             bool enable_timestamp,
                             bool enable_tickcount);
 #endif
-
-  DISALLOW_COPY_AND_ASSIGN(LogMessage);
 };
 
 // This class is used to explicitly ignore values in the conditional
@@ -650,14 +647,13 @@
                        int line,
                        LogSeverity severity,
                        SystemErrorCode err);
-
+  Win32ErrorLogMessage(const Win32ErrorLogMessage&) = delete;
+  Win32ErrorLogMessage& operator=(const Win32ErrorLogMessage&) = delete;
   // Appends the error message before destructing the encapsulated class.
   ~Win32ErrorLogMessage() override;
 
  private:
   SystemErrorCode err_;
-
-  DISALLOW_COPY_AND_ASSIGN(Win32ErrorLogMessage);
 };
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
 // Appends a formatted system message of the errno type
@@ -667,14 +663,13 @@
                   int line,
                   LogSeverity severity,
                   SystemErrorCode err);
-
+  ErrnoLogMessage(const ErrnoLogMessage&) = delete;
+  ErrnoLogMessage& operator=(const ErrnoLogMessage&) = delete;
   // Appends the error message before destructing the encapsulated class.
   ~ErrnoLogMessage() override;
 
  private:
   SystemErrorCode err_;
-
-  DISALLOW_COPY_AND_ASSIGN(ErrnoLogMessage);
 };
 #endif  // OS_WIN
 
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc
index b11ce9d..389f1ef4 100644
--- a/base/logging_unittest.cc
+++ b/base/logging_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/logging.h"
-#include "base/macros.h"
 #include "base/no_destructor.h"
 #include "base/run_loop.h"
 #include "base/sanitizer_buildflags.h"
@@ -719,6 +718,8 @@
     : public fuchsia::logger::testing::LogListenerSafe_TestBase {
  public:
   TestLogListenerSafe() = default;
+  TestLogListenerSafe(const TestLogListenerSafe&) = delete;
+  TestLogListenerSafe& operator=(const TestLogListenerSafe&) = delete;
   ~TestLogListenerSafe() override = default;
 
   void set_on_dump_logs_done(base::OnceClosure on_dump_logs_done) {
@@ -755,8 +756,6 @@
   fuchsia::logger::LogListenerSafePtr log_listener_;
   std::vector<fuchsia::logger::LogMessage> log_messages_;
   base::OnceClosure on_dump_logs_done_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestLogListenerSafe);
 };
 
 // Verifies that calling the log macro goes to the Fuchsia system logs.
diff --git a/base/logging_win.h b/base/logging_win.h
index cdde7bb..8aca72b9 100644
--- a/base/logging_win.h
+++ b/base/logging_win.h
@@ -11,7 +11,6 @@
 
 #include "base/base_export.h"
 #include "base/logging.h"
-#include "base/macros.h"
 #include "base/win/event_trace_provider.h"
 
 namespace base {
@@ -55,6 +54,8 @@
 // with Event Tracing for Windows.
 class BASE_EXPORT LogEventProvider : public base::win::EtwTraceProvider {
  public:
+  LogEventProvider(const LogEventProvider&) = delete;
+  LogEventProvider& operator=(const LogEventProvider&) = delete;
   static LogEventProvider* GetInstance();
 
   static bool LogMessage(logging::LogSeverity severity, const char* file,
@@ -76,7 +77,6 @@
   logging::LogSeverity old_log_level_;
 
   friend struct base::StaticMemorySingletonTraits<LogEventProvider>;
-  DISALLOW_COPY_AND_ASSIGN(LogEventProvider);
 };
 
 }  // namespace logging
diff --git a/base/native_library_unittest.cc b/base/native_library_unittest.cc
index 623f636..3933202d 100644
--- a/base/native_library_unittest.cc
+++ b/base/native_library_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "base/files/file_path.h"
-#include "base/macros.h"
 #include "base/native_library.h"
 #include "base/path_service.h"
 #include "base/test/native_library_test_utils.h"
@@ -88,7 +87,8 @@
         exe_path.AppendASCII(kTestLibraryName), options, nullptr);
     CHECK(library_);
   }
-
+  TestLibrary(const TestLibrary&) = delete;
+  TestLibrary& operator=(const TestLibrary&) = delete;
   ~TestLibrary() {
     UnloadNativeLibrary(library_);
   }
@@ -101,8 +101,6 @@
 
  private:
   NativeLibrary library_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestLibrary);
 };
 
 // NativeLibraaryTest.LoadLibrary is failing on M tablets only.
diff --git a/base/no_destructor_unittest.cc b/base/no_destructor_unittest.cc
index 63d5c13e..54ac1b53 100644
--- a/base/no_destructor_unittest.cc
+++ b/base/no_destructor_unittest.cc
@@ -4,8 +4,10 @@
 
 #include "base/no_destructor.h"
 
+#include <memory>
 #include <string>
 #include <utility>
+#include <vector>
 
 #include "base/atomicops.h"
 #include "base/barrier_closure.h"
@@ -93,7 +95,8 @@
       PlatformThread::YieldCurrentThread();
     done_construction_ = true;
   }
-
+  BlockingConstructor(const BlockingConstructor&) = delete;
+  BlockingConstructor& operator=(const BlockingConstructor&) = delete;
   ~BlockingConstructor() = delete;
 
   // Returns true if BlockingConstructor() was entered.
@@ -106,7 +109,7 @@
     subtle::NoBarrier_Store(&complete_construction_, 1);
   }
 
-  bool done_construction() { return done_construction_; }
+  bool done_construction() const { return done_construction_; }
 
  private:
   // Use Atomic32 instead of AtomicFlag for them to be trivially initialized.
@@ -114,8 +117,6 @@
   static subtle::Atomic32 complete_construction_;
 
   bool done_construction_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(BlockingConstructor);
 };
 
 // static
@@ -132,6 +133,9 @@
                             OnceClosure before_get)
       : SimpleThread("BlockingConstructorThread", Options(thread_priority)),
         before_get_(std::move(before_get)) {}
+  BlockingConstructorThread(const BlockingConstructorThread&) = delete;
+  BlockingConstructorThread& operator=(const BlockingConstructorThread&) =
+      delete;
 
   void Run() override {
     if (before_get_)
@@ -143,8 +147,6 @@
 
  private:
   OnceClosure before_get_;
-
-  DISALLOW_COPY_AND_ASSIGN(BlockingConstructorThread);
 };
 
 }  // namespace
diff --git a/base/observer_list.h b/base/observer_list.h
index 52c8fad0..28369a25 100644
--- a/base/observer_list.h
+++ b/base/observer_list.h
@@ -15,7 +15,6 @@
 
 #include "base/check_op.h"
 #include "base/gtest_prod_util.h"
-#include "base/macros.h"
 #include "base/notreached.h"
 #include "base/observer_list_internal.h"
 #include "base/sequence_checker.h"
@@ -247,7 +246,8 @@
     // Sequence checks only apply when iterators are live.
     DETACH_FROM_SEQUENCE(iteration_sequence_checker_);
   }
-
+  ObserverList(const ObserverList&) = delete;
+  ObserverList& operator=(const ObserverList&) = delete;
   ~ObserverList() {
     // If there are live iterators, ensure destruction is thread-safe.
     if (!live_iterators_.empty())
@@ -337,8 +337,6 @@
   const ObserverListPolicy policy_;
 
   SEQUENCE_CHECKER(iteration_sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(ObserverList);
 };
 
 template <class ObserverType, bool check_empty = false>
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 5f64aa2..41ac39e 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-0.20200922.3.1
+0.20200923.0.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 5f64aa2..41ac39e 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-0.20200922.3.1
+0.20200923.0.1
diff --git a/chrome/VERSION b/chrome/VERSION
index cdbeef96..e5811f6 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=87
 MINOR=0
-BUILD=4272
+BUILD=4273
 PATCH=0
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantLiteScriptCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantLiteScriptCoordinator.java
index a1a03296..584cb3a 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantLiteScriptCoordinator.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantLiteScriptCoordinator.java
@@ -84,6 +84,15 @@
             case LiteScriptFinishedState.LITE_SCRIPT_PROMPT_FAILED_CONDITION_NO_LONGER_TRUE:
             case LiteScriptFinishedState.LITE_SCRIPT_PROMPT_FAILED_OTHER:
             case LiteScriptFinishedState.LITE_SCRIPT_PROMPT_SUCCEEDED:
+            case LiteScriptFinishedState.LITE_SCRIPT_BROWSE_FAILED_NAVIGATE:
+            case LiteScriptFinishedState.LITE_SCRIPT_BROWSE_FAILED_OTHER:
+            case LiteScriptFinishedState.LITE_SCRIPT_GET_ACTIONS_FAILED:
+            case LiteScriptFinishedState.LITE_SCRIPT_GET_ACTIONS_PARSE_ERROR:
+            case LiteScriptFinishedState.LITE_SCRIPT_INVALID_SCRIPT:
+            case LiteScriptFinishedState.LITE_SCRIPT_PATH_MISMATCH:
+            case LiteScriptFinishedState.LITE_SCRIPT_SERVICE_DELETED:
+            case LiteScriptFinishedState.LITE_SCRIPT_UNKNOWN_FAILURE:
+            case LiteScriptFinishedState.LITE_SCRIPT_UNSAFE_ACTIONS:
                 break;
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuChipController.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuChipController.java
index 9cec9ec..8dbd134e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuChipController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuChipController.java
@@ -127,8 +127,17 @@
         mPopupWindow.show();
     }
 
-    @VisibleForTesting
+    // This method should only be used in test files.  It is not marked
+    // @VisibleForTesting to allow the Coordinator to reference it in its
+    // own testing methods.
     AnchoredPopupWindow getCurrentPopupWindowForTesting() {
         return mPopupWindow;
     }
+
+    // This method should only be used in test files.  It is not marked
+    // @VisibleForTesting to allow the Coordinator to reference it in its
+    // own testing methods.
+    void clickChipForTesting() {
+        onClick(mChipView);
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java
index 2a55aa8..5b7d838 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinator.java
@@ -36,6 +36,7 @@
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 import org.chromium.ui.modelutil.ModelListAdapter;
 import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.ui.widget.AnchoredPopupWindow;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -299,6 +300,25 @@
                 activity, PerformanceClass.PERFORMANCE_UNKNOWN, params, profile);
     }
 
+    @VisibleForTesting
+    void simulateShoppyImageClassificationForTesting() {
+        // Don't need to initialize controller because that should be triggered by
+        // forcing feature flags.
+        mChipController.handleImageClassification(true);
+    }
+
+    // Public only to allow references from RevampedContextMenuUtils.java
+    public void clickChipForTesting() {
+        mChipController.clickChipForTesting(); // IN-TEST
+    }
+
+    // Public only to allow references from RevampedContextMenuUtils.java
+    public AnchoredPopupWindow getCurrentPopupWindowForTesting() {
+        // Don't need to initialize controller because that should be triggered by
+        // forcing feature flags.
+        return mChipController.getCurrentPopupWindowForTesting(); // IN-TEST
+    }
+
     public void clickListItemForTesting(int id) {
         mListView.performItemClick(null, -1, id);
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java
index c45c8d0..e91fac6a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java
@@ -9,6 +9,7 @@
 import android.content.ClipData;
 import android.content.ClipboardManager;
 import android.content.Context;
+import android.os.Looper;
 import android.support.test.InstrumentationRegistry;
 import android.view.KeyEvent;
 
@@ -408,6 +409,66 @@
 
     @Test
     @MediumTest
+    @Feature({"Browser"})
+    @Features.EnableFeatures({ChromeFeatureList.CONTEXT_MENU_GOOGLE_LENS_CHIP})
+    public void testSelectLensChip() throws Throwable {
+        // Required to avoid runtime error.
+        Looper.prepare();
+
+        Tab tab = mDownloadTestRule.getActivity().getActivityTab();
+        ShareHelper.setIgnoreActivityNotFoundExceptionForTesting(true);
+        hardcodeTestImageForSharing(TEST_JPG_IMAGE_FILE_EXTENSION);
+
+        RevampedContextMenuCoordinator menuCoordinator =
+                RevampedContextMenuUtils.openContextMenu(tab, "testImage");
+        // Needs to run on UI thread so creation happens on same thread as dismissal.
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> menuCoordinator.simulateShoppyImageClassificationForTesting());
+
+        Assert.assertTrue("Chip popoup not showing.",
+                menuCoordinator.getCurrentPopupWindowForTesting().isShowing());
+
+        RevampedContextMenuUtils.selectAlreadyOpenedContextMenuChipWithExpectedIntent(
+                InstrumentationRegistry.getInstrumentation(), mDownloadTestRule.getActivity(),
+                menuCoordinator, "testImage", R.id.contextmenu_shop_image_with_google_lens,
+                "com.google.android.googlequicksearchbox");
+        Assert.assertEquals("Selection histogram pings not equal to one", 1,
+                RecordHistogram.getHistogramTotalCountForTesting(
+                        "ContextMenu.SelectedOptionAndroid.Image"));
+        Assert.assertFalse("Chip popoup still showing.",
+                menuCoordinator.getCurrentPopupWindowForTesting().isShowing());
+    }
+
+    // Assert that focus is unchanged and that the chip popup does not block the dismissal of the
+    // context menu.
+    @Test
+    @MediumTest
+    @Features.EnableFeatures({ChromeFeatureList.CONTEXT_MENU_GOOGLE_LENS_CHIP})
+    public void testDismissContextMenuOnClickLensChipEnabled() throws TimeoutException {
+        // Required to avoid runtime error.
+        Looper.prepare();
+
+        Tab tab = mDownloadTestRule.getActivity().getActivityTab();
+        RevampedContextMenuCoordinator menuCoordinator =
+                RevampedContextMenuUtils.openContextMenu(tab, "testImage");
+        // Needs to run on UI thread so creation happens on same thread as dismissal.
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> menuCoordinator.simulateShoppyImageClassificationForTesting());
+        Assert.assertNotNull("Context menu was not properly created", menuCoordinator);
+        CriteriaHelper.pollUiThread(() -> {
+            return !mDownloadTestRule.getActivity().hasWindowFocus();
+        }, "Context menu did not have window focus");
+
+        TestTouchUtils.singleClickView(InstrumentationRegistry.getInstrumentation(), tab.getView(),
+                tab.getView().getWidth() - 5, tab.getView().getHeight() - 5);
+
+        CriteriaHelper.pollUiThread(() -> {
+            return mDownloadTestRule.getActivity().hasWindowFocus();
+        }, "Activity did not regain focus.");
+    }
+
+    @Test
+    @MediumTest
     public void testDismissContextMenuOnClick() throws TimeoutException {
         Tab tab = mDownloadTestRule.getActivity().getActivityTab();
         RevampedContextMenuCoordinator menuCoordinator =
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 265bd22..b54c439 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -352,6 +352,12 @@
       =1 {{COUNT} compromised password}
       other {{COUNT} compromised passwords}}
   </message>
+  <message name="IDS_SETTINGS_INSECURE_PASSWORDS_COUNT" desc="Number of insecure passwords present in the database">
+    {COUNT, plural,
+      =0 {No security issues found}
+      =1 {Found {COUNT} security issue}
+      other {Found {COUNT} security issues}}
+  </message>
   <message name="IDS_SETTINGS_CHECK_PASSWORDS_AGAIN" desc="Button to start bulk password check manually in passwords check section.">
     Check again
   </message>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_INSECURE_PASSWORDS_COUNT.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_INSECURE_PASSWORDS_COUNT.png.sha1
new file mode 100644
index 0000000..bfdf6d7f
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_INSECURE_PASSWORDS_COUNT.png.sha1
@@ -0,0 +1 @@
+121c305725484c75be7ab0ed6f627abdfc5023ac
\ No newline at end of file
diff --git a/chrome/app/sharesheet_strings.grdp b/chrome/app/sharesheet_strings.grdp
index 01f6838..ccc3415b 100644
--- a/chrome/app/sharesheet_strings.grdp
+++ b/chrome/app/sharesheet_strings.grdp
@@ -5,4 +5,13 @@
   <message name="IDS_SHARESHEET_TITLE_LABEL" desc="The label to be shown as the title of the sharesheet bubble when a user clicks on the share button.">
     Share
   </message>
+  <message name="IDS_SHARESHEET_APPS_LIST_LABEL" desc="The label to be shown before the list of apps.">
+    Apps list
+  </message>
+  <message name="IDS_SHARESHEET_MORE_APPS_LABEL" desc="The label for the button at the bottom of the sharesheet which clicks into the expanded sharesheet.">
+    More apps
+  </message>
+  <message name="IDS_SHARESHEET_FEWER_APPS_LABEL" desc="The label for the button at the bottom of the sharesheet which clicks into the default sharesheet.">
+    Fewer apps
+  </message>
 </grit-part>
diff --git a/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_APPS_LIST_LABEL.png.sha1 b/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_APPS_LIST_LABEL.png.sha1
new file mode 100644
index 0000000..82fb6857
--- /dev/null
+++ b/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_APPS_LIST_LABEL.png.sha1
@@ -0,0 +1 @@
+32501db09db820361f32e8debbde95b81810da7b
\ No newline at end of file
diff --git a/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_FEWER_APPS_LABEL.png.sha1 b/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_FEWER_APPS_LABEL.png.sha1
new file mode 100644
index 0000000..29a5166
--- /dev/null
+++ b/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_FEWER_APPS_LABEL.png.sha1
@@ -0,0 +1 @@
+9eea332d3d39da4a1e5887e755bcf47a09127eb6
\ No newline at end of file
diff --git a/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_MORE_APPS_LABEL.png.sha1 b/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_MORE_APPS_LABEL.png.sha1
new file mode 100644
index 0000000..4b23489
--- /dev/null
+++ b/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_MORE_APPS_LABEL.png.sha1
@@ -0,0 +1 @@
+cb42423ee0b152a7460364e832abf984524d26bb
\ No newline at end of file
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn
index e10625e8..acb69dc 100644
--- a/chrome/app/vector_icons/BUILD.gn
+++ b/chrome/app/vector_icons/BUILD.gn
@@ -10,6 +10,7 @@
 aggregate_vector_icons("chrome_vector_icons") {
   icon_directory = "."
 
+  # Keep sorted alphabetically.
   icons = [
     "account_box.icon",
     "account_child.icon",
@@ -18,24 +19,21 @@
     "apps.icon",
     "autofill/webauthn_dialog_header.icon",
     "autofill/webauthn_dialog_header_dark.icon",
+    "back_arrow_touch.icon",
     "blocked_redirect.icon",
+    "bookmarkbar_touch_overflow.icon",
     "browser_tools.icon",
     "browser_tools_error.icon",
+    "browser_tools_error_touch.icon",
+    "browser_tools_touch.icon",
     "browser_tools_update.icon",
+    "browser_tools_update_touch.icon",
     "caret_down.icon",
     "caret_up.icon",
+    "cast_for_education.icon",
     "click_to_call_illustration.icon",
     "click_to_call_illustration_dark.icon",
     "close_all.icon",
-
-    # Alternative squarer content_paste icon optimised for display at 18x18dip.
-    # Currently only used in the Page Info bubble.
-    "back_arrow_touch.icon",
-    "bookmarkbar_touch_overflow.icon",
-    "browser_tools_error_touch.icon",
-    "browser_tools_touch.icon",
-    "browser_tools_update_touch.icon",
-    "cast_for_education.icon",
     "computer_with_circle_background.icon",
     "copy.icon",
     "crashed_tab.icon",
@@ -50,10 +48,12 @@
     "fullscreen.icon",
     "generic_stop.icon",
     "globe.icon",
+    "guest_menu_art.icon",
     "hardware_computer.icon",
     "hardware_smartphone.icon",
     "horizontal_menu.icon",
     "incognito.icon",
+    "incognito_menu_art.icon",
     "incognito_profile.icon",
     "input.icon",
     "key.icon",
diff --git a/chrome/app/vector_icons/guest_menu_art.icon b/chrome/app/vector_icons/guest_menu_art.icon
new file mode 100644
index 0000000..d26b82c
--- /dev/null
+++ b/chrome/app/vector_icons/guest_menu_art.icon
@@ -0,0 +1,104 @@
+// 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.
+
+CANVAS_DIMENSIONS, 272,
+MOVE_TO, 209.9f, 56.8f,
+CUBIC_TO, 209.3f, 56.2f, 208.4f, 56, 207.6f, 56.2f,
+LINE_TO, 200.4f, 58.1f,
+CUBIC_TO, 199.6f, 58.3f, 198.9f, 59, 198.7f, 59.8f,
+LINE_TO, 196.8f, 67,
+CUBIC_TO, 196.6f, 67.8f, 196.8f, 68.7f, 197.4f, 69.3f,
+LINE_TO, 200, 72,
+H_LINE_TO, 202.1f,
+LINE_TO, 198.4f, 68.3f,
+CUBIC_TO, 198.2f, 68.1f, 198.1f, 67.8f, 198.2f, 67.5f,
+LINE_TO, 200.1f, 60.3f,
+CUBIC_TO, 200.2f, 60, 200.4f, 59.8f, 200.7f, 59.7f,
+LINE_TO, 207.9f, 57.8f,
+CUBIC_TO, 208.2f, 57.7f, 208.5f, 57.8f, 208.7f, 58,
+LINE_TO, 214, 63.3f,
+CUBIC_TO, 214.2f, 63.5f, 214.3f, 63.8f, 214.2f, 64.1f,
+LINE_TO, 212.3f, 71.3f,
+CUBIC_TO, 212.2f, 71.6f, 212, 71.8f, 211.7f, 71.9f,
+LINE_TO, 211.3f, 72,
+H_LINE_TO, 213.7f,
+CUBIC_TO, 213.7f, 71.9f, 213.8f, 71.8f, 213.8f, 71.7f,
+LINE_TO, 215.7f, 64.5f,
+CUBIC_TO, 215.9f, 63.7f, 215.7f, 62.8f, 215.1f, 62.2f,
+LINE_TO, 209.9f, 56.8f,
+CLOSE,
+MOVE_TO, 176.1f, 6.4f,
+CUBIC_TO, 176.1f, 15.3f, 183.3f, 22.5f, 192.2f, 22.5f,
+CUBIC_TO, 201.1f, 22.5f, 208.3f, 15.3f, 208.3f, 6.4f,
+CUBIC_TO, 208.3f, 4.1f, 207.8f, 1.9f, 207, 0,
+H_LINE_TO, 177.5f,
+CUBIC_TO, 176.6f, 2, 176.1f, 4.1f, 176.1f, 6.4f,
+CLOSE,
+MOVE_TO, 102.5f, 18.7f,
+CUBIC_TO, 105.92f, 18.7f, 108.7f, 15.92f, 108.7f, 12.5f,
+CUBIC_TO, 108.7f, 9.08f, 105.92f, 6.3f, 102.5f, 6.3f,
+CUBIC_TO, 99.08f, 6.3f, 96.3f, 9.08f, 96.3f, 12.5f,
+CUBIC_TO, 96.3f, 15.92f, 99.08f, 18.7f, 102.5f, 18.7f,
+CLOSE,
+MOVE_TO, 56.1f, 4.9f,
+CUBIC_TO, 58.3f, 8, 57.6f, 12.4f, 54.4f, 14.6f,
+CUBIC_TO, 52.9f, 15.7f, 51, 16.1f, 49.2f, 15.8f,
+CUBIC_TO, 47.4f, 15.5f, 45.8f, 14.5f, 44.7f, 13,
+LINE_TO, 35.9f, 0.4f,
+CUBIC_TO, 35.8f, 0.3f, 35.7f, 0.1f, 35.7f, 0,
+H_LINE_TO, 34,
+CUBIC_TO, 34.2f, 0.4f, 34.4f, 0.8f, 34.7f, 1.2f,
+LINE_TO, 43.6f, 13.8f,
+CUBIC_TO, 44.9f, 15.6f, 46.8f, 16.9f, 49.1f, 17.3f,
+CUBIC_TO, 49.6f, 17.4f, 50.1f, 17.4f, 50.6f, 17.4f,
+CUBIC_TO, 52.3f, 17.4f, 54, 16.9f, 55.5f, 15.9f,
+CUBIC_TO, 59.3f, 13.2f, 60.2f, 7.9f, 57.5f, 4.1f,
+LINE_TO, 54.5f, 0,
+H_LINE_TO, 52.7f,
+LINE_TO, 56.1f, 4.9f,
+CLOSE,
+MOVE_TO, 272, 27.2f,
+CUBIC_TO, 270.8f, 27.1f, 269.7f, 27.3f, 268.6f, 27.7f,
+CUBIC_TO, 267.3f, 28.2f, 265.9f, 28.3f, 264.6f, 27.8f,
+LINE_TO, 264, 27.6f,
+CUBIC_TO, 262.7f, 27.1f, 261.7f, 26.1f, 261.2f, 24.8f,
+CUBIC_TO, 260.4f, 22.9f, 258.8f, 21.4f, 256.6f, 20.8f,
+CUBIC_TO, 253.4f, 19.9f, 249.8f, 21.3f, 248.2f, 24.3f,
+CUBIC_TO, 246.1f, 28.2f, 247.9f, 32.9f, 251.9f, 34.4f,
+CUBIC_TO, 253.7f, 35.1f, 255.7f, 35.1f, 257.4f, 34.4f,
+CUBIC_TO, 258.7f, 33.9f, 260.1f, 33.8f, 261.3f, 34.3f,
+LINE_TO, 261.9f, 34.5f,
+CUBIC_TO, 263.2f, 35, 264.2f, 36, 264.7f, 37.3f,
+CUBIC_TO, 265.4f, 39, 266.8f, 40.4f, 268.6f, 41.1f,
+CUBIC_TO, 269.7f, 41.5f, 270.8f, 41.7f, 271.9f, 41.6f,
+V_LINE_TO, 27.2f,
+H_LINE_TO, 272,
+CLOSE,
+MOVE_TO, 0, 34.1f,
+V_LINE_TO, 56.9f,
+LINE_TO, 25, 48.3f,
+CUBIC_TO, 25.8f, 48, 26.2f, 47.1f, 25.9f, 46.3f,
+CUBIC_TO, 21.6f, 36.2f, 10.5f, 31, 0, 34.1f,
+CLOSE,
+MOVE_TO, 65.9f, 52.9f,
+CUBIC_TO, 65.3f, 52.4f, 64.5f, 52.7f, 64.3f, 53.4f,
+LINE_TO, 60.4f, 72,
+H_LINE_TO, 65.1f,
+LINE_TO, 72.35f, 69.6f,
+LINE_TO, 79.6f, 67.2f,
+CUBIC_TO, 80.3f, 67, 80.5f, 66, 79.9f, 65.6f,
+LINE_TO, 65.9f, 52.9f,
+CLOSE,
+NEW_PATH,
+STROKE, 1,
+MOVE_TO, 0.5f, 4,
+CUBIC_TO, 0.5f, 2.07f, 2.07f, 0.5f, 4, 0.5f,
+H_LINE_TO, 268,
+CUBIC_TO, 269.93f, 0.5f, 271.5f, 2.07f, 271.5f, 4,
+V_LINE_TO, 68,
+CUBIC_TO, 271.5f, 69.93f, 269.93f, 71.5f, 268, 71.5f,
+H_LINE_TO, 4,
+CUBIC_TO, 2.07f, 71.5f, 0.5f, 69.93f, 0.5f, 68,
+V_LINE_TO, 4,
+CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/incognito_menu_art.icon b/chrome/app/vector_icons/incognito_menu_art.icon
new file mode 100644
index 0000000..5fa6158
--- /dev/null
+++ b/chrome/app/vector_icons/incognito_menu_art.icon
@@ -0,0 +1,116 @@
+// 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.
+
+CANVAS_DIMENSIONS, 272,
+MOVE_TO, 203.7f, 0,
+H_LINE_TO, 268,
+CUBIC_TO, 270.21f, 0, 272, 1.79f, 272, 4,
+V_LINE_TO, 69,
+CUBIC_TO, 272, 71.21f, 270.21f, 73, 268, 73,
+H_LINE_TO, 259.4f,
+LINE_TO, 258, 61.6f,
+CUBIC_TO, 256.3f, 62.1f, 254.5f, 62.4f, 252.6f, 62.4f,
+CUBIC_TO, 243.1f, 62.4f, 235.4f, 55.1f, 234.5f, 45.7f,
+CUBIC_TO, 229.4f, 42.5f, 225.3f, 44.5f, 223.8f, 45.6f,
+CUBIC_TO, 223.1f, 55, 215.3f, 62.4f, 205.7f, 62.4f,
+CUBIC_TO, 195.6f, 62.4f, 187.5f, 54.2f, 187.5f, 44.2f,
+CUBIC_TO, 187.5f, 34.1f, 195.7f, 26, 205.7f, 26,
+CUBIC_TO, 214.3f, 26, 221.5f, 32, 223.4f, 40.1f,
+CUBIC_TO, 226.4f, 38.8f, 230.5f, 38.3f, 234.9f, 40.2f,
+CUBIC_TO, 236.8f, 32.1f, 244, 26.1f, 252.6f, 26.1f,
+H_LINE_TO, 253.8f,
+LINE_TO, 253.2f, 20.8f,
+H_LINE_TO, 182.2f,
+H_LINE_TO, 94.4f,
+LINE_TO, 100.1f, 13.5f,
+H_LINE_TO, 172.1f,
+LINE_TO, 167.1f, 0,
+H_LINE_TO, 188.5f,
+LINE_TO, 184, 15.5f,
+H_LINE_TO, 252.6f,
+LINE_TO, 252, 10.3f,
+H_LINE_TO, 199.8f,
+LINE_TO, 203.7f, 0,
+CLOSE,
+MOVE_TO, 68.2f, 0,
+H_LINE_TO, 4,
+CUBIC_TO, 1.79f, 0, 0, 1.79f, 0, 4,
+V_LINE_TO, 69,
+CUBIC_TO, 0, 71.21f, 1.79f, 73, 4, 73,
+LINE_TO, 4.5f, 73,
+LINE_TO, 13.8f, 47.7f,
+CUBIC_TO, 16.4f, 49.4f, 19.5f, 50.4f, 22.8f, 50.4f,
+CUBIC_TO, 31.3f, 50.4f, 38.3f, 43.8f, 38.9f, 35.5f,
+CUBIC_TO, 40.3f, 34.5f, 44, 32.7f, 48.5f, 35.6f,
+CUBIC_TO, 49.2f, 43.9f, 56.1f, 50.4f, 64.6f, 50.4f,
+CUBIC_TO, 67.5f, 50.4f, 70.2f, 49.7f, 72.6f, 48.3f,
+LINE_TO, 53, 73,
+H_LINE_TO, 76.4f,
+CUBIC_TO, 74.4f, 69.3f, 73.2f, 65.1f, 73.2f, 60.6f,
+CUBIC_TO, 73.2f, 46.6f, 84.6f, 35.2f, 98.6f, 35.2f,
+CUBIC_TO, 110.6f, 35.2f, 120.6f, 43.6f, 123.3f, 54.8f,
+CUBIC_TO, 127.5f, 53, 133.2f, 52.3f, 139.3f, 54.9f,
+CUBIC_TO, 141.9f, 43.6f, 152, 35.2f, 164, 35.2f,
+CUBIC_TO, 168.8f, 35.2f, 173.3f, 36.6f, 177.1f, 38.9f,
+LINE_TO, 180.3f, 28,
+H_LINE_TO, 88.7f,
+LINE_TO, 80.1f, 38.8f,
+CUBIC_TO, 80.6f, 37.3f, 80.8f, 35.8f, 80.8f, 34.2f,
+CUBIC_TO, 80.8f, 25.3f, 73.5f, 18, 64.6f, 18,
+CUBIC_TO, 56.9f, 18, 50.5f, 23.4f, 48.8f, 30.5f,
+CUBIC_TO, 44.9f, 28.9f, 41.3f, 29.3f, 38.6f, 30.5f,
+CUBIC_TO, 37, 24, 31.6f, 19, 24.9f, 18.1f,
+LINE_TO, 26.7f, 13.3f,
+H_LINE_TO, 85.5f,
+V_LINE_TO, 8.7f,
+H_LINE_TO, 28.4f,
+LINE_TO, 30.1f, 4.1f,
+H_LINE_TO, 69.7f,
+LINE_TO, 68.2f, 0,
+CLOSE,
+MOVE_TO, 85.3f, 73,
+H_LINE_TO, 111.7f,
+CUBIC_TO, 114.7f, 69.7f, 116.6f, 65.4f, 116.6f, 60.6f,
+CUBIC_TO, 116.6f, 50.6f, 108.5f, 42.5f, 98.5f, 42.5f,
+CUBIC_TO, 88.5f, 42.5f, 80.4f, 50.6f, 80.4f, 60.6f,
+CUBIC_TO, 80.4f, 65.4f, 82.3f, 69.8f, 85.3f, 73,
+CLOSE,
+MOVE_TO, 120.5f, 73,
+H_LINE_TO, 141.6f,
+CUBIC_TO, 139.9f, 69.9f, 138.8f, 66.5f, 138.5f, 62.8f,
+CUBIC_TO, 131.5f, 58.3f, 125.8f, 61.2f, 123.6f, 62.7f,
+CUBIC_TO, 123.3f, 66.4f, 122.2f, 69.9f, 120.5f, 73,
+CLOSE,
+MOVE_TO, 150.4f, 73,
+H_LINE_TO, 167.2f,
+LINE_TO, 174.6f, 46.2f,
+CUBIC_TO, 171.5f, 43.9f, 167.7f, 42.5f, 163.6f, 42.5f,
+CUBIC_TO, 153.6f, 42.5f, 145.5f, 50.6f, 145.5f, 60.6f,
+CUBIC_TO, 145.5f, 65.4f, 147.4f, 69.8f, 150.4f, 73,
+CLOSE,
+MOVE_TO, 76.2f, 34.2f,
+CUBIC_TO, 76.2f, 40.61f, 71.01f, 45.8f, 64.6f, 45.8f,
+CUBIC_TO, 58.19f, 45.8f, 53, 40.61f, 53, 34.2f,
+CUBIC_TO, 53, 27.79f, 58.19f, 22.6f, 64.6f, 22.6f,
+CUBIC_TO, 71.01f, 22.6f, 76.2f, 27.79f, 76.2f, 34.2f,
+CLOSE,
+MOVE_TO, 34.4f, 34.2f,
+CUBIC_TO, 34.4f, 27.9f, 29.4f, 22.8f, 23.2f, 22.6f,
+LINE_TO, 15.5f, 43.2f,
+CUBIC_TO, 17.5f, 44.8f, 20, 45.8f, 22.8f, 45.8f,
+CUBIC_TO, 29.2f, 45.8f, 34.4f, 40.6f, 34.4f, 34.2f,
+CLOSE,
+MOVE_TO, 218.7f, 44.2f,
+CUBIC_TO, 218.7f, 51.38f, 212.88f, 57.2f, 205.7f, 57.2f,
+CUBIC_TO, 198.52f, 57.2f, 192.7f, 51.38f, 192.7f, 44.2f,
+CUBIC_TO, 192.7f, 37.02f, 198.52f, 31.2f, 205.7f, 31.2f,
+CUBIC_TO, 212.88f, 31.2f, 218.7f, 37.02f, 218.7f, 44.2f,
+CLOSE,
+MOVE_TO, 239.6f, 44.2f,
+CUBIC_TO, 239.6f, 51.4f, 245.4f, 57.2f, 252.6f, 57.2f,
+CUBIC_TO, 254.3f, 57.2f, 255.9f, 56.9f, 257.4f, 56.3f,
+LINE_TO, 254.4f, 31.3f,
+CUBIC_TO, 253.8f, 31.2f, 253.2f, 31.2f, 252.5f, 31.2f,
+CUBIC_TO, 245.4f, 31.1f, 239.6f, 37, 239.6f, 44.2f,
+CLOSE
\ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 6993b98..4595b9d 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3485,6 +3485,15 @@
      kOsCrOS,
      SINGLE_VALUE_TYPE(
          ::switches::kEnableExperimentalAccessibilityChromeVoxTutorial)},
+    {"enable-experimental-accessibility-magnifier-new-focus-following",
+     flag_descriptions::
+         kExperimentalAccessibilityMagnifierNewFocusFollowingName,
+     flag_descriptions::
+         kExperimentalAccessibilityMagnifierNewFocusFollowingDescription,
+     kOsCrOS,
+     SINGLE_VALUE_TYPE(
+         ::switches::
+             kEnableExperimentalAccessibilityMagnifierNewFocusFollowing)},
 #endif  // OS_CHROMEOS
 #if defined(OS_MAC)
     {"enable-immersive-fullscreen-toolbar",
diff --git a/chrome/browser/apps/app_service/app_service_metrics.cc b/chrome/browser/apps/app_service/app_service_metrics.cc
index 9927220..c731dcff 100644
--- a/chrome/browser/apps/app_service/app_service_metrics.cc
+++ b/chrome/browser/apps/app_service/app_service_metrics.cc
@@ -56,10 +56,11 @@
   kYouTubeMusic = 38,
   // This is our test SWA. It's only installed in tests.
   kMockSystemApp = 39,
+  kStadia = 40,
 
   // Add any new values above this one, and update kMaxValue to the highest
   // enumerator value.
-  kMaxValue = kMockSystemApp,
+  kMaxValue = kStadia,
 };
 
 void RecordDefaultAppLaunch(DefaultAppName default_app_name,
@@ -249,6 +250,8 @@
 #endif  // OS_CHROMEOS
   else if (app_id == chromeos::default_web_apps::kYoutubeMusicAppId)
     RecordDefaultAppLaunch(DefaultAppName::kYouTubeMusic, launch_source);
+  else if (app_id == chromeos::default_web_apps::kStadiaAppId)
+    RecordDefaultAppLaunch(DefaultAppName::kStadia, launch_source);
 
   // Above are default apps; below are built-in apps.
 
diff --git a/chrome/browser/chromeos/child_accounts/family_user_session_metrics.cc b/chrome/browser/chromeos/child_accounts/family_user_session_metrics.cc
index f393f4d..e0dafaa 100644
--- a/chrome/browser/chromeos/child_accounts/family_user_session_metrics.cc
+++ b/chrome/browser/chromeos/child_accounts/family_user_session_metrics.cc
@@ -10,7 +10,6 @@
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/user_metrics.h"
-#include "base/time/time.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
@@ -21,6 +20,9 @@
 
 constexpr int kEngagementHourBuckets = base::Time::kHoursPerDay;
 constexpr base::TimeDelta kOneHour = base::TimeDelta::FromHours(1);
+constexpr base::TimeDelta kMinSessionDuration = base::TimeDelta::FromSeconds(1);
+constexpr base::TimeDelta kMaxSessionDuration = base::TimeDelta::FromDays(1);
+constexpr int kSessionDurationBuckets = 100;
 
 // Returns the hour (0-23) within the day for given local time.
 int HourOfDay(base::Time time) {
@@ -81,12 +83,14 @@
     "FamilyUser.SessionEngagement.Weekend";
 const char FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName[] =
     "FamilyUser.SessionEngagement.Total";
+const char FamilyUserSessionMetrics::kSessionEngagementDurationHistogramName[] =
+    "FamilyUser.SessionEngagement.Duration";
 
 // static
 void FamilyUserSessionMetrics::RegisterProfilePrefs(
     PrefRegistrySimple* registry) {
-  registry->RegisterTimePref(
-      prefs::kFamilyUserMetricsSessionEngagementStartTime, base::Time());
+  registry->RegisterTimeDeltaPref(
+      prefs::kFamilyUserMetricsSessionEngagementDuration, base::TimeDelta());
 }
 
 FamilyUserSessionMetrics::FamilyUserSessionMetrics(PrefService* pref_service)
@@ -96,34 +100,57 @@
 }
 
 FamilyUserSessionMetrics::~FamilyUserSessionMetrics() {
-  if (is_user_active_) {
-    is_user_active_ = false;
-    UpdateUserEngagement();
+  // |active_session_start_| will be reset in UpdateUserEngagement() after user
+  // becomes inactive. |active_session_start_| equals to base::Time() indicates
+  // that UpdateUserEngagement(false) has already been called.
+  if (active_session_start_ != base::Time()) {
+    UpdateUserEngagement(/*is_user_active=*/false);
   }
 
   UsageTimeStateNotifier::GetInstance()->RemoveObserver(this);
 }
 
-void FamilyUserSessionMetrics::OnUsageTimeStateChange(
-    UsageTimeStateNotifier::UsageTimeState state) {
-  is_user_active_ = state == UsageTimeStateNotifier::UsageTimeState::ACTIVE;
-
-  UpdateUserEngagement();
+void FamilyUserSessionMetrics::OnNewDay() {
+  base::TimeDelta unreported_duration = pref_service_->GetTimeDelta(
+      prefs::kFamilyUserMetricsSessionEngagementDuration);
+  if (unreported_duration <= base::TimeDelta())
+    return;
+  base::UmaHistogramCustomTimes(kSessionEngagementDurationHistogramName,
+                                unreported_duration, kMinSessionDuration,
+                                kMaxSessionDuration, kSessionDurationBuckets);
+  pref_service_->ClearPref(prefs::kFamilyUserMetricsSessionEngagementDuration);
 }
 
-void FamilyUserSessionMetrics::UpdateUserEngagement() {
-  if (is_user_active_) {
+void FamilyUserSessionMetrics::SetActiveSessionStartForTesting(
+    base::Time time) {
+  active_session_start_ = time;
+}
+
+void FamilyUserSessionMetrics::OnUsageTimeStateChange(
+    UsageTimeStateNotifier::UsageTimeState state) {
+  UpdateUserEngagement(/*is_user_active=*/state ==
+                       UsageTimeStateNotifier::UsageTimeState::ACTIVE);
+}
+
+void FamilyUserSessionMetrics::UpdateUserEngagement(bool is_user_active) {
+  base::Time now = base::Time::Now();
+  if (is_user_active) {
     base::RecordAction(
         base::UserMetricsAction(kSessionEngagementStartActionName));
-    pref_service_->SetTime(prefs::kFamilyUserMetricsSessionEngagementStartTime,
-                           base::Time::Now());
+    active_session_start_ = now;
   } else {
-    base::Time start = pref_service_->GetTime(
-        prefs::kFamilyUserMetricsSessionEngagementStartTime);
-
     ReportUserEngagementHourToUma(
-        /*start=*/start,
-        /*end=*/base::Time::Now());
+        /*start=*/active_session_start_,
+        /*end=*/now);
+    if (now > active_session_start_) {
+      base::TimeDelta unreported_duration = pref_service_->GetTimeDelta(
+          prefs::kFamilyUserMetricsSessionEngagementDuration);
+      pref_service_->SetTimeDelta(
+          prefs::kFamilyUserMetricsSessionEngagementDuration,
+          unreported_duration + now - active_session_start_);
+    }
+
+    active_session_start_ = base::Time();
   }
 }
 
diff --git a/chrome/browser/chromeos/child_accounts/family_user_session_metrics.h b/chrome/browser/chromeos/child_accounts/family_user_session_metrics.h
index 2ac5361..158f1e2d 100644
--- a/chrome/browser/chromeos/child_accounts/family_user_session_metrics.h
+++ b/chrome/browser/chromeos/child_accounts/family_user_session_metrics.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_FAMILY_USER_SESSION_METRICS_H_
 #define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_FAMILY_USER_SESSION_METRICS_H_
 
+#include "base/time/time.h"
 #include "chrome/browser/chromeos/child_accounts/family_user_metrics_service.h"
 #include "chrome/browser/chromeos/child_accounts/usage_time_state_notifier.h"
 
@@ -21,6 +22,9 @@
 // day when the user is active split by weekday/weekend and total of
 // weekday/weekend. Recorded when UsageTimeNotifier::UsageTimeState changes to
 // INACTIVE. Covers the time between ACTIVE and INACTIVE.
+// - FamilyUser.SessionEngagement.Duration: Daily sum of user's active time in
+// milliseconds. Recorded at the beginning of the first active session on a
+// subsequent day.
 class FamilyUserSessionMetrics : public FamilyUserMetricsService::Observer,
                                  public UsageTimeStateNotifier::Observer {
  public:
@@ -28,6 +32,7 @@
   static const char kSessionEngagementWeekdayHistogramName[];
   static const char kSessionEngagementWeekendHistogramName[];
   static const char kSessionEngagementTotalHistogramName[];
+  static const char kSessionEngagementDurationHistogramName[];
 
   static void RegisterProfilePrefs(PrefRegistrySimple* registry);
 
@@ -36,21 +41,28 @@
   FamilyUserSessionMetrics& operator=(const FamilyUserSessionMetrics&) = delete;
   ~FamilyUserSessionMetrics() override;
 
+  // FamilyUserMetricsService::Observer:
+  void OnNewDay() override;
+
+  void SetActiveSessionStartForTesting(base::Time time);
+
  private:
   // UsageTimeStateNotifier::Observer:
   // When the user signs out, this function doesn't get called and
-  // |is_user_active_| doesn't change to false. Destructor will be called
-  // instead.
+  // UsageTimeStateNotifier::UsageTimeState doesn't change to inactive.
+  // Destructor will be called instead.
   void OnUsageTimeStateChange(
       UsageTimeStateNotifier::UsageTimeState state) override;
 
-  // Called when user engagement changes, save engagement data to pref
-  // or report to UMA.
-  void UpdateUserEngagement();
+  // Called when user engagement changes.Saves engagement hour and session
+  // duration data to prefs or report to UMA.
+  void UpdateUserEngagement(bool is_user_active);
 
   PrefService* const pref_service_;
 
-  bool is_user_active_ = false;
+  // The time when the user becomes active. It will be reset to base::Time()
+  // when the user becomes inactive.
+  base::Time active_session_start_;
 };
 }  // namespace chromeos
 
diff --git a/chrome/browser/chromeos/child_accounts/family_user_session_metrics_unittest.cc b/chrome/browser/chromeos/child_accounts/family_user_session_metrics_unittest.cc
index 675dae7..c275dc3d4 100644
--- a/chrome/browser/chromeos/child_accounts/family_user_session_metrics_unittest.cc
+++ b/chrome/browser/chromeos/child_accounts/family_user_session_metrics_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include "base/logging.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/metrics/user_action_tester.h"
 #include "base/test/task_environment.h"
@@ -23,6 +24,10 @@
 
 namespace {
 
+constexpr base::TimeDelta kTenMinutes = base::TimeDelta::FromMinutes(10);
+constexpr base::TimeDelta kOneHour = base::TimeDelta::FromHours(1);
+constexpr base::TimeDelta kOneDay = base::TimeDelta::FromDays(1);
+
 void SetScreenOff(bool is_screen_off) {
   power_manager::ScreenIdleState screen_idle_state;
   screen_idle_state.set_off(is_screen_off);
@@ -73,19 +78,22 @@
     task_environment_.FastForwardBy(forward_by);
   }
 
-  void SetSessionEngagementStartPref(base::Time start) {
-    pref_service_.SetTime(prefs::kFamilyUserMetricsSessionEngagementStartTime,
-                          start);
-  }
-
   void SetSessionState(session_manager::SessionState state) {
     session_manager_.SetSessionState(state);
   }
 
+  void SetActiveSessionStartTime(base::Time time) {
+    family_user_session_metrics_->SetActiveSessionStartForTesting(time);
+  }
+
   session_manager::SessionState GetSessionState() {
     return session_manager_.session_state();
   }
 
+  void OnNewDay() { family_user_session_metrics_->OnNewDay(); }
+
+  PrefService* pref_service() { return &pref_service_; }
+
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 
@@ -104,67 +112,150 @@
             user_action_tester.GetActionCount(
                 FamilyUserSessionMetrics::kSessionEngagementStartActionName));
 
-  SetupTaskRunnerWithTime("1 Jan 2020 10:00");
+  SetupTaskRunnerWithTime("1 Jan 2020 23:00");
 
   SetSessionState(session_manager::SessionState::ACTIVE);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
 
-  // Session locked at 10:10:00.
+  task_environment_.FastForwardBy(kTenMinutes);
+  // Session locked at 23:10:00.
   SetSessionState(session_manager::SessionState::LOCKED);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
 
-  // Session activated at 10:20:00.
+  task_environment_.FastForwardBy(kOneHour);
+  // Session activated at 00:10:00 on 2 Jan 2020.
   SetSessionState(session_manager::SessionState::ACTIVE);
 
-  task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
+  OnNewDay();
 
-  // Session locked at 10:20:00 on the second day.
+  task_environment_.FastForwardBy(kOneHour);
+  // Session locked at 01:10:00 on 2 Jan 2020.
   SetSessionState(session_manager::SessionState::LOCKED);
 
+  // Engagement start metric result:
   EXPECT_EQ(2,
             user_action_tester.GetActionCount(
                 FamilyUserSessionMetrics::kSessionEngagementStartActionName));
 
-  histogram_tester.ExpectBucketCount(
-      FamilyUserSessionMetrics::kSessionEngagementWeekdayHistogramName, 10, 3);
+  for (int i = 0; i <= 23; i++) {
+    if (i == 0 || i == 1 || i == 23) {
+      histogram_tester.ExpectBucketCount(
+          FamilyUserSessionMetrics::kSessionEngagementWeekdayHistogramName, i,
+          1);
+      histogram_tester.ExpectBucketCount(
+          FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, i, 1);
+    } else {
+      histogram_tester.ExpectBucketCount(
+          FamilyUserSessionMetrics::kSessionEngagementWeekdayHistogramName, i,
+          0);
+      histogram_tester.ExpectBucketCount(
+          FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, i, 0);
+    }
+  }
 
   histogram_tester.ExpectTotalCount(
-      FamilyUserSessionMetrics::kSessionEngagementWeekdayHistogramName, 26);
-  histogram_tester.ExpectTotalCount(
-      FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, 26);
+      FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, 3);
+
+  // Duration metric result:
+  histogram_tester.ExpectUniqueTimeSample(
+      FamilyUserSessionMetrics::kSessionEngagementDurationHistogramName,
+      kTenMinutes, 1);
+  EXPECT_EQ(kOneHour, pref_service()->GetTimeDelta(
+                          prefs::kFamilyUserMetricsSessionEngagementDuration));
 }
 
 TEST_F(FamilyUserSessionMetricsTest, ScreenStateChange) {
   base::HistogramTester histogram_tester;
   base::UserActionTester user_action_tester;
 
-  SetupTaskRunnerWithTime("3 Jan 2020 23:00");
+  SetupTaskRunnerWithTime("3 Jan 2020 23:10");
 
   SetSessionState(session_manager::SessionState::ACTIVE);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(60));
+  task_environment_.FastForwardBy(kOneHour);
 
-  // Test screen off at 0:00:00.
+  // Test screen off after midnight at 0:10:00 on 4 Jan 2020.
   SetScreenOff(true);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
 
-  // Test screen on at 0:10:00.
+  OnNewDay();
+
+  // Engagement start metric result:
+  EXPECT_EQ(1,
+            user_action_tester.GetActionCount(
+                FamilyUserSessionMetrics::kSessionEngagementStartActionName));
+
+  // Engagement Hour metric result:
+  histogram_tester.ExpectUniqueSample(
+      FamilyUserSessionMetrics::kSessionEngagementWeekdayHistogramName, 23, 1);
+  histogram_tester.ExpectUniqueSample(
+      FamilyUserSessionMetrics::kSessionEngagementWeekendHistogramName, 0, 1);
+  histogram_tester.ExpectTotalCount(
+      FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, 2);
+
+  // Duration metric result:
+  histogram_tester.ExpectUniqueTimeSample(
+      FamilyUserSessionMetrics::kSessionEngagementDurationHistogramName,
+      kOneHour, 1);
+  EXPECT_EQ(base::TimeDelta(),
+            pref_service()->GetTimeDelta(
+                prefs::kFamilyUserMetricsSessionEngagementDuration));
+
+  // Test screen on on 4 Jan 2020 0:10:00.
   SetScreenOff(false);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
 
-  // Session locked at 0:20:00.
-  SetSessionState(session_manager::SessionState::LOCKED);
+  task_environment_.FastForwardBy(base::TimeDelta::FromHours(25));
+  // Test screen off on 5 Jan 2020 1:10:00.
+  SetScreenOff(true);
 
+  OnNewDay();
+
+  // Engagement start metric result:
   EXPECT_EQ(2,
             user_action_tester.GetActionCount(
                 FamilyUserSessionMetrics::kSessionEngagementStartActionName));
 
+  // Engagement Hour metric result:
   histogram_tester.ExpectUniqueSample(
       FamilyUserSessionMetrics::kSessionEngagementWeekdayHistogramName, 23, 1);
-  histogram_tester.ExpectUniqueSample(
-      FamilyUserSessionMetrics::kSessionEngagementWeekendHistogramName, 0, 2);
+  for (int i = 0; i <= 23; i++) {
+    if (i == 0) {
+      histogram_tester.ExpectBucketCount(
+          FamilyUserSessionMetrics::kSessionEngagementWeekendHistogramName, i,
+          3);
+      histogram_tester.ExpectBucketCount(
+          FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, i, 3);
+    } else if (i == 1) {
+      histogram_tester.ExpectBucketCount(
+          FamilyUserSessionMetrics::kSessionEngagementWeekendHistogramName, i,
+          2);
+      histogram_tester.ExpectBucketCount(
+          FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, i, 2);
+    } else if (i == 23) {
+      histogram_tester.ExpectBucketCount(
+          FamilyUserSessionMetrics::kSessionEngagementWeekendHistogramName, i,
+          1);
+      histogram_tester.ExpectBucketCount(
+          FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, i, 2);
+
+    } else {
+      histogram_tester.ExpectBucketCount(
+          FamilyUserSessionMetrics::kSessionEngagementWeekendHistogramName, i,
+          1);
+    }
+  }
 
   histogram_tester.ExpectTotalCount(
-      FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, 3);
+      FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, 28);
+
+  // Duration metric result:
+  histogram_tester.ExpectTimeBucketCount(
+      FamilyUserSessionMetrics::kSessionEngagementDurationHistogramName,
+      kOneHour, 1);
+  histogram_tester.ExpectTimeBucketCount(
+      FamilyUserSessionMetrics::kSessionEngagementDurationHistogramName,
+      kOneDay, 1);
+  histogram_tester.ExpectTotalCount(
+      FamilyUserSessionMetrics::kSessionEngagementDurationHistogramName, 2);
+  EXPECT_EQ(base::TimeDelta(),
+            pref_service()->GetTimeDelta(
+                prefs::kFamilyUserMetricsSessionEngagementDuration));
 }
 
 TEST_F(FamilyUserSessionMetricsTest, SuspendStateChange) {
@@ -174,32 +265,41 @@
   SetupTaskRunnerWithTime("4 Jan 2020 6:00");
 
   SetSessionState(session_manager::SessionState::ACTIVE);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
+  task_environment_.FastForwardBy(kTenMinutes);
 
   // Test suspend at 6:10:00.
   SetSuspendImminent();
-  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
+  task_environment_.FastForwardBy(kTenMinutes);
 
   // Test cancel at 6:20:00.
   CancelSuspend();
 
-  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
+  task_environment_.FastForwardBy(kTenMinutes);
 
   // Test suspend at 6:30:00.
   SetSuspendImminent();
-  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
+  task_environment_.FastForwardBy(kTenMinutes);
 
   // Session locked at 6:40:00.
   SetSessionState(session_manager::SessionState::LOCKED);
 
+  // Engagement start metric result:
   EXPECT_EQ(2,
             user_action_tester.GetActionCount(
                 FamilyUserSessionMetrics::kSessionEngagementStartActionName));
 
+  // Engagement Hour metric result:
   histogram_tester.ExpectUniqueSample(
       FamilyUserSessionMetrics::kSessionEngagementWeekendHistogramName, 6, 2);
   histogram_tester.ExpectTotalCount(
       FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, 2);
+
+  // Duration metric result:
+  histogram_tester.ExpectTotalCount(
+      FamilyUserSessionMetrics::kSessionEngagementDurationHistogramName, 0);
+  EXPECT_EQ(base::TimeDelta::FromMinutes(20),
+            pref_service()->GetTimeDelta(
+                prefs::kFamilyUserMetricsSessionEngagementDuration));
 }
 
 TEST_F(FamilyUserSessionMetricsTest, ClockBackward) {
@@ -215,20 +315,29 @@
 
   // Set session start prefs to 11:00:00. Mock a state that start time > end
   // time.
-  SetSessionEngagementStartPref(mock_session_start);
+  SetActiveSessionStartTime(mock_session_start);
 
   // Session locked at 10:00:00.
   SetSessionState(session_manager::SessionState::LOCKED);
 
+  // Engagement start metric result:
   EXPECT_EQ(1,
             user_action_tester.GetActionCount(
                 FamilyUserSessionMetrics::kSessionEngagementStartActionName));
 
-  // Engagement hour data will be ignored if start time > end time.
+  // Engagement Hour metric result:
+  // Engagement hour and duration data will be ignored if start time > end time.
   histogram_tester.ExpectTotalCount(
       FamilyUserSessionMetrics::kSessionEngagementWeekdayHistogramName, 0);
   histogram_tester.ExpectTotalCount(
       FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, 0);
+
+  // Duration metric result:
+  histogram_tester.ExpectTotalCount(
+      FamilyUserSessionMetrics::kSessionEngagementDurationHistogramName, 0);
+  EXPECT_EQ(base::TimeDelta(),
+            pref_service()->GetTimeDelta(
+                prefs::kFamilyUserMetricsSessionEngagementDuration));
 }
 
 // Tests destroying FamilyUserSessionMetrics without invoking
@@ -242,33 +351,52 @@
 
   SetSessionState(session_manager::SessionState::ACTIVE);
 
-  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
+  task_environment_.FastForwardBy(kTenMinutes);
 
   DestructFamilyUserSessionMetrics();
   SetSessionState(session_manager::SessionState::UNKNOWN);
 
+  // Engagement start metric result:
   EXPECT_EQ(1,
             user_action_tester.GetActionCount(
                 FamilyUserSessionMetrics::kSessionEngagementStartActionName));
+
+  // Engagement Hour metric result:
   histogram_tester.ExpectUniqueSample(
       FamilyUserSessionMetrics::kSessionEngagementWeekdayHistogramName, 10, 1);
 
+  // Duration metric result:
+  histogram_tester.ExpectTotalCount(
+      prefs::kFamilyUserMetricsSessionEngagementDuration, 0);
+  EXPECT_EQ(kTenMinutes,
+            pref_service()->GetTimeDelta(
+                prefs::kFamilyUserMetricsSessionEngagementDuration));
+
   // Test restart.
   InitiateFamilyUserSessionMetrics();
   EXPECT_NE(session_manager::SessionState::ACTIVE, GetSessionState());
   SetSessionState(session_manager::SessionState::ACTIVE);
 
+  // Engagement start metric result:
   EXPECT_EQ(2,
             user_action_tester.GetActionCount(
                 FamilyUserSessionMetrics::kSessionEngagementStartActionName));
 
-  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
+  task_environment_.FastForwardBy(kTenMinutes);
   SetSessionState(session_manager::SessionState::LOCKED);
 
+  // Engagement Hour metric result:
   histogram_tester.ExpectUniqueSample(
       FamilyUserSessionMetrics::kSessionEngagementWeekdayHistogramName, 10, 2);
   histogram_tester.ExpectTotalCount(
       FamilyUserSessionMetrics::kSessionEngagementTotalHistogramName, 2);
+
+  // Duration metric result:
+  histogram_tester.ExpectTotalCount(
+      prefs::kFamilyUserMetricsSessionEngagementDuration, 0);
+  EXPECT_EQ(base::TimeDelta::FromMinutes(20),
+            pref_service()->GetTimeDelta(
+                prefs::kFamilyUserMetricsSessionEngagementDuration));
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/crostini/crostini_util.cc b/chrome/browser/chromeos/crostini/crostini_util.cc
index a3d68b0..08e4c6d 100644
--- a/chrome/browser/chromeos/crostini/crostini_util.cc
+++ b/chrome/browser/chromeos/crostini/crostini_util.cc
@@ -130,7 +130,7 @@
     const std::string& app_id,
     guest_os::GuestOsRegistryService::Registration registration,
     int64_t display_id,
-    const std::vector<std::string>& files,
+    const std::vector<std::string>& args,
     crostini::CrostiniSuccessCallback callback,
     bool success,
     const std::string& failure_reason) {
@@ -143,7 +143,7 @@
                                            registration.ContainerName());
   if (app_id == kCrostiniTerminalSystemAppId) {
     // Use first file as 'cwd'.
-    std::string cwd = !files.empty() ? files[0] : "";
+    std::string cwd = !args.empty() ? args[0] : "";
     if (!LaunchTerminal(profile, display_id, container_id, cwd)) {
       return OnLaunchFailed(app_id, std::move(callback),
                             "failed to launch terminal");
@@ -152,8 +152,7 @@
                                  crostini::CrostiniResult::SUCCESS, true, "");
   }
   crostini::CrostiniManager::GetForProfile(profile)->LaunchContainerApplication(
-      container_id, registration.DesktopFileId(), files,
-      registration.IsScaled(),
+      container_id, registration.DesktopFileId(), args, registration.IsScaled(),
       base::BindOnce(OnApplicationLaunched, app_id, std::move(callback),
                      crostini::CrostiniResult::UNKNOWN_ERROR));
 }
@@ -163,7 +162,7 @@
     const std::string& app_id,
     guest_os::GuestOsRegistryService::Registration registration,
     int64_t display_id,
-    const std::vector<storage::FileSystemURL>& files,
+    const std::vector<LaunchArg>& args,
     crostini::CrostiniSuccessCallback callback) {
   ChromeLauncherController* chrome_launcher_controller =
       ChromeLauncherController::instance();
@@ -178,8 +177,14 @@
   // Share any paths not in crostini.  The user will see the spinner while this
   // is happening.
   std::vector<base::FilePath> paths_to_share;
-  std::vector<std::string> files_to_launch;
-  for (const storage::FileSystemURL& url : files) {
+  std::vector<std::string> launch_args;
+  launch_args.reserve(args.size());
+  for (const auto& arg : args) {
+    if (absl::holds_alternative<std::string>(arg)) {
+      launch_args.push_back(absl::get<std::string>(arg));
+      continue;
+    }
+    const storage::FileSystemURL& url = absl::get<storage::FileSystemURL>(arg);
     base::FilePath path;
     if (!file_manager::util::ConvertFileSystemURLToPathInsideCrostini(
             profile, url, &path)) {
@@ -191,19 +196,19 @@
         file_manager::util::GetCrostiniMountPointName(profile)) {
       paths_to_share.push_back(url.path());
     }
-    files_to_launch.push_back(path.value());
+    launch_args.push_back(path.value());
   }
 
   if (paths_to_share.empty()) {
     OnSharePathForLaunchApplication(profile, app_id, std::move(registration),
-                                    display_id, std::move(files_to_launch),
+                                    display_id, std::move(launch_args),
                                     std::move(callback), true, "");
   } else {
     guest_os::GuestOsSharePath::GetForProfile(profile)->SharePaths(
         registration.VmName(), std::move(paths_to_share), /*persist=*/false,
         base::BindOnce(OnSharePathForLaunchApplication, profile, app_id,
                        std::move(registration), display_id,
-                       std::move(files_to_launch), std::move(callback)));
+                       std::move(launch_args), std::move(callback)));
   }
 }
 
@@ -297,7 +302,7 @@
     const std::string& app_id,
     guest_os::GuestOsRegistryService::Registration registration,
     int64_t display_id,
-    const std::vector<storage::FileSystemURL>& files,
+    const std::vector<LaunchArg>& args,
     CrostiniSuccessCallback callback) {
   auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile);
   auto* registry_service =
@@ -311,13 +316,16 @@
     // and share the path before launching terminal.
     bool requires_share = false;
     base::FilePath cwd;
-    if (!files.empty()) {
-      if (files[0].mount_filesystem_id() !=
+    if (!args.empty() &&
+        absl::holds_alternative<storage::FileSystemURL>(args[0])) {
+      const storage::FileSystemURL& url =
+          absl::get<storage::FileSystemURL>(args[0]);
+      if (url.mount_filesystem_id() !=
           file_manager::util::GetCrostiniMountPointName(profile)) {
         requires_share = true;
       } else {
-        file_manager::util::ConvertFileSystemURLToPathInsideCrostini(
-            profile, files[0], &cwd);
+        file_manager::util::ConvertFileSystemURLToPathInsideCrostini(profile,
+                                                                     url, &cwd);
       }
     }
 
@@ -343,8 +351,7 @@
       base::BindOnce(
           [](Profile* profile, const std::string& app_id,
              guest_os::GuestOsRegistryService::Registration registration,
-             int64_t display_id,
-             const std::vector<storage::FileSystemURL> files,
+             int64_t display_id, const std::vector<LaunchArg> args,
              crostini::CrostiniSuccessCallback callback,
              crostini::CrostiniResult result) {
             if (result != crostini::CrostiniResult::SUCCESS) {
@@ -361,9 +368,9 @@
             }
 
             LaunchApplication(profile, app_id, std::move(registration),
-                              display_id, files, std::move(callback));
+                              display_id, args, std::move(callback));
           },
-          profile, app_id, std::move(registration), display_id, files,
+          profile, app_id, std::move(registration), display_id, args,
           std::move(callback)));
 
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
@@ -374,7 +381,7 @@
 void LaunchCrostiniApp(Profile* profile,
                        const std::string& app_id,
                        int64_t display_id,
-                       const std::vector<storage::FileSystemURL>& files,
+                       const std::vector<LaunchArg>& args,
                        CrostiniSuccessCallback callback) {
   // Policies can change under us, and crostini may now be forbidden.
   if (!CrostiniFeatures::Get()->IsUIAllowed(profile)) {
@@ -404,7 +411,7 @@
     // Prompt for user-restart.
     return ShowCrostiniRecoveryView(
         profile, crostini::CrostiniUISurface::kAppList, app_id, display_id,
-        files, std::move(callback));
+        args, std::move(callback));
   }
 
   if (crostini_manager->GetCrostiniDialogStatus(DialogType::UPGRADER)) {
@@ -416,7 +423,7 @@
     return;
   }
   LaunchCrostiniAppImpl(profile, app_id, std::move(*registration), display_id,
-                        files, std::move(callback));
+                        args, std::move(callback));
 }
 
 std::string CryptohomeIdForProfile(Profile* profile) {
diff --git a/chrome/browser/chromeos/crostini/crostini_util.h b/chrome/browser/chromeos/crostini/crostini_util.h
index 5c5a57a..2214c70 100644
--- a/chrome/browser/chromeos/crostini/crostini_util.h
+++ b/chrome/browser/chromeos/crostini/crostini_util.h
@@ -16,6 +16,7 @@
 #include "base/values.h"
 #include "chrome/browser/chromeos/crostini/crostini_simple_types.h"
 #include "storage/browser/file_system/file_system_url.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
 
 namespace base {
 class FilePath;
@@ -89,13 +90,15 @@
 bool MaybeShowCrostiniDialogBeforeLaunch(Profile* profile,
                                          CrostiniResult result);
 
+using LaunchArg = absl::variant<storage::FileSystemURL, std::string>;
+
 // Launch a Crostini App with a given set of files, given as absolute paths in
 // the container. For apps which can only be launched with a single file,
 // launch multiple instances.
 void LaunchCrostiniApp(Profile* profile,
                        const std::string& app_id,
                        int64_t display_id,
-                       const std::vector<storage::FileSystemURL>& files = {},
+                       const std::vector<LaunchArg>& args = {},
                        CrostiniSuccessCallback callback = base::DoNothing());
 
 // Retrieves cryptohome_id from profile.
@@ -172,7 +175,7 @@
                               CrostiniUISurface ui_surface,
                               const std::string& app_id,
                               int64_t display_id,
-                              const std::vector<storage::FileSystemURL>& files,
+                              const std::vector<LaunchArg>& args,
                               CrostiniSuccessCallback callback);
 
 // Add a newly created LXD container to the kCrostiniContainers pref
diff --git a/chrome/browser/chromeos/extensions/default_app_order.cc b/chrome/browser/chromeos/extensions/default_app_order.cc
index 03c9eaa1..42efb4db 100644
--- a/chrome/browser/chromeos/extensions/default_app_order.cc
+++ b/chrome/browser/chromeos/extensions/default_app_order.cc
@@ -68,6 +68,7 @@
     extension_misc::kGooglePhotosAppId,
     arc::kGooglePhotosAppId,
     arc::kGoogleDuoAppId,
+    default_web_apps::kStadiaAppId,
     app_list::kDefaultPageBreak1,  // First default page break
     // TODO(crbug.com/976578): Remove after M78.
     extension_misc::kGoogleMapsAppId,
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index a22739e3..b4cb0cd 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -521,6 +521,7 @@
         TestCase("openQuickViewMtp"),
         TestCase("openQuickViewTabIndexImage"),
         TestCase("openQuickViewTabIndexText"),
+        TestCase("openQuickViewTabIndexHtml"),
         TestCase("openQuickViewTabIndexAudio"),
         TestCase("openQuickViewTabIndexVideo"),
         TestCase("openQuickViewTabIndexDeleteDialog"),
diff --git a/chrome/browser/chromeos/file_manager/guest_os_file_tasks.cc b/chrome/browser/chromeos/file_manager/guest_os_file_tasks.cc
index 2a04a96f..95d43f9 100644
--- a/chrome/browser/chromeos/file_manager/guest_os_file_tasks.cc
+++ b/chrome/browser/chromeos/file_manager/guest_os_file_tasks.cc
@@ -282,13 +282,19 @@
     return;
   }
 
+  using LaunchArg = absl::variant<storage::FileSystemURL, std::string>;
+  std::vector<LaunchArg> args;
+  args.reserve(file_system_urls.size());
+  for (const auto& url : file_system_urls) {
+    args.emplace_back(url);
+  }
   guest_os::GuestOsRegistryService::VmType vm_type = registration->VmType();
   switch (vm_type) {
     case guest_os::GuestOsRegistryService::VmType::
         ApplicationList_VmType_TERMINA:
       DCHECK(crostini::CrostiniFeatures::Get()->IsUIAllowed(profile));
       crostini::LaunchCrostiniApp(
-          profile, task.app_id, display::kInvalidDisplayId, file_system_urls,
+          profile, task.app_id, display::kInvalidDisplayId, args,
           base::BindOnce(
               [](FileTaskFinishedCallback done, bool success,
                  const std::string& failure_reason) {
@@ -310,7 +316,7 @@
         ApplicationList_VmType_PLUGIN_VM:
       DCHECK(plugin_vm::PluginVmFeatures::Get()->IsEnabled(profile));
       plugin_vm::LaunchPluginVmApp(
-          profile, task.app_id, file_system_urls,
+          profile, task.app_id, args,
           base::BindOnce(
               [](FileTaskFinishedCallback done,
                  plugin_vm::LaunchPluginVmAppResult result,
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_files.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_files.cc
index 4902eaf..8993df0 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_files.cc
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_files.cc
@@ -147,7 +147,7 @@
 
 void LaunchPluginVmApp(Profile* profile,
                        std::string app_id,
-                       const std::vector<storage::FileSystemURL>& files,
+                       const std::vector<LaunchArg>& args,
                        LaunchPluginVmAppCallback callback) {
   if (!plugin_vm::PluginVmFeatures::Get()->IsEnabled(profile)) {
     return std::move(callback).Run(LaunchPluginVmAppResult::FAILED,
@@ -164,31 +164,35 @@
   // Forward slashes are converted to backslash during path conversion.
   base::FilePath vm_mount("//ChromeOS");
 
-  std::vector<std::string> file_paths;
-  file_paths.reserve(files.size());
-  for (const auto& file : files) {
+  std::vector<std::string> launch_args;
+  launch_args.reserve(args.size());
+  for (const auto& arg : args) {
+    if (absl::holds_alternative<std::string>(arg)) {
+      launch_args.push_back(absl::get<std::string>(arg));
+      continue;
+    }
+    const storage::FileSystemURL& url = absl::get<storage::FileSystemURL>(arg);
     base::FilePath file_path;
     // Validate paths are already shared, and convert file paths.
-    if (!share_path->IsPathShared(kPluginVmName, file.path()) ||
+    if (!share_path->IsPathShared(kPluginVmName, url.path()) ||
         !file_manager::util::ConvertFileSystemURLToPathInsideVM(
-            profile, file, vm_mount, &file_path)) {
+            profile, url, vm_mount, &file_path)) {
       return std::move(callback).Run(
           file_manager::util::GetMyFilesFolderForProfile(profile).IsParent(
-              file.path())
+              url.path())
               ? LaunchPluginVmAppResult::FAILED_DIRECTORY_NOT_SHARED
               : LaunchPluginVmAppResult::FAILED_FILE_ON_EXTERNAL_DRIVE,
-          "Only files in shared dirs are supported. Got: " +
-              file.DebugString());
+          "Only files in shared dirs are supported. Got: " + url.DebugString());
     }
     // Convert slashes: '/' => '\'.
     std::string result;
     base::ReplaceChars(file_path.value(), "/", "\\", &result);
-    file_paths.push_back(std::move(result));
+    launch_args.push_back(std::move(result));
   }
 
   manager->LaunchPluginVm(
       base::BindOnce(&LaunchPluginVmAppImpl, profile, std::move(app_id),
-                     std::move(file_paths), std::move(callback)));
+                     std::move(launch_args), std::move(callback)));
 }
 
 }  // namespace plugin_vm
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_files.h b/chrome/browser/chromeos/plugin_vm/plugin_vm_files.h
index 493dc7e1..ed4e9ea 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_files.h
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_files.h
@@ -8,6 +8,7 @@
 #include "base/callback.h"
 #include "base/files/file_path.h"
 #include "storage/browser/file_system/file_system_url.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
 
 class Profile;
 
@@ -27,6 +28,8 @@
   FAILED_FILE_ON_EXTERNAL_DRIVE,
 };
 
+using LaunchArg = absl::variant<storage::FileSystemURL, std::string>;
+
 using LaunchPluginVmAppCallback =
     base::OnceCallback<void(LaunchPluginVmAppResult result,
                             const std::string& failure_reason)>;
@@ -35,7 +38,7 @@
 // the VM. Will start Plugin VM if it is not already running.
 void LaunchPluginVmApp(Profile* profile,
                        std::string app_id,
-                       const std::vector<storage::FileSystemURL>& files,
+                       const std::vector<LaunchArg>& files,
                        LaunchPluginVmAppCallback callback);
 
 }  // namespace plugin_vm
diff --git a/chrome/browser/chromeos/plugin_vm/plugin_vm_files_unittest.cc b/chrome/browser/chromeos/plugin_vm/plugin_vm_files_unittest.cc
index 3f38b3a..004896d 100644
--- a/chrome/browser/chromeos/plugin_vm/plugin_vm_files_unittest.cc
+++ b/chrome/browser/chromeos/plugin_vm/plugin_vm_files_unittest.cc
@@ -122,8 +122,7 @@
   LaunchPluginVmApp(&profile_,
                     crostini::CrostiniTestHelper::GenerateAppId(app_id, vm_name,
                                                                 container_name),
-                    std::vector<storage::FileSystemURL>{},
-                    app_launched_callback.Get());
+                    {}, app_launched_callback.Get());
   ASSERT_FALSE(launch_plugin_vm_callback.is_null());
 
   // Add app to app_list.
diff --git a/chrome/browser/chromeos/web_applications/DEPS b/chrome/browser/chromeos/web_applications/DEPS
new file mode 100644
index 0000000..d6dded2
--- /dev/null
+++ b/chrome/browser/chromeos/web_applications/DEPS
@@ -0,0 +1,5 @@
+specific_include_rules = {
+  "camera_app_integration_browsertest.cc": [
+    "+chrome/browser/ui/views",
+  ],
+}
diff --git a/chrome/browser/chromeos/web_applications/camera_app_integration_browsertest.cc b/chrome/browser/chromeos/web_applications/camera_app_integration_browsertest.cc
new file mode 100644
index 0000000..2ac2b2b2
--- /dev/null
+++ b/chrome/browser/chromeos/web_applications/camera_app_integration_browsertest.cc
@@ -0,0 +1,36 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/chromeos/web_applications/system_web_app_integration_test.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/web_applications/system_web_app_manager_browsertest.h"
+#include "chromeos/constants/chromeos_features.h"
+#include "content/public/test/browser_test.h"
+
+class CameraAppIntegrationTest : public SystemWebAppIntegrationTest {
+ public:
+  CameraAppIntegrationTest() {
+    scoped_feature_list_.InitWithFeatures(
+        {chromeos::features::kCameraSystemWebApp}, {});
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+// TODO(crbug.com/1129340): Remove this test after CCA supports responsive UI.
+// Test that the window of Camera App is not resizeable.
+IN_PROC_BROWSER_TEST_P(CameraAppIntegrationTest, WindowNotResizeable) {
+  WaitForTestSystemAppInstall();
+  Browser* browser;
+  LaunchApp(web_app::SystemAppType::CAMERA, &browser);
+  BrowserView* const browser_view =
+      BrowserView::GetBrowserViewForBrowser(browser);
+  EXPECT_FALSE(browser_view->CanResize());
+}
+
+INSTANTIATE_SYSTEM_WEB_APP_MANAGER_TEST_SUITE_MANIFEST_INSTALL_P(
+    CameraAppIntegrationTest);
diff --git a/chrome/browser/chromeos/web_applications/default_web_app_ids.h b/chrome/browser/chromeos/web_applications/default_web_app_ids.h
index dc8e5dd9..4d07623 100644
--- a/chrome/browser/chromeos/web_applications/default_web_app_ids.h
+++ b/chrome/browser/chromeos/web_applications/default_web_app_ids.h
@@ -58,6 +58,10 @@
 // web_app::GenerateAppIdFromURL(GURL("https://music.youtube.com/?source=pwa")).
 constexpr char kYoutubeMusicAppId[] = "cinhimbnkkaeohfgghhklpknlkffjgod";
 
+// Generated as
+// web_app::GenerateAppIdFromURL(GURL("https://stadia.google.com/?lfhs=2")).
+constexpr char kStadiaAppId[] = "pnkcfpnngfokcnnijgkllghjlhkailce";
+
 }  // namespace default_web_apps
 }  // namespace chromeos
 
diff --git a/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc b/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc
index e75353ce..7f5e236 100644
--- a/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc
+++ b/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc
@@ -27,6 +27,7 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/interactive_test_utils.h"
+#include "chrome/test/base/ui_test_utils.h"
 #include "chromeos/components/help_app_ui/url_constants.h"
 #include "chromeos/components/web_applications/test/sandboxed_web_ui_test_base.h"
 #include "chromeos/constants/chromeos_features.h"
@@ -56,6 +57,10 @@
 
 using HelpAppAllProfilesIntegrationTest = HelpAppIntegrationTest;
 
+content::WebContents* GetActiveWebContents() {
+  return chrome::FindLastActive()->tab_strip_model()->GetActiveWebContents();
+}
+
 // Waits for and expects that the correct url is opened.
 void WaitForAppToOpen(const GURL& expected_url) {
   // Start with a number of browsers (may include an incognito browser).
@@ -68,10 +73,7 @@
   // There should be another browser window for the newly opened app.
   EXPECT_EQ(num_browsers + 1, chrome::GetTotalBrowserCount());
   // Help app should have opened at the expected page.
-  EXPECT_EQ(expected_url, chrome::FindLastActive()
-                              ->tab_strip_model()
-                              ->GetActiveWebContents()
-                              ->GetVisibleURL());
+  EXPECT_EQ(expected_url, GetActiveWebContents()->GetVisibleURL());
 }
 
 // Test that the Help App installs and launches correctly. Runs some spot
@@ -163,10 +165,7 @@
 #else
   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(GURL(chrome::kChromeHelpViaKeyboardURL),
-            chrome::FindLastActive()
-                ->tab_strip_model()
-                ->GetActiveWebContents()
-                ->GetVisibleURL());
+            GetActiveWebContents()->GetVisibleURL());
 #endif
 }
 
@@ -194,13 +193,10 @@
   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
 
   // The opened window should be showing the url with attached WebUI.
-  content::WebContents* web_contents =
-      chrome::FindLastActive()->tab_strip_model()->GetActiveWebContents();
-
   // The inner frame should be the pathname for the release notes pathname.
   EXPECT_EQ("chrome-untrusted://help-app/updates",
             SandboxedWebUiAppTestBase::EvalJsInAppFrame(
-                web_contents, "window.location.href"));
+                GetActiveWebContents(), "window.location.href"));
 #else
   // Nothing should happen on non-branded builds.
   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
@@ -328,10 +324,7 @@
 
   // Settings should be active in a new window.
   EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
-  EXPECT_EQ(expected_url, chrome::FindLastActive()
-                              ->tab_strip_model()
-                              ->GetActiveWebContents()
-                              ->GetVisibleURL());
+  EXPECT_EQ(expected_url, GetActiveWebContents()->GetVisibleURL());
 }
 
 // Test that the Help App opens when Gesture help requested.
@@ -362,10 +355,7 @@
 #if defined(OS_CHROMEOS) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Default browser tab and Help app are open.
   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
-  EXPECT_EQ("chrome://help-app/", chrome::FindLastActive()
-                                      ->tab_strip_model()
-                                      ->GetActiveWebContents()
-                                      ->GetVisibleURL());
+  EXPECT_EQ("chrome://help-app/", GetActiveWebContents()->GetVisibleURL());
   // The HELP app is 18, see DefaultAppName in
   // src/chrome/browser/apps/app_service/app_service_metrics.cc
   histogram_tester.ExpectUniqueSample("Apps.DefaultAppLaunch.FromKeyboard", 18,
@@ -374,10 +364,7 @@
   // We just have the one browser. Navigates chrome.
   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(GURL(chrome::kChromeHelpViaKeyboardURL),
-            chrome::FindLastActive()
-                ->tab_strip_model()
-                ->GetActiveWebContents()
-                ->GetVisibleURL());
+            GetActiveWebContents()->GetVisibleURL());
   // The HELP app is 18, see DefaultAppName in
   // src/chrome/browser/apps/app_service/app_service_metrics.cc
   histogram_tester.ExpectUniqueSample("Apps.DefaultAppLaunch.FromKeyboard", 18,
@@ -385,6 +372,25 @@
 #endif
 }
 
+// Test that the Help App opens in a new window if try to navigate there in a
+// browser.
+IN_PROC_BROWSER_TEST_P(HelpAppIntegrationTest,
+                       HelpAppCapturesBrowserNavigation) {
+  WaitForTestSystemAppInstall();
+  content::TestNavigationObserver navigation_observer(
+      GURL("chrome://help-app"));
+  navigation_observer.StartWatchingNewWebContents();
+  ASSERT_EQ(1u, chrome::GetTotalBrowserCount());
+
+  // Try to navigate to the help app in the browser.
+  ui_test_utils::SendToOmniboxAndSubmit(browser(), "chrome://help-app");
+  navigation_observer.Wait();
+
+  // We now have two browsers, one for the chrome window, one for the Help app.
+  EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
+  EXPECT_EQ(GURL("chrome://help-app"), GetActiveWebContents()->GetVisibleURL());
+}
+
 INSTANTIATE_SYSTEM_WEB_APP_MANAGER_TEST_SUITE_MANIFEST_INSTALL_P(
     HelpAppIntegrationTest);
 
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc
index e0aafd5..4d8e04a 100644
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -309,8 +309,6 @@
   // Nearby Share.
   (*s_allowlist)[::prefs::kNearbySharingEnabledPrefName] =
       settings_api::PrefType::PREF_TYPE_BOOLEAN;
-  (*s_allowlist)[::prefs::kNearbySharingOnboardingCompletePrefName] =
-      settings_api::PrefType::PREF_TYPE_BOOLEAN;
   (*s_allowlist)[::prefs::kNearbySharingActiveProfilePrefName] =
       settings_api::PrefType::PREF_TYPE_BOOLEAN;
   (*s_allowlist)[::prefs::kNearbySharingDeviceNamePrefName] =
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 457e2d8..4446c323 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1483,6 +1483,11 @@
     "expiry_milestone": 87
   },
   {
+    "name": "enable-experimental-accessibility-magnifier-new-focus-following",
+    "owners": [ "josiahk", "//ui/accessibility/OWNERS" ],
+    "expiry_milestone": 88
+  },
+  {
     "name": "enable-experimental-accessibility-switch-access-text",
     "owners": [ "anastasi@google.com", "//ui/accessibility/OWNERS" ],
     "expiry_milestone": 90
@@ -1569,7 +1574,7 @@
   {
     "name": "enable-generic-sensor-extra-classes",
     "owners": [ "reillyg@chromium.org", "raphael.kubo.da.costa@intel.com" ],
-    "expiry_milestone": 86
+    "expiry_milestone": 90
   },
   {
     "name": "enable-google-srp-isolated-prerender-nsp",
@@ -3153,7 +3158,7 @@
   {
     "name": "new-shortcut-mapping",
     "owners": [ "oshima", "afakhry" ],
-    "expiry_milestone": 86
+    "expiry_milestone": 90
   },
   {
     "name": "new-tabstrip-animation",
@@ -3765,8 +3770,8 @@
   },
   {
     "name": "pull-to-refresh",
-    "owners": [ "afakhry" ],
-    "expiry_milestone": 83
+    "owners": [ "afakhry", "tclaiborne" ],
+    "expiry_milestone": 89
   },
   {
     "name": "query-tiles",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 06ef05b..64e9c3f 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -4033,6 +4033,12 @@
     "Enable experimental feature which allows setting cursor color in "
     "Accessibility settings.";
 
+const char kExperimentalAccessibilityMagnifierNewFocusFollowingName[] =
+    "Enable new focus following in Magnifier";
+const char kExperimentalAccessibilityMagnifierNewFocusFollowingDescription[] =
+    "Enable experimental feature which allows more comprehensive focus "
+    "following in Magnifier.";
+
 const char kFilesAppCopyImageName[] = "Enable Copy Images from Files App";
 const char kFilesAppCopyImageDescription[] =
     "Enables the Files App to copy images selected to the system clipboard";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 4769d119..92211ac 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -2335,6 +2335,10 @@
 extern const char kExperimentalAccessibilityCursorColorsName[];
 extern const char kExperimentalAccessibilityCursorColorsDescription[];
 
+extern const char kExperimentalAccessibilityMagnifierNewFocusFollowingName[];
+extern const char
+    kExperimentalAccessibilityMagnifierNewFocusFollowingDescription[];
+
 extern const char kFilesAppCopyImageName[];
 extern const char kFilesAppCopyImageDescription[];
 
diff --git a/chrome/browser/media/router/providers/cast/cast_activity.h b/chrome/browser/media/router/providers/cast/cast_activity.h
index 2278a2d8..a242826 100644
--- a/chrome/browser/media/router/providers/cast/cast_activity.h
+++ b/chrome/browser/media/router/providers/cast/cast_activity.h
@@ -81,9 +81,6 @@
   virtual void SendStopSessionMessageToClients(const std::string& hash_token);
 
   // Sends |message| to the client given by |client_id|.
-  //
-  // TODO(jrw): This method's functionality overlaps that of OnAppMessage().
-  // Can the methods be combined?
   virtual void SendMessageToClient(
       const std::string& client_id,
       blink::mojom::PresentationConnectionMessagePtr message);
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity.cc b/chrome/browser/media/router/providers/cast/mirroring_activity.cc
index 21f1bfbf..017ff960 100644
--- a/chrome/browser/media/router/providers/cast/mirroring_activity.cc
+++ b/chrome/browser/media/router/providers/cast/mirroring_activity.cc
@@ -280,12 +280,7 @@
   DVLOG(2) << "Relaying internal message from receiver: " << message.message;
   mirroring::mojom::CastMessagePtr ptr = mirroring::mojom::CastMessage::New();
   ptr->message_namespace = message.message_namespace;
-
-  // TODO(jrw): This line re-serializes a JSON string that was parsed by the
-  // caller of this method.  Yuck!  This is probably a necessary evil as long as
-  // the extension needs to communicate with the mirroring service.
   CHECK(base::JSONWriter::Write(message.message, &ptr->json_format_data));
-
   channel_to_service_->Send(std::move(ptr));
 }
 
@@ -308,8 +303,6 @@
 
   const std::string message_namespace = GetMirroringNamespace(*result.value);
 
-  // TODO(jrw): Can some of this logic be shared with
-  // AppActivity::SendAppMessageToReceiver?
   cast::channel::CastMessage cast_message = cast_channel::CreateCastMessage(
       message_namespace, std::move(*result.value),
       message_handler_->sender_id(), session->transport_id());
diff --git a/chrome/browser/nearby_sharing/common/nearby_share_prefs.cc b/chrome/browser/nearby_sharing/common/nearby_share_prefs.cc
index db1d842..b80ad4a 100644
--- a/chrome/browser/nearby_sharing/common/nearby_share_prefs.cc
+++ b/chrome/browser/nearby_sharing/common/nearby_share_prefs.cc
@@ -26,8 +26,6 @@
 const char kNearbySharingDeviceIdPrefName[] = "nearby_sharing.device_id";
 const char kNearbySharingDeviceNamePrefName[] = "nearby_sharing.device_name";
 const char kNearbySharingEnabledPrefName[] = "nearby_sharing.enabled";
-const char kNearbySharingOnboardingCompletePrefName[] =
-    "nearby_sharing.onboarding_complete";
 const char kNearbySharingFullNamePrefName[] = "nearby_sharing.full_name";
 const char kNearbySharingIconUrlPrefName[] = "nearby_sharing.icon_url";
 const char kNearbySharingOnboardingDismissedTimePrefName[] =
@@ -60,8 +58,6 @@
   // available.
   registry->RegisterBooleanPref(prefs::kNearbySharingEnabledPrefName,
                                 /*default_value=*/true);
-  registry->RegisterBooleanPref(prefs::kNearbySharingOnboardingCompletePrefName,
-                                /*default_value=*/false);
   registry->RegisterIntegerPref(
       prefs::kNearbySharingBackgroundVisibilityName,
       /*default_value=*/static_cast<int>(Visibility::kUnknown));
diff --git a/chrome/browser/nearby_sharing/common/nearby_share_prefs.h b/chrome/browser/nearby_sharing/common/nearby_share_prefs.h
index fd95db8..62c49427 100644
--- a/chrome/browser/nearby_sharing/common/nearby_share_prefs.h
+++ b/chrome/browser/nearby_sharing/common/nearby_share_prefs.h
@@ -17,7 +17,6 @@
 extern const char kNearbySharingDeviceIdPrefName[];
 extern const char kNearbySharingDeviceNamePrefName[];
 extern const char kNearbySharingEnabledPrefName[];
-extern const char kNearbySharingOnboardingCompletePrefName[];
 extern const char kNearbySharingFullNamePrefName[];
 extern const char kNearbySharingIconUrlPrefName[];
 extern const char kNearbySharingOnboardingDismissedTimePrefName[];
diff --git a/chrome/browser/nearby_sharing/nearby_share_settings.cc b/chrome/browser/nearby_sharing/nearby_share_settings.cc
index 935ce45..c2c227d 100644
--- a/chrome/browser/nearby_sharing/nearby_share_settings.cc
+++ b/chrome/browser/nearby_sharing/nearby_share_settings.cc
@@ -83,12 +83,6 @@
 
 void NearbyShareSettings::SetEnabled(bool enabled) {
   pref_service_->SetBoolean(prefs::kNearbySharingEnabledPrefName, enabled);
-  if (enabled) {
-    // We rely on the the UI to enforce that if the feature was enabled for the
-    // first time, that onboarding was run.
-    pref_service_->SetBoolean(prefs::kNearbySharingOnboardingCompletePrefName,
-                              true);
-  }
 }
 
 void NearbyShareSettings::GetDeviceName(
diff --git a/chrome/browser/resource_coordinator/tab_manager_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_unittest.cc
index b181c55..f45c5b1 100644
--- a/chrome/browser/resource_coordinator/tab_manager_unittest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_unittest.cc
@@ -17,13 +17,8 @@
 #include "base/metrics/field_trial.h"
 #include "base/notreached.h"
 #include "base/strings/string16.h"
-#include "base/task/current_thread.h"
 #include "base/test/mock_entropy_provider.h"
 #include "base/test/scoped_feature_list.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/test/test_mock_time_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/tick_clock.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
@@ -113,15 +108,10 @@
 class TabManagerTest : public ChromeRenderViewHostTestHarness {
  public:
   TabManagerTest()
-      : scoped_context_(
-            std::make_unique<base::TestMockTimeTaskRunner::ScopedContext>(
-                task_runner_)),
-        scoped_set_tick_clock_for_testing_(task_runner_->GetMockTickClock()),
-        previous_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
-    base::CurrentThread::Get()->SetTaskRunner(task_runner_);
-
+      : ChromeRenderViewHostTestHarness(
+            base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
     // Start with a non-zero time.
-    task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(42));
+    task_environment()->FastForwardBy(base::TimeDelta::FromSeconds(42));
   }
 
   std::unique_ptr<WebContents> CreateWebContents() {
@@ -131,9 +121,6 @@
     content::WebContentsTester::For(web_contents.get())
         ->NavigateAndCommit(GURL("https://www.example.com"));
 
-    base::RepeatingClosure run_loop_cb = base::BindRepeating(
-        &base::TestMockTimeTaskRunner::RunUntilIdle, task_runner_);
-
     return web_contents;
   }
 
@@ -171,8 +158,6 @@
 
   void TearDown() override {
     ResetState();
-    base::CurrentThread::Get()->SetTaskRunner(std::move(previous_task_runner_));
-    scoped_context_.reset();
     ChromeRenderViewHostTestHarness::TearDown();
   }
 
@@ -263,11 +248,6 @@
   }
 
   TabManager* tab_manager_ = nullptr;
-  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_ =
-      base::MakeRefCounted<base::TestMockTimeTaskRunner>();
-  std::unique_ptr<base::TestMockTimeTaskRunner::ScopedContext> scoped_context_;
-  ScopedSetTickClockForTesting scoped_set_tick_clock_for_testing_;
-  scoped_refptr<base::SingleThreadTaskRunner> previous_task_runner_;
   std::unique_ptr<BackgroundTabNavigationThrottle> throttle1_;
   std::unique_ptr<BackgroundTabNavigationThrottle> throttle2_;
   std::unique_ptr<BackgroundTabNavigationThrottle> throttle3_;
@@ -363,7 +343,7 @@
   tab_strip2->GetWebContentsAt(1)->WasHidden();
 
   // Advance time enough that the tabs are urgent discardable.
-  task_runner_->AdvanceMockTickClock(kBackgroundUrgentProtectionTime);
+  task_environment()->AdvanceClock(kBackgroundUrgentProtectionTime);
 
   for (int i = 0; i < 4; ++i)
     tab_manager_->DiscardTab(LifecycleUnitDiscardReason::URGENT);
@@ -517,7 +497,7 @@
 
   // Simulate timeout when loading the 1st tab. TabManager should start loading
   // the 2nd tab.
-  task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10));
+  task_environment()->FastForwardBy(base::TimeDelta::FromSeconds(10));
 
   EXPECT_TRUE(tab_manager_->IsTabLoadingForTest(contents1_.get()));
   EXPECT_TRUE(tab_manager_->IsTabLoadingForTest(contents2_.get()));
@@ -527,7 +507,7 @@
   EXPECT_TRUE(tab_manager_->IsNavigationDelayedForTest(nav_handle3_.get()));
 
   // Simulate timeout again. TabManager should start loading the 3rd tab.
-  task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10));
+  task_environment()->FastForwardBy(base::TimeDelta::FromSeconds(10));
 
   EXPECT_TRUE(tab_manager_->IsTabLoadingForTest(contents1_.get()));
   EXPECT_TRUE(tab_manager_->IsTabLoadingForTest(contents2_.get()));
@@ -560,7 +540,7 @@
             tab_manager_->background_tab_loading_mode_);
 
   // Simulate timeout when loading the 1st tab.
-  task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10));
+  task_environment()->FastForwardBy(base::TimeDelta::FromSeconds(10));
 
   // Tab 2 and 3 are still pending because of the paused loading mode.
   EXPECT_FALSE(tab_manager_->IsTabLoadingForTest(contents2_.get()));
@@ -924,7 +904,7 @@
 
   const int num_of_tabs_to_test = 20;
   for (int i = 0; i < num_of_tabs_to_test; ++i) {
-    task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(10));
+    task_environment()->FastForwardBy(base::TimeDelta::FromSeconds(10));
     tab_strip->AppendWebContents(CreateWebContents(), /*foreground=*/true);
   }
 
diff --git a/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json b/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json
index deeb9d9f..50507dbc 100644
--- a/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json
+++ b/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json
@@ -144,7 +144,7 @@
       "options_page": "hmm_options.html?code=xkb:us:intl:nld"
     },
     {
-      "name": "__MSG_keyboard_us_international_pc__",
+      "name": "__MSG_keyboard_netherlands_us_international_pc__",
       "type": "ime",
       "id": "xkb:us:intl_pc:nld",
       "indicator": "NLD",
@@ -248,7 +248,7 @@
       "options_page": "hmm_options.html?code=xkb:us:workman-intl:eng"
     },
     {
-      "name": "__MSG_keyboard_belgian__",
+      "name": "__MSG_keyboard_belgian_dutch__",
       "type": "ime",
       "id": "xkb:be::nld",
       "description": "",
@@ -289,7 +289,7 @@
       "options_page": "hmm_options.html?code=xkb:fr:bepo:fra"
     },
     {
-      "name": "__MSG_keyboard_belgian__",
+      "name": "__MSG_keyboard_belgian_french__",
       "type": "ime",
       "id": "xkb:be::fra",
       "description": "",
@@ -390,7 +390,7 @@
       "options_page": "hmm_options.html?code=xkb:de:neo:ger"
     },
     {
-      "name": "__MSG_keyboard_belgian__",
+      "name": "__MSG_keyboard_belgian_german__",
       "type": "ime",
       "id": "xkb:be::ger",
       "description": "",
@@ -471,7 +471,7 @@
       "options_page": "hmm_options.html?code=xkb:br::por"
     },
     {
-      "name": "__MSG_keyboard_us_international__",
+      "name": "__MSG_keyboard_portuguese_us_international__",
       "type": "ime",
       "id": "xkb:us:intl:por",
       "indicator": "INTL",
@@ -485,7 +485,7 @@
       "options_page": "hmm_options.html?code=xkb:us:intl:por"
     },
     {
-      "name": "__MSG_keyboard_us_international_pc__",
+      "name": "__MSG_keyboard_portuguese_us_international_pc__",
       "type": "ime",
       "id": "xkb:us:intl_pc:por",
       "indicator": "INTL",
diff --git a/chrome/browser/resources/settings/autofill_page/password_check.html b/chrome/browser/resources/settings/autofill_page/password_check.html
index 617b9ccb..24633c8 100644
--- a/chrome/browser/resources/settings/autofill_page/password_check.html
+++ b/chrome/browser/resources/settings/autofill_page/password_check.html
@@ -7,7 +7,7 @@
         width: 1.6em;
       }
 
-      iron-icon.has-leaks {
+      iron-icon.has-security-issues {
         --iron-icon-fill-color: var(--google-red-600);
         background: radial-gradient(circle 1.1em at 1.1em,
                                     #FCE8E6 100%,
@@ -21,7 +21,7 @@
       }
 
       @media (prefers-color-scheme: dark) {
-        iron-icon.has-leaks {
+        iron-icon.has-security-issues {
           --iron-icon-fill-color: var(--google-red-refresh-300);
           background: radial-gradient(circle 1.1em at 1.1em,
                                     var(--google-grey-900) 100%,
@@ -29,7 +29,7 @@
         }
       }
 
-      iron-icon.no-leaks {
+      iron-icon.no-security-issues {
         --iron-icon-fill-color: var(--google-blue-600);
         background-size: 16px 16px;
       }
@@ -38,7 +38,7 @@
         display: none;
       }
 
-      #leakCheckHeader {
+      #securityCheckHeader {
         border-bottom: var(--cr-separator-line);
       }
 
@@ -47,8 +47,9 @@
       }
 
     </style>
-    <!-- The banner is visible if no compromised password was found (yet). -->
-    <template is="dom-if" if="[[shouldShowBanner_(status, leakedPasswords)]]">
+    <!-- The banner is visible if no insecure password was found (yet). -->
+    <template is="dom-if"
+        if="[[shouldShowBanner_(status, leakedPasswords, weakPasswords)]]">
       <picture>
         <source srcset="[[bannerImageSrc_(1, status)]]"
                 media="(prefers-color-scheme: dark)">
@@ -57,11 +58,11 @@
     </template>
 
     <!-- The header showing progress or result of the check-->
-    <div class="cr-row first two-line" id="leakCheckHeader">
+    <div class="cr-row first two-line" id="securityCheckHeader">
       <!-- If the password check concluded, show only a status Icon. -->
       <template is="dom-if" if="[[!isCheckInProgress_(status)]]">
-        <iron-icon class$="[[getStatusIconClass_(status, leakedPasswords)]]"
-                   icon="[[getStatusIcon_(status, leakedPasswords)]]">
+        <iron-icon class$="[[getStatusIconClass_(status, leakedPasswords, weakPasswords)]]"
+                   icon="[[getStatusIcon_(status, leakedPasswords, weakPasswords)]]">
         </iron-icon>
       </template>
 
@@ -80,8 +81,8 @@
           </span>
         </div>
         <div class="secondary" id="subtitle"
-            hidden$="[[!showsPasswordsCount_(status, leakedPasswords)]]">
-          [[compromisedPasswordsCount]]
+            hidden$="[[!showsPasswordsCount_(status, leakedPasswords, weakPasswords)]]">
+          [[getPasswordsCount_(insecurePasswordsCount, compromisedPasswordsCount)]]
         </div>
       </div>
       <cr-button id="controlPasswordCheckButton"
diff --git a/chrome/browser/resources/settings/autofill_page/password_check.js b/chrome/browser/resources/settings/autofill_page/password_check.js
index 890fa9d..a77d186 100644
--- a/chrome/browser/resources/settings/autofill_page/password_check.js
+++ b/chrome/browser/resources/settings/autofill_page/password_check.js
@@ -275,6 +275,24 @@
   },
 
   /**
+   * Returns true if there are any weak credentials.
+   * @return {boolean}
+   * @private
+   */
+  hasWeakCredentials_() {
+    return !!this.weakPasswords.length;
+  },
+
+  /**
+   * Returns true if there are any insecure credentials.
+   * @return {boolean}
+   * @private
+   */
+  hasInsecureCredentials_() {
+    return !!this.leakedPasswords.length || !!this.weakPasswords.length;
+  },
+
+  /**
    * @param {!CustomEvent<{moreActionsButton: !HTMLElement}>} event
    * @private
    */
@@ -374,10 +392,10 @@
    * @private
    */
   getStatusIcon_() {
-    if (!this.hasLeaksOrErrors_()) {
+    if (!this.hasInsecureCredentialsOrErrors_()) {
       return 'settings:check-circle';
     }
-    if (this.hasLeakedCredentials_()) {
+    if (this.hasInsecureCredentials_()) {
       return 'cr:warning';
     }
     return 'cr:info';
@@ -389,11 +407,11 @@
    * @private
    */
   getStatusIconClass_() {
-    if (!this.hasLeaksOrErrors_()) {
-      return this.waitsForFirstCheck_() ? 'hidden' : 'no-leaks';
+    if (!this.hasInsecureCredentialsOrErrors_()) {
+      return this.waitsForFirstCheck_() ? 'hidden' : 'no-security-issues';
     }
-    if (this.hasLeakedCredentials_()) {
-      return 'has-leaks';
+    if (this.hasInsecureCredentials_()) {
+      return 'has-security-issues';
     }
     return '';
   },
@@ -537,21 +555,21 @@
    * @private
    */
   shouldShowBanner_() {
-    if (this.hasLeakedCredentials_()) {
+    if (this.hasInsecureCredentials_()) {
       return false;
     }
     return this.status.state === CheckState.CANCELED ||
-        !this.hasLeaksOrErrors_();
+        !this.hasInsecureCredentialsOrErrors_();
   },
 
   /**
-   * Returns true if there are leaked credentials or the status is unexpected
+   * Returns true if there are insecure credentials or the status is unexpected
    * for a regular password check.
    * @return {boolean}
    * @private
    */
-  hasLeaksOrErrors_() {
-    if (this.hasLeakedCredentials_()) {
+  hasInsecureCredentialsOrErrors_() {
+    if (this.hasInsecureCredentials_()) {
       return true;
     }
     switch (this.status.state) {
@@ -571,13 +589,13 @@
   },
 
   /**
-   * Returns true if there are leaked credentials or the status is unexpected
+   * Returns true if there are insecure credentials or the status is unexpected
    * for a regular password check.
    * @return {boolean}
    * @private
    */
   showsPasswordsCount_() {
-    if (this.hasLeakedCredentials_()) {
+    if (this.hasInsecureCredentials_()) {
       return true;
     }
     switch (this.status.state) {
@@ -598,6 +616,20 @@
   },
 
   /**
+   * Returns count of insecure credentials, if |passwordsWeaknessCheckEnabled|
+   * is true, otherwise, returns count of compromised credentials.
+   * @return {string}
+   * @private
+   */
+  getPasswordsCount_() {
+    if (this.passwordsWeaknessCheckEnabled) {
+      return this.insecurePasswordsCount;
+    } else {
+      return this.compromisedPasswordsCount;
+    }
+  },
+
+  /**
    * Returns true iff the leak check was performed at least once before.
    * @return {boolean}
    * @private
diff --git a/chrome/browser/resources/settings/autofill_page/password_check_behavior.js b/chrome/browser/resources/settings/autofill_page/password_check_behavior.js
index 7229dc4c..4a596bf 100644
--- a/chrome/browser/resources/settings/autofill_page/password_check_behavior.js
+++ b/chrome/browser/resources/settings/autofill_page/password_check_behavior.js
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import {assert} from 'chrome://resources/js/assert.m.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {PluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js';
 
 import {PasswordManagerImpl, PasswordManagerProxy} from './password_manager_proxy.js';
@@ -24,6 +25,11 @@
     compromisedPasswordsCount: String,
 
     /**
+     * The number of insecure passwords as a formatted string.
+     */
+    insecurePasswordsCount: String,
+
+    /**
      * An array of leaked passwords to display.
      * @type {!Array<!PasswordManagerProxy.InsecureCredential>}
      */
@@ -33,6 +39,15 @@
     },
 
     /**
+     * An array of weak passwords to display.
+     * @type {!Array<!PasswordManagerProxy.InsecureCredential>}
+     */
+    weakPasswords: {
+      type: Array,
+      value: () => [],
+    },
+
+    /**
      * The status indicates progress and affects banner, title and icon.
      * @type {!PasswordManagerProxy.PasswordCheckStatus}
      */
@@ -49,6 +64,17 @@
       type: Boolean,
       value: true,
     },
+
+    /**
+     * Returns true if passwords weakness check is enabled.
+     * @type {boolean}
+     */
+    passwordsWeaknessCheckEnabled: {
+      type: Boolean,
+      value() {
+        return loadTimeData.getBoolean('passwordsWeaknessCheck');
+      }
+    },
   },
 
   /**
@@ -57,6 +83,11 @@
   leakedCredentialsListener_: null,
 
   /**
+   * @private {?function(!PasswordManagerProxy.InsecureCredentials):void}
+   */
+  weakCredentialsListener_: null,
+
+  /**
    * @private {?function(!PasswordManagerProxy.PasswordCheckStatus):void}
    */
   statusChangedListener_: null,
@@ -78,6 +109,25 @@
           .then(count => {
             this.compromisedPasswordsCount = count;
           });
+      PluralStringProxyImpl.getInstance()
+          .getPluralString(
+              'insecurePasswords',
+              this.leakedPasswords.length + this.weakPasswords.length)
+          .then(count => {
+            this.insecurePasswordsCount = count;
+          });
+    };
+
+    this.weakCredentialsListener_ = weakCredentials => {
+      this.weakPasswords = weakCredentials;
+
+      PluralStringProxyImpl.getInstance()
+          .getPluralString(
+              'insecurePasswords',
+              this.leakedPasswords.length + this.weakPasswords.length)
+          .then(count => {
+            this.insecurePasswordsCount = count;
+          });
     };
 
     this.passwordManager = PasswordManagerImpl.getInstance();
@@ -85,11 +135,15 @@
         this.statusChangedListener_);
     this.passwordManager.getCompromisedCredentials().then(
         this.leakedCredentialsListener_);
+    this.passwordManager.getWeakCredentials().then(
+        this.weakCredentialsListener_);
 
     this.passwordManager.addPasswordCheckStatusListener(
         this.statusChangedListener_);
     this.passwordManager.addCompromisedCredentialsListener(
         this.leakedCredentialsListener_);
+    this.passwordManager.addWeakCredentialsListener(
+        this.weakCredentialsListener_);
   },
 
   /** @override */
@@ -100,6 +154,9 @@
     this.passwordManager.removeCompromisedCredentialsListener(
         assert(this.leakedCredentialsListener_));
     this.leakedCredentialsListener_ = null;
+    this.passwordManager.removeWeakCredentialsListener(
+        assert(this.weakCredentialsListener_));
+    this.weakCredentialsListener_ = null;
   },
 
   /**
diff --git a/chrome/browser/resources/settings/autofill_page/password_manager_proxy.js b/chrome/browser/resources/settings/autofill_page/password_manager_proxy.js
index 7abe200..5349d1a 100644
--- a/chrome/browser/resources/settings/autofill_page/password_manager_proxy.js
+++ b/chrome/browser/resources/settings/autofill_page/password_manager_proxy.js
@@ -204,6 +204,12 @@
   getCompromisedCredentials() {}
 
   /**
+   * Requests the latest information about weak credentials.
+   * @return {!Promise<(PasswordManagerProxy.InsecureCredentials)>}
+   */
+  getWeakCredentials() {}
+
+  /**
    * Returns the current status of the check via |callback|.
    * @return {!Promise<(PasswordManagerProxy.PasswordCheckStatus)>}
    */
@@ -230,6 +236,20 @@
   removeCompromisedCredentialsListener(listener) {}
 
   /**
+   * Add an observer to the weak passwords change.
+   * @param {function(!PasswordManagerProxy.InsecureCredentials):void}
+   *      listener
+   */
+  addWeakCredentialsListener(listener) {}
+
+  /**
+   * Remove an observer to the weak passwords change.
+   * @param {function(!PasswordManagerProxy.InsecureCredentials):void}
+   *     listener
+   */
+  removeWeakCredentialsListener(listener) {}
+
+  /**
    * Add an observer to the passwords check status change.
    * @param {function(!PasswordManagerProxy.PasswordCheckStatus):void} listener
    */
@@ -529,6 +549,13 @@
   }
 
   /** @override */
+  getWeakCredentials() {
+    return new Promise(resolve => {
+      chrome.passwordsPrivate.getWeakCredentials(resolve);
+    });
+  }
+
+  /** @override */
   removeInsecureCredential(insecureCredential) {
     chrome.passwordsPrivate.removeInsecureCredential(insecureCredential);
   }
@@ -546,6 +573,16 @@
   }
 
   /** @override */
+  addWeakCredentialsListener(listener) {
+    chrome.passwordsPrivate.onWeakCredentialsChanged.addListener(listener);
+  }
+
+  /** @override */
+  removeWeakCredentialsListener(listener) {
+    chrome.passwordsPrivate.onWeakCredentialsChanged.removeListener(listener);
+  }
+
+  /** @override */
   addPasswordCheckStatusListener(listener) {
     chrome.passwordsPrivate.onPasswordCheckStatusChanged.addListener(listener);
   }
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
index 6675a10..2bb6a511 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//chrome/browser/resources/settings/chromeos/os_settings.gni")
 import("//third_party/closure_compiler/compile_js.gni")
+import("//ui/webui/resources/tools/js_modulizer.gni")
 
 js_type_check("closure_compile") {
   deps = [
@@ -180,12 +181,12 @@
 js_type_check("closure_compile_module") {
   is_polymer3 = true
   deps = [
-#    ":cellular_setup_dialog.m"
-#    ":internet_config.m",
+    ":cellular_setup_dialog.m",
+    ":internet_config.m",
 #    ":internet_detail_page.m",
     ":internet_known_networks_page.m",
 #    ":internet_page.m",
-#    ":internet_page_browser_proxy.m",
+    ":internet_page_browser_proxy.m",
     ":internet_shared_css.m",
 #    ":internet_subpage.m",
 #    ":network_proxy_section.m",
@@ -195,10 +196,30 @@
   ]
 }
 
+js_library("cellular_setup_dialog.m") {
+  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.m.js" ]
+  deps = [
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+    "//ui/webui/resources/cr_components/chromeos/cellular_setup:cellular_setup.m",
+    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m",
+    "//ui/webui/resources/js:i18n_behavior.m",
+  ]
+  extra_deps = [ ":cellular_setup_dialog_module" ]
+}
+
 js_library("internet_config.m") {
   sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/internet_config.m.js" ]
   deps = [
-    # TODO: Fill those in.
+    ":internet_shared_css.m",
+    "//chrome/browser/resources/settings/chromeos:metrics_recorder.m",
+    "//chrome/browser/resources/settings:router.m",
+    "//third_party/polymer/v3_0/components-chromium/iron-flex-layout:iron-flex-layout",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+    "//ui/webui/resources/cr_components/chromeos/network:network_config.m",
+    "//ui/webui/resources/cr_elements/cr_button:cr_button.m",
+    "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m",
+    "//ui/webui/resources/js:i18n_behavior.m",
+    "//ui/webui/resources/js:util.m",
   ]
   extra_deps = [ ":internet_config_module" ]
 }
@@ -293,14 +314,6 @@
   extra_deps = [ ":tether_connection_dialog_module" ]
 }
 
-js_library("cellular_setup_dialog.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.m.js" ]
-  deps = [
-    # TODO: Fill those in.
-  ]
-  extra_deps = [ ":cellular_setup_dialog_module" ]
-}
-
 import("//tools/polymer/polymer.gni")
 
 group("polymer3_elements") {
@@ -324,6 +337,8 @@
   js_file = "internet_config.js"
   html_file = "internet_config.html"
   html_type = "dom-module"
+  auto_imports = os_settings_auto_imports
+  namespace_rewrites = os_settings_namespace_rewrites
 }
 
 polymer_modulizer("internet_detail_page") {
@@ -388,8 +403,7 @@
   html_type = "dom-module"
 }
 
-import("//ui/webui/resources/tools/js_modulizer.gni")
-
 js_modulizer("modulize") {
   input_files = [ "internet_page_browser_proxy.js" ]
+  namespace_rewrites = os_settings_namespace_rewrites
 }
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.html b/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.html
index f9e5c272..950461a 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.html
@@ -3,6 +3,8 @@
 <link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.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="../../settings_shared_css.html">
 
 <dom-module id="os-settings-cellular-setup-dialog">
   <template>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_config.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_config.html
index a051e5b..92b37dfc 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_config.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_config.html
@@ -4,6 +4,7 @@
 <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://resources/html/util.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
 <link rel="import" href="../metrics_recorder.html">
 <link rel="import" href="internet_shared_css.html">
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js
index 1cb79e3..516668bc 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js
@@ -121,7 +121,7 @@
 
   /** @private */
   onSaveTap_() {
-    this.$.networkConfig.save();
+    /** @type {!NetworkConfigElement} */ (this.$.networkConfig).save();
     settings.recordSettingChange();
   },
 
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.js
index 70f9670..430dd1e 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.js
@@ -2,10 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// clang-format off
+// #import {addSingletonGetter, addWebUIListener} from 'chrome://resources/js/cr.m.js';
+// clang-format on
+
 /** @fileoverview A helper object used for Internet page. */
 cr.define('settings', function() {
   /** @interface */
-  class InternetPageBrowserProxy {
+  /* #export */ class InternetPageBrowserProxy {
     /**
      * Shows the Cellular activation UI.
      * @param {string} guid
@@ -47,7 +51,7 @@
   /**
    * @implements {settings.InternetPageBrowserProxy}
    */
-  class InternetPageBrowserProxyImpl {
+  /* #export */ class InternetPageBrowserProxyImpl {
     /** @override */
     showCellularSetupUI(guid) {
       chrome.send('showCellularSetupUI', [guid]);
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js
index 05d89d3c..f8b59e6 100644
--- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js
+++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js
@@ -467,25 +467,12 @@
    * @private
    */
   nearbyShareClick_(event) {
-    const nearbyEnabled = this.getPref('nearby_sharing.enabled').value;
-    const onboardingComplete =
-        this.getPref('nearby_sharing.onboarding_complete').value;
-    let params = undefined;
-    if (!nearbyEnabled) {
-      if (onboardingComplete) {
-
-        // If we have already run onboarding at least once, we don't need to do
-        // it again, just enabled the feature in place.
-        this.setPrefValue('nearby_sharing.enabled', true);
-        return;
-      }
-      // Otherwise we need to go into the subpage and trigger the onboarding
-      // dialog.
-      params = new URLSearchParams();
-      params.set('onboarding', '');
+    if (!this.getPref('nearby_sharing.enabled').value) {
+      this.setPrefValue('nearby_sharing.enabled', true);
+    } else {
+      // Navigate to Nearby Share subpage.
+      settings.Router.getInstance().navigateTo(settings.routes.NEARBY_SHARE);
     }
-    settings.Router.getInstance().navigateTo(
-        settings.routes.NEARBY_SHARE, params);
   },
 
   /** @private */
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js
index 32651cc5..1b36a69 100644
--- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_receive_dialog.js
@@ -103,6 +103,11 @@
     if (this.observerReceiver_) {
       this.observerReceiver_.$.close();
     }
+
+    if (this.receiveManager_) {
+      /** @type {nearbyShare.mojom.ReceiveManagerRemote} */
+      (this.receiveManager_).$.close();
+    }
   },
 
   /**
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni
index 76367c5..4bdddc4 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.gni
+++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -32,6 +32,7 @@
                                    "settings.FingerprintResultType|FingerprintResultType",
                                    "settings.FingerprintScan|FingerprintScan",
                                    "settings.FingerprintSetupStep|FingerprintSetupStep",
+                                   "settings.InternetPageBrowserProxy|InternetPageBrowserProxy",
                                    "settings.input_method_util.generateOptions|generateOptions",
                                    "settings.input_method_util.getFirstPartyInputMethodEngineId|getFirstPartyInputMethodEngineId",
                                    "settings.input_method_util.getOptionLabelName|getOptionLabelName",
@@ -130,6 +131,7 @@
                              "ui/webui/resources/html/cr.html|sendWithPromise,removeWebUIListener,addWebUIListener,WebUIListener",
                              "ui/webui/resources/html/icon.html|getImage",
                              "ui/webui/resources/html/polymer.html|afterNextRender,Polymer,html,flush",
+                             "ui/webui/resources/html/util.html|HTMLEscape",
                              "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_browser_proxy.html|CupsPrintersBrowserProxy,CupsPrintersBrowserProxyImpl,CupsPrinterInfo,PrinterSetupResult,CupsPrintersList,PrinterPpdMakeModel,ManufacturersInfo,ModelsInfo,PrintServerResult,PrinterMakeModel",
                              "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_list_behavior.html|CupsPrintersEntryListBehavior",
                              "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_manager.html|CupsPrintersEntryManager",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js
index db885698..1eb19a8 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.js
+++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -7,6 +7,8 @@
 import './bluetooth_page/bluetooth_page.m.js';
 import './bluetooth_page/bluetooth_subpage.m.js';
 import './bluetooth_page/bluetooth_device_list_item.m.js';
+import './internet_page/cellular_setup_dialog.m.js';
+import './internet_page/internet_config.m.js';
 import './internet_page/internet_known_networks_page.m.js';
 import './nearby_share_page/nearby_share_receive_dialog.m.js';
 import './nearby_share_page/nearby_share_subpage.m.js';
@@ -37,6 +39,7 @@
 export {AmbientModeBrowserProxyImpl} from './ambient_mode_page/ambient_mode_browser_proxy.m.js';
 export {AmbientModeTemperatureUnit, AmbientModeTopicSource} from './ambient_mode_page/constants.m.js';
 export {bluetoothApis} from './bluetooth_page/bluetooth_page.m.js';
+export {InternetPageBrowserProxy, InternetPageBrowserProxyImpl} from './internet_page/internet_page_browser_proxy.m.js';
 export {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_page/multidevice_browser_proxy.m.js';
 export {MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, MultiDeviceSettingsMode, SmartLockSignInEnabledState} from './multidevice_page/multidevice_constants.m.js';
 export {Account, NearbyAccountManagerBrowserProxy, NearbyAccountManagerBrowserProxyImpl} from './nearby_share_page/nearby_account_manager_browser_proxy.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp b/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp
index e5709e59..e795836 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp
+++ b/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp
@@ -30,11 +30,26 @@
            use_base_dir="false"
            compress="false"
            type="BINDATA" />
+  <include name="IDR_OS_SETTINGS_CELLULAR_SETUP_DIALOG_M_JS"
+           file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.m.js"
+           use_base_dir="false"
+           compress="false"
+           type="BINDATA" />
+  <include name="IDR_OS_SETTINGS_INTERNET_CONFIG_M_JS"
+           file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/internet_page/internet_config.m.js"
+           use_base_dir="false"
+           compress="false"
+           type="BINDATA" />
   <include name="IDR_OS_SETTINGS_INTERNET_KNOWN_NETWORKS_PAGE_M_JS"
            file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.m.js"
            use_base_dir="false"
            compress="false"
            type="BINDATA" />
+  <include name="IDR_OS_SETTINGS_INTERNET_PAGE_BROWSER_PROXY_M_JS"
+           file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.m.js"
+           use_base_dir="false"
+           compress="false"
+           type="BINDATA" />
   <include name="IDR_OS_SETTINGS_INTERNET_SHARED_CSS_M_JS"
            file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/internet_page/internet_shared_css.m.js"
            use_base_dir="false"
diff --git a/chrome/browser/resources/settings/icons.html b/chrome/browser/resources/settings/icons.html
index 02cf6bdd..6e5af49 100644
--- a/chrome/browser/resources/settings/icons.html
+++ b/chrome/browser/resources/settings/icons.html
@@ -94,6 +94,7 @@
       <g id="palette"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"></path></g>
       <g id="payment-handler"><path d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z"></path></g>
       <g id="insecure-content"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"></path></g>
+      <g id="person"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path></g>
       <g id="photo"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"></path></g>
       <g id="power-settings-new"><path d="M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z"></path></g>
       <g id="protocol-handler"><path d="M21.72 11.33l-6.644-7.035a.97.97 0 0 0-1.38-.01l-1.67 1.72-1.617-1.712a.97.97 0 0 0-1.38-.01l-6.737 6.935c-.187.191-.29.447-.292.719-.002.272.099.529.28.722l6.644 7.034a.949.949 0 0 0 1.38.011l1.671-1.718 1.615 1.71a.949.949 0 0 0 1.381.01l6.74-6.935a1.054 1.054 0 0 0 .01-1.44zM6.947 12.464l3.657 3.785-.974.98-5.273-5.456 5.349-5.378.929.962-3.677 3.7a.998.998 0 0 0-.292.702 1 1 0 0 0 .28.705zm7.35 4.768l-.931-.963 3.68-3.7a1.012 1.012 0 0 0 .007-1.407l-3.656-3.784.974-.98 5.273 5.456-5.348 5.378z"></path></g>
@@ -113,7 +114,6 @@
       <g id="web"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-5 14H4v-4h11v4zm0-5H4V9h11v4zm5 5h-4V9h4v9z"></path></g>
 </if>
       <g id="window-placement"><path d="M21 1H8c-1.1 0-2 .9-2 2v6H3c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h13c1.1 0 2-.9 2-2v-6h3c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm-5 20H3v-8h13v8zm5-8h-3v-2c0-1.1-.9-2-2-2H8V5h13v8z"></path></g>
-      <g id="idle-detection"><path d="M21,10.12h-6.78l2.74-2.82c-2.73-2.7-7.15-2.8-9.88-0.1c-2.73,2.71-2.73,7.08,0,9.79s7.15,2.71,9.88,0 C18.32,15.65,19,14.08,19,12.1h2c0,1.98-0.88,4.55-2.64,6.29c-3.51,3.48-9.21,3.48-12.72,0c-3.5-3.47-3.53-9.11-0.02-12.58 s9.14-3.47,12.65,0L21,3V10.12z M12.5,8v4.25l3.5,2.08l-0.72,1.21L11,13V8H12.5z"></path></g>
       <g id="zoom-in"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></g>
       <g id="font-access"><path d="M0 0h24v24H0V0z" fill="none"></path><path d="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 18H4V4h16v16zM10.69 6h2.6l4.51 12h-2.5l-1.01-2.87H9.7L8.7 18H6.2l4.49-12zm2.87 7.06l-1.06-3.02-.43-1.44h-.13l-.44 1.44-1.07 3.02h3.13z"></path></g>
     </defs>
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html
index 85817fb..161b726b 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.html
+++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -232,7 +232,7 @@
       </site-details-permission>
       <site-details-permission
           category="[[ContentSettingsTypes.IDLE_DETECTION]]"
-          icon="settings:idle-detection"
+          icon="settings:person"
           label="$i18n{siteSettingsIdleDetection}">
       </site-details-permission>
       <template is="dom-if" if="[[enableExperimentalWebPlatformFeatures_]]">
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
index a25b71c..cbbddf3 100644
--- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
+++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
@@ -143,7 +143,7 @@
       route: routes.SITE_SETTINGS_IDLE_DETECTION,
       id: Id.IDLE_DETECTION,
       label: 'siteSettingsIdleDetection',
-      icon: 'settings:idle-detection',
+      icon: 'settings:person',
       enabledLabel: 'siteSettingsIdleDetectionAsk',
       disabledLabel: 'siteSettingsIdleDetectionBlock',
     },
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index e4023dc..4cea73d 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1735,6 +1735,8 @@
       "app_list/search/files/drive_zero_state_provider.h",
       "app_list/search/files/file_result.cc",
       "app_list/search/files/file_result.h",
+      "app_list/search/files/item_suggest_cache.cc",
+      "app_list/search/files/item_suggest_cache.h",
       "app_list/search/launcher_search/launcher_search_icon_image_loader.cc",
       "app_list/search/launcher_search/launcher_search_icon_image_loader.h",
       "app_list/search/launcher_search/launcher_search_icon_image_loader_impl.cc",
diff --git a/chrome/browser/ui/app_list/search/files/drive_zero_state_provider.cc b/chrome/browser/ui/app_list/search/files/drive_zero_state_provider.cc
index a85dd90..dd68e98 100644
--- a/chrome/browser/ui/app_list/search/files/drive_zero_state_provider.cc
+++ b/chrome/browser/ui/app_list/search/files/drive_zero_state_provider.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/ui/app_list/search/drive_quick_access_chip_result.h"
 #include "chrome/browser/ui/app_list/search/drive_quick_access_result.h"
 #include "chrome/browser/ui/app_list/search/search_controller.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -27,10 +28,12 @@
 
 DriveZeroStateProvider::DriveZeroStateProvider(
     Profile* profile,
-    SearchController* search_controller)
+    SearchController* search_controller,
+    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
     : profile_(profile),
       drive_service_(
           drive::DriveIntegrationServiceFactory::GetForProfile(profile)),
+      item_suggest_cache_(profile, std::move(url_loader_factory)),
       suggested_files_enabled_(app_list_features::IsSuggestedFilesEnabled()) {
   DCHECK(profile_);
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -66,7 +69,7 @@
 
 void DriveZeroStateProvider::AppListShown() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
+  item_suggest_cache_.UpdateCache();
   // TODO(crbug.com/1034842): Query ItemSuggest, consider rate-limiting.
 }
 
diff --git a/chrome/browser/ui/app_list/search/files/drive_zero_state_provider.h b/chrome/browser/ui/app_list/search/files/drive_zero_state_provider.h
index 56437a9..8260cd5 100644
--- a/chrome/browser/ui/app_list/search/files/drive_zero_state_provider.h
+++ b/chrome/browser/ui/app_list/search/files/drive_zero_state_provider.h
@@ -15,6 +15,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
 #include "chrome/browser/chromeos/file_manager/file_tasks_notifier.h"
+#include "chrome/browser/ui/app_list/search/files/item_suggest_cache.h"
 #include "chrome/browser/ui/app_list/search/search_provider.h"
 
 class Profile;
@@ -26,7 +27,10 @@
 class DriveZeroStateProvider : public SearchProvider,
                                public drive::DriveIntegrationServiceObserver {
  public:
-  DriveZeroStateProvider(Profile* profile, SearchController* search_controller);
+  DriveZeroStateProvider(
+      Profile* profile,
+      SearchController* search_controller,
+      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
   ~DriveZeroStateProvider() override;
 
   DriveZeroStateProvider(const DriveZeroStateProvider&) = delete;
@@ -44,6 +48,8 @@
   Profile* const profile_;
   drive::DriveIntegrationService* const drive_service_;
 
+  ItemSuggestCache item_suggest_cache_;
+
   // Whether the suggested files experiment is enabled.
   const bool suggested_files_enabled_;
 
@@ -54,13 +60,7 @@
   SEQUENCE_CHECKER(sequence_checker_);
 
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
-  // Factory for general use.
-  base::WeakPtrFactory<DriveZeroStateProvider> weak_ptr_factory_{this};
-  // Factory only for weak pointers for ItemSuggest API calls. Using two
-  // factories allows in-flight API calls to be cancelled independently of other
-  // tasks by invalidating only this factory's weak pointers.
-  base::WeakPtrFactory<DriveZeroStateProvider> item_suggest_weak_ptr_factory_{
-      this};
+  base::WeakPtrFactory<DriveZeroStateProvider> weak_factory_{this};
 };
 
 }  // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/files/item_suggest_cache.cc b/chrome/browser/ui/app_list/search/files/item_suggest_cache.cc
new file mode 100644
index 0000000..0ed559d
--- /dev/null
+++ b/chrome/browser/ui/app_list/search/files/item_suggest_cache.cc
@@ -0,0 +1,251 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/app_list/search/files/item_suggest_cache.h"
+
+#include "base/bind.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/strcat.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
+#include "components/google/core/common/google_util.h"
+#include "components/signin/public/identity_manager/access_token_info.h"
+#include "components/signin/public/identity_manager/account_info.h"
+#include "components/signin/public/identity_manager/consent_level.h"
+#include "components/signin/public/identity_manager/identity_manager.h"
+#include "components/signin/public/identity_manager/scope_set.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_status_code.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+#include "url/gurl.h"
+
+namespace app_list {
+namespace {
+
+// Maximum accepted size of an ItemSuggest response. 10 KB.
+constexpr int kMaxResponseSize = 10 * 1024;
+
+// TODO(crbug.com/1034842): Investigate:
+//  - enterprise policies that should limit this traffic.
+//  - settings that should disable drive results.
+constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+    net::DefineNetworkTrafficAnnotation("launcher_item_suggest", R"(
+      semantics {
+        sender: "Launcher suggested drive files"
+        description:
+          "The Chrome OS launcher requests suggestions for Drive files from "
+          "the Drive ItemSuggest API. These are displayed in the launcher."
+        trigger:
+          "Once on login after Drive FS is mounted. Afterwards, whenever the "
+          "Chrome OS launcher is opened."
+        data:
+          "OAuth2 access token."
+        destination: GOOGLE_OWNED_SERVICE
+      }
+      policy {
+        cookies_allowed: NO
+        setting:
+          "This cannot be disabled."
+      })");
+
+// The scope required for an access token in order to query ItemSuggest.
+constexpr char kDriveScope[] = "https://www.googleapis.com/auth/drive.readonly";
+
+// TODO(crbug.com/1034842): Check this is correct. Also consider:
+//  - controlling at least the scenario type by experiment param.
+//  - whether we can filter the response to certain fields
+constexpr char kRequestBody[] = R"({
+      'max_suggestions': 5,
+      'client_info': {
+          'platform_type': 'CHROMEOS',
+          'application_type': 'GOOGLE_DRIVE',
+          'scenario_type': 'QUICK_ACCESS'
+      }})";
+
+//----------------
+// Error utilities
+//----------------
+
+// Possible error states of the item suggest cache. These values persist to
+// logs. Entries should not be renumbered and numeric values should never be
+// reused.
+enum class Error {
+  kDisabled = 1,
+  kInvalidServerUrl = 2,
+  kNoIdentityManager = 3,
+  kGoogleAuthError = 4,
+  kNetError = 5,
+  k3xxError = 6,
+  k4xxError = 7,
+  k5xxError = 8,
+  kEmptyResponse = 9,
+  kNoResultsInResponse = 10,
+  kJsonParseFailure = 11,
+  kJsonConversionFailure = 12,
+  kMaxValue = kJsonConversionFailure,
+};
+
+void LogError(Error error) {
+  // TODO(crbug.com/1034842): Implement.
+}
+
+void LogResponseSize(const int size) {
+  // TODO(crbug.com/1034842): Implement.
+}
+
+}  // namespace
+
+// static
+const base::Feature ItemSuggestCache::kExperiment{
+    "LauncherItemSuggest", base::FEATURE_DISABLED_BY_DEFAULT};
+constexpr base::FeatureParam<bool> ItemSuggestCache::kEnabled;
+constexpr base::FeatureParam<std::string> ItemSuggestCache::kServerUrl;
+
+ItemSuggestCache::ItemSuggestCache(
+    Profile* profile,
+    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
+    : enabled_(kEnabled.Get()),
+      server_url_(kServerUrl.Get()),
+      profile_(profile),
+      url_loader_factory_(std::move(url_loader_factory)) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+ItemSuggestCache::~ItemSuggestCache() = default;
+
+void ItemSuggestCache::UpdateCache() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // TODO(crbug.com/1034842): Add rate-limiting for cache updates.
+
+  // Make no requests and exit in four cases:
+  // - item suggest has been disabled via experiment
+  // - the server url is not https
+  // - the server url is not trusted by Google
+  // - another request is in-flight (url_loader_ is non-null)
+  if (url_loader_) {
+    return;
+  } else if (!enabled_) {
+    LogError(Error::kDisabled);
+    return;
+  } else if (!server_url_.SchemeIs(url::kHttpsScheme) ||
+             !google_util::IsGoogleAssociatedDomainUrl(server_url_)) {
+    LogError(Error::kInvalidServerUrl);
+    return;
+  }
+
+  signin::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfile(profile_);
+  if (!identity_manager) {
+    LogError(Error::kNoIdentityManager);
+    return;
+  }
+
+  signin::ScopeSet scopes({kDriveScope});
+
+  // Fetch an OAuth2 access token.
+  token_fetcher_ = std::make_unique<signin::PrimaryAccountAccessTokenFetcher>(
+      "launcher_item_suggest", identity_manager, scopes,
+      base::BindOnce(&ItemSuggestCache::OnTokenReceived,
+                     weak_factory_.GetWeakPtr()),
+      signin::PrimaryAccountAccessTokenFetcher::Mode::kImmediate,
+      signin::ConsentLevel::kSync);
+}
+
+void ItemSuggestCache::OnTokenReceived(GoogleServiceAuthError error,
+                                       signin::AccessTokenInfo token_info) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  token_fetcher_.reset();
+
+  if (error.state() != GoogleServiceAuthError::NONE) {
+    LogError(Error::kGoogleAuthError);
+    return;
+  }
+
+  // Make a new request.
+  url_loader_ = MakeRequestLoader(token_info.token);
+  url_loader_->SetRetryOptions(0, network::SimpleURLLoader::RETRY_NEVER);
+  url_loader_->AttachStringForUpload(kRequestBody, "application/json");
+
+  // Perform the request.
+  url_loader_->DownloadToString(
+      url_loader_factory_.get(),
+      base::BindOnce(&ItemSuggestCache::OnSuggestionsReceived,
+                     weak_factory_.GetWeakPtr()),
+      kMaxResponseSize);
+}
+
+void ItemSuggestCache::OnSuggestionsReceived(
+    const std::unique_ptr<std::string> json_response) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  const int net_error = url_loader_->NetError();
+  if (net_error != net::OK) {
+    if (!url_loader_->ResponseInfo() || !url_loader_->ResponseInfo()->headers) {
+      LogError(Error::kNetError);
+    } else {
+      const int status = url_loader_->ResponseInfo()->headers->response_code();
+      if (status >= 500) {
+        LogError(Error::k5xxError);
+      } else if (status >= 400) {
+        LogError(Error::k4xxError);
+      } else if (status >= 300) {
+        LogError(Error::k3xxError);
+      }
+    }
+
+    return;
+  } else if (!json_response || json_response->empty()) {
+    LogError(Error::kEmptyResponse);
+    return;
+  }
+
+  LogResponseSize(json_response->size());
+
+  // Parse the JSON response from ItemSuggest.
+  data_decoder::DataDecoder::ParseJsonIsolated(
+      *json_response, base::BindOnce(&ItemSuggestCache::OnJsonParsed,
+                                     weak_factory_.GetWeakPtr()));
+}
+
+void ItemSuggestCache::OnJsonParsed(
+    data_decoder::DataDecoder::ValueOrError result) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (!result.value) {
+    LogError(Error::kJsonParseFailure);
+    return;
+  }
+
+  // TODO(crbug.com/1034842): Convert json to result objects.
+}
+
+std::unique_ptr<network::SimpleURLLoader> ItemSuggestCache::MakeRequestLoader(
+    const std::string& token) {
+  auto resource_request = std::make_unique<network::ResourceRequest>();
+
+  resource_request->method = "POST";
+  resource_request->url = server_url_;
+  // Do not allow cookies.
+  resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
+  // Ignore the cache because we always want fresh results.
+  resource_request->load_flags =
+      net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE;
+
+  DCHECK(resource_request->url.is_valid());
+
+  resource_request->headers.SetHeader(net::HttpRequestHeaders::kContentType,
+                                      "application/json");
+  resource_request->headers.SetHeader(net::HttpRequestHeaders::kAuthorization,
+                                      "Bearer " + token);
+
+  return network::SimpleURLLoader::Create(std::move(resource_request),
+                                          kTrafficAnnotation);
+}
+
+}  // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/files/item_suggest_cache.h b/chrome/browser/ui/app_list/search/files/item_suggest_cache.h
new file mode 100644
index 0000000..56f48703
--- /dev/null
+++ b/chrome/browser/ui/app_list/search/files/item_suggest_cache.h
@@ -0,0 +1,73 @@
+// 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 CHROME_BROWSER_UI_APP_LIST_SEARCH_FILES_ITEM_SUGGEST_CACHE_H_
+#define CHROME_BROWSER_UI_APP_LIST_SEARCH_FILES_ITEM_SUGGEST_CACHE_H_
+
+#include "base/feature_list.h"
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/sequence_checker.h"
+#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h"
+#include "google_apis/gaia/google_service_auth_error.h"
+#include "services/data_decoder/public/cpp/data_decoder.h"
+
+class Profile;
+
+namespace network {
+class SharedURLLoaderFactory;
+class SimpleURLLoader;
+}  // namespace network
+
+namespace app_list {
+
+class ItemSuggestCache {
+ public:
+  ItemSuggestCache(
+      Profile* profile,
+      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+  ~ItemSuggestCache();
+
+  ItemSuggestCache(const ItemSuggestCache&) = delete;
+  ItemSuggestCache& operator=(const ItemSuggestCache&) = delete;
+
+  void UpdateCache();
+
+  // Whether or not to override configuration of the cache with an experiment.
+  static const base::Feature kExperiment;
+
+ private:
+  // Whether or not the ItemSuggestCache is enabled.
+  static constexpr base::FeatureParam<bool> kEnabled{&kExperiment, "enabled",
+                                                     true};
+  // The url of the service that fetches descriptions given image pixels.
+  static constexpr base::FeatureParam<std::string> kServerUrl{
+      &kExperiment, "server_url",
+      "https://appsitemsuggest-pa.googleapis.com/v1/items"};
+
+  void OnTokenReceived(GoogleServiceAuthError error,
+                       signin::AccessTokenInfo token_info);
+  void OnSuggestionsReceived(const std::unique_ptr<std::string> json_response);
+  void OnJsonParsed(data_decoder::DataDecoder::ValueOrError result);
+  std::unique_ptr<network::SimpleURLLoader> MakeRequestLoader(
+      const std::string& token);
+
+  const bool enabled_;
+  const GURL server_url_;
+
+  Profile* profile_;
+  std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher> token_fetcher_;
+  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
+  std::unique_ptr<network::SimpleURLLoader> url_loader_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  base::WeakPtrFactory<ItemSuggestCache> weak_factory_{this};
+};
+
+}  // namespace app_list
+
+#endif  // CHROME_BROWSER_UI_APP_LIST_SEARCH_FILES_ITEM_SUGGEST_CACHE_H_
diff --git a/chrome/browser/ui/app_list/search/search_controller_factory.cc b/chrome/browser/ui/app_list/search/search_controller_factory.cc
index 635c4e5..dffb677 100644
--- a/chrome/browser/ui/app_list/search/search_controller_factory.cc
+++ b/chrome/browser/ui/app_list/search/search_controller_factory.cc
@@ -25,6 +25,7 @@
 #include "chrome/browser/ui/app_list/search/assistant_search_provider.h"
 #include "chrome/browser/ui/app_list/search/assistant_text_search_provider.h"
 #include "chrome/browser/ui/app_list/search/drive_quick_access_provider.h"
+#include "chrome/browser/ui/app_list/search/files/drive_zero_state_provider.h"
 #include "chrome/browser/ui/app_list/search/launcher_search/launcher_search_provider.h"
 #include "chrome/browser/ui/app_list/search/mixer.h"
 #include "chrome/browser/ui/app_list/search/omnibox_provider.h"
@@ -36,6 +37,8 @@
 #include "chrome/common/chrome_switches.h"
 #include "chromeos/services/assistant/public/cpp/features.h"
 #include "components/arc/arc_util.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
 
 namespace app_list {
 
@@ -83,6 +86,13 @@
 // TODO(wutao): Need UX spec.
 constexpr size_t kMaxSettingsShortcutResults = 6;
 
+// A flag to easily replace the old Drive zero-state provider with the new one
+// during development.
+//
+// TODO(crbug.com/1034842): Once implementation is finished, remove this flag
+// and always use the new provider.
+constexpr bool kUseNewDriveProvider = false;
+
 }  // namespace
 
 std::unique_ptr<SearchController> CreateSearchController(
@@ -195,9 +205,19 @@
                             std::make_unique<ZeroStateFileProvider>(profile));
     size_t drive_quick_access_group_id =
         controller->AddGroup(kMaxDriveQuickAccessResults);
-    controller->AddProvider(
-        drive_quick_access_group_id,
-        std::make_unique<DriveQuickAccessProvider>(profile, controller.get()));
+
+    if (kUseNewDriveProvider) {
+      controller->AddProvider(
+          drive_quick_access_group_id,
+          std::make_unique<DriveZeroStateProvider>(
+              profile, controller.get(),
+              content::BrowserContext::GetDefaultStoragePartition(profile)
+                  ->GetURLLoaderFactoryForBrowserProcess()));
+    } else {
+      controller->AddProvider(drive_quick_access_group_id,
+                              std::make_unique<DriveQuickAccessProvider>(
+                                  profile, controller.get()));
+    }
   }
 
   if (app_list_features::IsLauncherSettingsSearchEnabled()) {
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 2d26d60..604d77d0 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -359,7 +359,10 @@
 Browser::CreateParams::CreateParams(Type type,
                                     Profile* profile,
                                     bool user_gesture)
-    : type(type), profile(profile), user_gesture(user_gesture) {}
+    : type(type),
+      profile(profile),
+      user_gesture(user_gesture),
+      can_resize(!chrome::IsRunningInForcedAppMode()) {}
 
 Browser::CreateParams::CreateParams(const CreateParams& other) = default;
 
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index 7c4a3b8..f53d9be0 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -234,6 +234,9 @@
     // programmatically created.
     bool user_gesture;
 
+    // True if the app is resizeable.
+    bool can_resize;
+
     // Whether this browser was created specifically for dragged tab(s).
     bool in_tab_dragging = false;
 
@@ -645,6 +648,9 @@
            type_ == TYPE_APP_POPUP;
   }
 
+  // True if the browser is resizeable.
+  bool can_resize() const { return create_params_.can_resize; }
+
   // True when the mouse cursor is locked.
   bool IsMouseLocked() const;
 
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc
index 8b6223a..0ac6f37 100644
--- a/chrome/browser/ui/extensions/application_launch.cc
+++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -403,7 +403,8 @@
 
 Browser* CreateApplicationWindow(Profile* profile,
                                  const apps::AppLaunchParams& params,
-                                 const GURL& url) {
+                                 const GURL& url,
+                                 bool can_resize) {
   const Extension* const extension = GetExtension(profile, params);
 
   std::string app_name;
@@ -442,6 +443,7 @@
 
   browser_params.initial_show_state =
       DetermineWindowShowState(profile, params.container, extension);
+  browser_params.can_resize = can_resize;
 
   return new Browser(browser_params);
 }
diff --git a/chrome/browser/ui/extensions/application_launch.h b/chrome/browser/ui/extensions/application_launch.h
index 52b87f5..7fe45f04 100644
--- a/chrome/browser/ui/extensions/application_launch.h
+++ b/chrome/browser/ui/extensions/application_launch.h
@@ -38,7 +38,8 @@
 // delaying activating and showing it.
 Browser* CreateApplicationWindow(Profile* profile,
                                  const apps::AppLaunchParams& params,
-                                 const GURL& url);
+                                 const GURL& url,
+                                 bool can_resize = true);
 
 // Navigate application window to application url, but do not show it yet.
 content::WebContents* NavigateApplicationWindow(
diff --git a/chrome/browser/ui/views/crostini/crostini_recovery_view.cc b/chrome/browser/ui/views/crostini/crostini_recovery_view.cc
index 1475a10..7eede3f 100644
--- a/chrome/browser/ui/views/crostini/crostini_recovery_view.cc
+++ b/chrome/browser/ui/views/crostini/crostini_recovery_view.cc
@@ -36,27 +36,26 @@
     crostini::CrostiniUISurface ui_surface,
     const std::string& app_id,
     int64_t display_id,
-    const std::vector<storage::FileSystemURL>& files,
+    const std::vector<crostini::LaunchArg>& args,
     crostini::CrostiniSuccessCallback callback) {
-  CrostiniRecoveryView::Show(profile, app_id, display_id, files,
+  CrostiniRecoveryView::Show(profile, app_id, display_id, args,
                              std::move(callback));
   base::UmaHistogramEnumeration(kCrostiniRecoverySourceHistogram, ui_surface,
                                 crostini::CrostiniUISurface::kCount);
 }
 
-void CrostiniRecoveryView::Show(
-    Profile* profile,
-    const std::string& app_id,
-    int64_t display_id,
-    const std::vector<storage::FileSystemURL>& files,
-    crostini::CrostiniSuccessCallback callback) {
+void CrostiniRecoveryView::Show(Profile* profile,
+                                const std::string& app_id,
+                                int64_t display_id,
+                                const std::vector<crostini::LaunchArg>& args,
+                                crostini::CrostiniSuccessCallback callback) {
   DCHECK(crostini::CrostiniFeatures::Get()->IsUIAllowed(profile));
   // Any new apps launched during recovery are immediately cancelled.
   if (g_crostini_recovery_view) {
     std::move(callback).Run(false, "recovery in progress");
   } else {
     g_crostini_recovery_view = new CrostiniRecoveryView(
-        profile, app_id, display_id, files, std::move(callback));
+        profile, app_id, display_id, args, std::move(callback));
     CreateDialogWidget(g_crostini_recovery_view, nullptr, nullptr);
   }
   // Always call Show to bring the dialog to the front of the screen.
@@ -88,7 +87,7 @@
   }
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE, base::BindOnce(&crostini::LaunchCrostiniApp, profile_, app_id_,
-                                display_id_, files_, std::move(callback_)));
+                                display_id_, args_, std::move(callback_)));
   GetWidget()->CloseWithReason(
       views::Widget::ClosedReason::kAcceptButtonClicked);
 }
@@ -110,12 +109,12 @@
     Profile* profile,
     const std::string& app_id,
     int64_t display_id,
-    const std::vector<storage::FileSystemURL>& files,
+    const std::vector<crostini::LaunchArg>& args,
     crostini::CrostiniSuccessCallback callback)
     : profile_(profile),
       app_id_(app_id),
       display_id_(display_id),
-      files_(files),
+      args_(args),
       callback_(std::move(callback)),
       weak_ptr_factory_(this) {
   SetButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
diff --git a/chrome/browser/ui/views/crostini/crostini_recovery_view.h b/chrome/browser/ui/views/crostini/crostini_recovery_view.h
index ef45537..4b4daf4 100644
--- a/chrome/browser/ui/views/crostini/crostini_recovery_view.h
+++ b/chrome/browser/ui/views/crostini/crostini_recovery_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_VIEWS_CROSTINI_CROSTINI_RECOVERY_VIEW_H_
 
 #include "chrome/browser/chromeos/crostini/crostini_simple_types.h"
+#include "chrome/browser/chromeos/crostini/crostini_util.h"
 #include "storage/browser/file_system/file_system_url.h"
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
 
@@ -22,7 +23,7 @@
   static void Show(Profile* profile,
                    const std::string& app_id,
                    int64_t display_id,
-                   const std::vector<storage::FileSystemURL>& files,
+                   const std::vector<crostini::LaunchArg>& args,
                    crostini::CrostiniSuccessCallback callback);
 
   // views::DialogDelegateView:
@@ -36,7 +37,7 @@
   CrostiniRecoveryView(Profile* profile,
                        const std::string& app_id,
                        int64_t display_id,
-                       const std::vector<storage::FileSystemURL>& files,
+                       const std::vector<crostini::LaunchArg>& args,
                        crostini::CrostiniSuccessCallback callback);
   ~CrostiniRecoveryView() override;
 
@@ -45,7 +46,7 @@
   Profile* profile_;  // Not owned.
   std::string app_id_;
   int64_t display_id_;
-  const std::vector<storage::FileSystemURL> files_;
+  const std::vector<crostini::LaunchArg> args_;
   crostini::CrostiniSuccessCallback callback_;
 
   base::WeakPtrFactory<CrostiniRecoveryView> weak_ptr_factory_;
diff --git a/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc b/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc
index 90d9949..7103b05 100644
--- a/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc
+++ b/chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc
@@ -186,10 +186,17 @@
         flags);
   }
 
-  // Paint central pixel in red.
+  // Paint central pixel.
   gfx::RectF pixel((size().width() - kPixelSize) / 2,
                    (size().height() - kPixelSize) / 2, kPixelSize, kPixelSize);
-  flags.setColor(SK_ColorRED);
+  flags.setAntiAlias(true);
+  flags.setColor(SK_ColorWHITE);
+  flags.setStrokeWidth(2);
+  pixel.Inset(-0.5f, -0.5f);
+  view_canvas->DrawRect(pixel, flags);
+  flags.setColor(SK_ColorBLACK);
+  flags.setStrokeWidth(1);
+  pixel.Inset(0.5f, 0.5f);
   view_canvas->DrawRect(pixel, flags);
 
   // Paint outline.
diff --git a/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm b/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm
index fa6e562..e3c30d6b 100644
--- a/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm
+++ b/chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm
@@ -94,11 +94,11 @@
 }
 
 gfx::Size EyeDropperView::GetSize() const {
-  return gfx::Size(70, 70);
+  return gfx::Size(90, 90);
 }
 
 float EyeDropperView::GetDiameter() const {
-  return 70;
+  return 90;
 }
 
 std::unique_ptr<content::EyeDropper> ShowEyeDropper(
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 071a287..750861e 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -516,6 +516,7 @@
     : views::ClientView(nullptr, nullptr), browser_(std::move(browser)) {
   SetShowIcon(::ShouldShowWindowIcon(browser_.get()));
   SetHasWindowSizeControls(!chrome::IsRunningInForcedAppMode());
+  SetCanResize(browser_->can_resize());
 
   browser_->tab_strip_model()->AddObserver(this);
   immersive_mode_controller_ = chrome::CreateImmersiveModeController();
@@ -698,19 +699,6 @@
   return IsTabStripVisible() ? tabstrip_->GetPreferredSize().height() : 0;
 }
 
-TabSearchButton* BrowserView::GetTabSearchButton() {
-  if (!base::FeatureList::IsEnabled(features::kTabSearch))
-    return nullptr;
-
-  // If kTabSearchFixedEntrypoint is enabled then the tab search button is
-  // defined in the tab strip region view.
-  // TODO(tluk): Consolidate these once Tab Scrolling successfully moves the
-  // tab controls container to the tab strip region view.
-  return base::FeatureList::IsEnabled(features::kTabSearchFixedEntrypoint)
-             ? tab_strip_region_view_->tab_search_button()
-             : tabstrip_->tab_search_button();
-}
-
 bool BrowserView::IsTabStripVisible() const {
   // Return false if this window does not normally display a tabstrip.
   if (!browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP))
@@ -2623,8 +2611,13 @@
     return;
 #endif  // BUILDFLAG(ENABLE_WEBUI_TAB_STRIP)
 
-  DCHECK(GetTabSearchButton());
-  if (GetTabSearchButton()->ShowTabSearchBubble()) {
+  // If kTabSearchFixedEntrypoint is enabled then the tab search button is
+  // defined in the tab strip region view.
+  // TODO(tluk): Consolidate these once Tab Scrolling successfully moves the
+  // tab controls container to the tab strip region view.
+  if ((base::FeatureList::IsEnabled(features::kTabSearchFixedEntrypoint) &&
+       tab_strip_region_view_->tab_search_button()->ShowTabSearchBubble()) ||
+      tabstrip_->tab_search_button()->ShowTabSearchBubble()) {
     // Only log the open action if it resulted in creating a new instance of the
     // Tab Search bubble.
     base::UmaHistogramEnumeration("Tabs.TabSearch.OpenAction",
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index eb4256ff..58daed3 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -66,7 +66,6 @@
 class InfoBarContainerView;
 class LocationBarView;
 class StatusBubbleViews;
-class TabSearchButton;
 class TabStrip;
 class TabStripRegionView;
 class ToolbarButtonProvider;
@@ -220,9 +219,6 @@
   // Accessor for the contents WebView.
   views::WebView* contents_web_view() { return contents_web_view_; }
 
-  // Accessor for the BrowserView's TabSearchButton instance.
-  TabSearchButton* GetTabSearchButton();
-
   // Returns true if various window components are visible.
   bool IsTabStripVisible() const;
 
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view.h b/chrome/browser/ui/views/intent_picker_bubble_view.h
index 5f387868c..eb5c90f0 100644
--- a/chrome/browser/ui/views/intent_picker_bubble_view.h
+++ b/chrome/browser/ui/views/intent_picker_bubble_view.h
@@ -115,6 +115,14 @@
   FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewTest, ButtonLabels);
   FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewBrowserTestChromeOS,
                            BubblePopOut);
+  FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewBrowserTestChromeOS,
+                           OutOfScopeDoesNotShowBubble);
+  FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewBrowserTestChromeOS,
+                           PWAOnlyDoesNotShowBubble);
+  FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewBrowserTestChromeOS,
+                           NotLinkDoesNotShowBubble);
+  FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewBrowserTestChromeOS,
+                           DismissBubble);
 
   static std::unique_ptr<IntentPickerBubbleView> CreateBubbleViewForTesting(
       views::View* anchor_view,
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc
index 77dae26..e5b906f2 100644
--- a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc
+++ b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc
@@ -63,11 +63,16 @@
 
   apps::AppServiceTest& app_service_test() { return app_service_test_; }
 
+  IntentPickerBubbleView* intent_picker_bubble() {
+    return IntentPickerBubbleView::intent_picker_bubble();
+  }
+
  private:
   apps::AppServiceProxy* app_service_proxy_ = nullptr;
   apps::AppServiceTest app_service_test_;
 };
 
+// Test that the intent picker bubble will pop out for ARC apps.
 IN_PROC_BROWSER_TEST_F(IntentPickerBubbleViewBrowserTestChromeOS,
                        BubblePopOut) {
   GURL test_url("https://www.google.com/");
@@ -87,12 +92,128 @@
   ui_test_utils::NavigateToURL(&params);
   app_service_test().WaitForAppService();
   EXPECT_TRUE(intent_picker_view->GetVisible());
-  EXPECT_TRUE(IntentPickerBubbleView::intent_picker_bubble_);
-  EXPECT_EQ(1U,
-            IntentPickerBubbleView::intent_picker_bubble_->GetScrollViewSize());
-  auto& app_info =
-      IntentPickerBubbleView::intent_picker_bubble_->app_info_for_testing();
+  EXPECT_TRUE(intent_picker_bubble());
+  EXPECT_TRUE(intent_picker_bubble()->GetVisible());
+  EXPECT_EQ(1U, intent_picker_bubble()->GetScrollViewSize());
+  auto& app_info = intent_picker_bubble()->app_info_for_testing();
   ASSERT_EQ(1U, app_info.size());
   EXPECT_EQ(kAppId1, app_info[0].launch_name);
   EXPECT_EQ(app_name, app_info[0].display_name);
 }
+
+// Test that navigate outside url scope will not show the intent picker icon or
+// bubble.
+IN_PROC_BROWSER_TEST_F(IntentPickerBubbleViewBrowserTestChromeOS,
+                       OutOfScopeDoesNotShowBubble) {
+  GURL test_url("https://www.google.com/");
+  GURL out_of_scope_url("https://www.example.com/");
+  std::string app_name = "test_name";
+  AddFakeAppWithIntentFilter(kAppId1, app_name, test_url,
+                             apps::mojom::AppType::kArc);
+  PageActionIconView* intent_picker_view = GetIntentPickerIcon();
+
+  chrome::NewTab(browser());
+  ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
+
+  // Navigate from a link.
+  NavigateParams params(browser(), out_of_scope_url,
+                        ui::PageTransition::PAGE_TRANSITION_LINK);
+
+  // Navigates and waits for loading to finish.
+  ui_test_utils::NavigateToURL(&params);
+  app_service_test().WaitForAppService();
+  EXPECT_FALSE(intent_picker_view->GetVisible());
+  EXPECT_FALSE(intent_picker_bubble());
+}
+
+// Test that intent picker bubble will not pop up for only PWA apps.
+IN_PROC_BROWSER_TEST_F(IntentPickerBubbleViewBrowserTestChromeOS,
+                       PWAOnlyDoesNotShowBubble) {
+  GURL test_url("https://www.google.com/");
+  std::string app_name = "test_name";
+  AddFakeAppWithIntentFilter(kAppId1, app_name, test_url,
+                             apps::mojom::AppType::kWeb);
+  PageActionIconView* intent_picker_view = GetIntentPickerIcon();
+
+  chrome::NewTab(browser());
+  ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
+
+  // Navigate from a link.
+  NavigateParams params(browser(), test_url,
+                        ui::PageTransition::PAGE_TRANSITION_LINK);
+
+  // Navigates and waits for loading to finish.
+  ui_test_utils::NavigateToURL(&params);
+  app_service_test().WaitForAppService();
+  EXPECT_TRUE(intent_picker_view->GetVisible());
+  EXPECT_FALSE(intent_picker_bubble());
+}
+
+// Test that intent picker bubble will not pop up for non-link navigation.
+IN_PROC_BROWSER_TEST_F(IntentPickerBubbleViewBrowserTestChromeOS,
+                       NotLinkDoesNotShowBubble) {
+  GURL test_url("https://www.google.com/");
+  std::string app_name = "test_name";
+  AddFakeAppWithIntentFilter(kAppId1, app_name, test_url,
+                             apps::mojom::AppType::kArc);
+  PageActionIconView* intent_picker_view = GetIntentPickerIcon();
+
+  chrome::NewTab(browser());
+  ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
+
+  // Navigate from a link.
+  NavigateParams params(browser(), test_url,
+                        ui::PageTransition::PAGE_TRANSITION_FROM_ADDRESS_BAR);
+
+  // Navigates and waits for loading to finish.
+  ui_test_utils::NavigateToURL(&params);
+  app_service_test().WaitForAppService();
+  EXPECT_TRUE(intent_picker_view->GetVisible());
+  EXPECT_FALSE(intent_picker_bubble());
+}
+
+// Test that dismiss the bubble for 2 times for the same origin will not show
+// the bubble again. Test that the intent picker bubble will pop out for ARC
+// apps.
+IN_PROC_BROWSER_TEST_F(IntentPickerBubbleViewBrowserTestChromeOS,
+                       DismissBubble) {
+  GURL test_url("https://www.google.com/");
+  std::string app_name = "test_name";
+  AddFakeAppWithIntentFilter(kAppId1, app_name, test_url,
+                             apps::mojom::AppType::kArc);
+  PageActionIconView* intent_picker_view = GetIntentPickerIcon();
+
+  chrome::NewTab(browser());
+  ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
+
+  // Navigate from a link.
+  NavigateParams params(browser(), test_url,
+                        ui::PageTransition::PAGE_TRANSITION_LINK);
+
+  // Navigates and waits for loading to finish.
+  ui_test_utils::NavigateToURL(&params);
+  app_service_test().WaitForAppService();
+  EXPECT_TRUE(intent_picker_view->GetVisible());
+  EXPECT_TRUE(intent_picker_bubble());
+  EXPECT_TRUE(intent_picker_bubble()->GetVisible());
+  EXPECT_EQ(1U, intent_picker_bubble()->GetScrollViewSize());
+  auto& app_info = intent_picker_bubble()->app_info_for_testing();
+  ASSERT_EQ(1U, app_info.size());
+  EXPECT_EQ(kAppId1, app_info[0].launch_name);
+  EXPECT_EQ(app_name, app_info[0].display_name);
+  EXPECT_TRUE(intent_picker_bubble()->Close());
+
+  ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
+  ui_test_utils::NavigateToURL(&params);
+  app_service_test().WaitForAppService();
+  EXPECT_TRUE(intent_picker_view->GetVisible());
+  EXPECT_TRUE(intent_picker_bubble());
+  EXPECT_TRUE(intent_picker_bubble()->GetVisible());
+  EXPECT_TRUE(intent_picker_bubble()->Close());
+
+  ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
+  ui_test_utils::NavigateToURL(&params);
+  app_service_test().WaitForAppService();
+  EXPECT_TRUE(intent_picker_view->GetVisible());
+  EXPECT_FALSE(intent_picker_bubble());
+}
diff --git a/chrome/browser/ui/views/profiles/incognito_menu_view.cc b/chrome/browser/ui/views/profiles/incognito_menu_view.cc
index 764e259..8e64be0e 100644
--- a/chrome/browser/ui/views/profiles/incognito_menu_view.cc
+++ b/chrome/browser/ui/views/profiles/incognito_menu_view.cc
@@ -52,7 +52,10 @@
   int incognito_window_count =
       BrowserList::GetOffTheRecordBrowsersActiveForProfile(
           browser()->profile());
-
+  // TODO(crbug.com/1105763): Add asset colors to native theme and update icon
+  // temporary color placeholder to align with the design deck colors.
+  ui::ThemedVectorIcon header_art_icon(&kIncognitoMenuArtIcon,
+                                       ui::NativeTheme::kColorId_MenuIconColor);
   SetProfileIdentityInfo(
       /*profile_name=*/base::string16(),
       /*background_color=*/SK_ColorTRANSPARENT,
@@ -63,7 +66,8 @@
       incognito_window_count > 1
           ? l10n_util::GetPluralStringFUTF16(IDS_INCOGNITO_WINDOW_COUNT_MESSAGE,
                                              incognito_window_count)
-          : base::string16());
+          : base::string16(),
+      header_art_icon);
 
 #if defined(OS_WIN)
   if (ProfileShortcutManager::IsFeatureEnabled() &&
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc
index c6a4375..f93e7d6 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -491,11 +491,16 @@
                                                 guest_window_count);
   }
 
+  // TODO(crbug.com/1105763): Add asset colors to native theme and update icon
+  // temporary color placeholder to align with the design deck colors.
+  ui::ThemedVectorIcon header_art_icon(&kGuestMenuArtIcon,
+                                       ui::NativeTheme::kColorId_MenuIconColor);
   SetProfileIdentityInfo(
       /*profile_name=*/base::string16(),
       /*background_color=*/SK_ColorTRANSPARENT,
       /*edit_button=*/base::nullopt, profiles::GetGuestAvatar(),
-      l10n_util::GetStringUTF16(IDS_GUEST_PROFILE_NAME), subtitle);
+      l10n_util::GetStringUTF16(IDS_GUEST_PROFILE_NAME), subtitle,
+      header_art_icon);
 }
 
 void ProfileMenuView::BuildAutofillButtons() {
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
index 5332d75..bac3c57 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -61,6 +61,9 @@
 constexpr int kDefaultMargin = 8;
 constexpr int kBadgeSize = 16;
 constexpr int kCircularImageButtonSize = 28;
+// TODO(crbug.com/1128499): Remove this constant by extracting art height from
+// |avatar_header_art|.
+constexpr int kHeaderArtHeight = 72;
 constexpr int kIdentityImageBorder = 2;
 constexpr int kIdentityImageSizeInclBorder =
     ProfileMenuViewBase::kIdentityImageSize + 2 * kIdentityImageBorder;
@@ -360,7 +363,8 @@
     base::Optional<SkColor> background_color,
     int corner_radius,
     std::unique_ptr<views::View> avatar_image_view,
-    std::unique_ptr<views::View> edit_button) {
+    std::unique_ptr<views::View> edit_button,
+    const ui::ThemedVectorIcon& avatar_header_art) {
   constexpr int kExtraMarginInsideProfileBackground = 2;
 
   views::View* profile_background_container =
@@ -389,8 +393,23 @@
         views::CreateBackgroundFromPainter(
             views::Painter::CreateSolidRoundRectPainter(
                 background_color.value(), corner_radius, background_insets)));
+  } else {
+    profile_background_container->SetBackground(
+        views::CreateThemedVectorIconBackground(profile_background_container,
+                                                avatar_header_art));
   }
 
+  // |avatar_margin| is derived from |avatar_header_art| asset height, it
+  // increases margin for the avatar icon to make |avatar_header_art| visible
+  // above the center of the avatar icon.
+  // Subtracting |kIdentityImageBorder| from the height as it isn't part of the
+  // actual image and shouldn't affect the margin.
+  const int avatar_margin =
+      avatar_header_art.empty()
+          ? kDefaultMargin
+          : kHeaderArtHeight - kIdentityImageBorder -
+                ProfileMenuViewBase::kIdentityImageSize / 2;
+
   // The |heading_and_image_container| is on the left and it stretches almost
   // the full width. It contains the profile heading and the avatar image.
   views::View* heading_and_image_container =
@@ -406,12 +425,14 @@
       ->SetOrientation(views::LayoutOrientation::kVertical)
       .SetMainAxisAlignment(views::LayoutAlignment::kCenter)
       .SetCrossAxisAlignment(views::LayoutAlignment::kCenter)
-      .SetInteriorMargin(gfx::Insets(/*top=*/kDefaultMargin, 0, 0, 0));
+      .SetInteriorMargin(gfx::Insets(/*top=*/avatar_margin, 0, 0, 0));
   if (heading_label) {
+    DCHECK(avatar_header_art.empty());
     heading_label->SetBorder(
         views::CreateEmptyBorder(gfx::Insets(/*vertical=*/kDefaultMargin, 0)));
     heading_and_image_container->AddChildView(std::move(heading_label));
   }
+
   heading_and_image_container->AddChildView(std::move(avatar_image_view));
 
   // The |edit_button| is on the right and has fixed width.
@@ -520,7 +541,8 @@
     base::Optional<EditButtonParams> edit_button_params,
     const ui::ImageModel& image_model,
     const base::string16& title,
-    const base::string16& subtitle) {
+    const base::string16& subtitle,
+    const ui::ThemedVectorIcon& avatar_header_art) {
   constexpr int kBottomMargin = kDefaultMargin;
   const bool new_design =
       base::FeatureList::IsEnabled(features::kNewProfilePicker);
@@ -603,7 +625,7 @@
       /*parent=*/identity_info_container_, std::move(heading_label),
       background_color,
       GetCornerRadius(),  // Use the same radius as the bubble has.
-      std::move(avatar_image_view), std::move(edit_button));
+      std::move(avatar_image_view), std::move(edit_button), avatar_header_art);
   BuildProfileTitleAndSubtitle(/*parent=*/identity_info_container_, title,
                                subtitle);
 }
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.h b/chrome/browser/ui/views/profiles/profile_menu_view_base.h
index e4cf118..c1492c4 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_base.h
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.h
@@ -128,7 +128,8 @@
       base::Optional<EditButtonParams> edit_button_params,
       const ui::ImageModel& image_model,
       const base::string16& title,
-      const base::string16& subtitle = base::string16());
+      const base::string16& subtitle = base::string16(),
+      const ui::ThemedVectorIcon& avatar_header_art = ui::ThemedVectorIcon());
   void SetSyncInfo(const SyncInfo& sync_info,
                    const base::RepeatingClosure& action,
                    bool show_badge);
diff --git a/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc b/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc
index 98e8d5b..b9b6d6a3 100644
--- a/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc
+++ b/chrome/browser/ui/views/sharesheet/sharesheet_bubble_view.cc
@@ -189,10 +189,9 @@
                                  kExpandViewPadding);
   expanded_layout->StartRow(views::GridLayout::kFixedSize, COLUMN_SET_ID_TITLE,
                             kExpandViewTitleLabelHeight);
-  // TODO(crbug.com/1130409) Add translation for this string.
   auto* app_list_label =
       expanded_layout->AddView(std::make_unique<views::Label>(
-          base::UTF8ToUTF16(base::StringPiece("Apps list"))));
+          l10n_util::GetStringUTF16(IDS_SHARESHEET_APPS_LIST_LABEL)));
   app_list_label->SetFontList(gfx::FontList(kExpandViewTitleFont));
   app_list_label->SetLineHeight(kExpandViewTitleLabelHeight);
   app_list_label->SetEnabledColor(kShareTargetTitleColor);
@@ -247,7 +246,7 @@
 
     auto target_view = std::make_unique<SharesheetTargetButton>(
         this, target.display_name, secondary_display_name, &target.icon);
-    target_view->set_tag(++target_counter);
+    target_view->set_tag(target_counter++);
 
     layout_for_target->AddView(std::move(target_view));
   }
diff --git a/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.cc b/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.cc
index f6fdc9ef..d7bf31a 100644
--- a/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.cc
+++ b/chrome/browser/ui/views/sharesheet/sharesheet_expand_button.cc
@@ -5,7 +5,9 @@
 #include "chrome/browser/ui/views/sharesheet/sharesheet_expand_button.h"
 
 #include "chrome/app/vector_icons/vector_icons.h"
+#include "chrome/grit/generated_resources.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/views/layout/box_layout.h"
@@ -45,14 +47,13 @@
 void SharesheetExpandButton::SetDefaultView() {
   icon_->SetImage(
       gfx::CreateVectorIcon(kCaretDownIcon, kCaretIconSize, kLabelColor));
-  // TODO(crbug.com/1130409) Add translation for this and below strings.
-  label_->SetText(base::UTF8ToUTF16(base::StringPiece("More apps")));
+  label_->SetText(l10n_util::GetStringUTF16(IDS_SHARESHEET_MORE_APPS_LABEL));
 }
 
 void SharesheetExpandButton::SetExpandedView() {
   icon_->SetImage(
       gfx::CreateVectorIcon(kCaretUpIcon, kCaretIconSize, kLabelColor));
-  label_->SetText(base::UTF8ToUTF16(base::StringPiece("Fewer apps")));
+  label_->SetText(l10n_util::GetStringUTF16(IDS_SHARESHEET_FEWER_APPS_LABEL));
 }
 
 gfx::Size SharesheetExpandButton::CalculatePreferredSize() const {
diff --git a/chrome/browser/ui/views/tabs/tab_search_button_browsertest.cc b/chrome/browser/ui/views/tabs/tab_search_button_browsertest.cc
deleted file mode 100644
index a7fe2cba4..0000000
--- a/chrome/browser/ui/views/tabs/tab_search_button_browsertest.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/tabs/tab_search_button.h"
-
-#include <vector>
-
-#include "base/feature_list.h"
-#include "base/test/scoped_feature_list.h"
-#include "build/build_config.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/ui_features.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/tabs/tab_search_button.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "content/public/test/browser_test.h"
-#include "ui/base/accelerators/accelerator.h"
-
-namespace {
-ui::MouseEvent GetDummyEvent() {
-  return ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::PointF(), gfx::PointF(),
-                        base::TimeTicks::Now(), 0, 0);
-}
-}  // namespace
-
-class TabSearchButtonBrowserTest : public InProcessBrowserTest,
-                                   public ::testing::WithParamInterface<bool> {
- public:
-  // InProcessBrowserTest:
-  void SetUp() override {
-    // Run the test with both kTabSearchFixedEntrypoint enabled and disabled.
-    if (GetParam()) {
-      scoped_feature_list_.InitWithFeatures(
-          /*enabled_features=*/{features::kTabSearch,
-                                features::kTabSearchFixedEntrypoint},
-          /*disabled_features=*/{});
-    } else {
-      scoped_feature_list_.InitWithFeatures(
-          /*enabled_features=*/{features::kTabSearch},
-          /*disabled_features=*/{features::kTabSearchFixedEntrypoint});
-    }
-    InProcessBrowserTest::SetUp();
-  }
-
-  BrowserView* browser_view() {
-    return BrowserView::GetBrowserViewForBrowser(browser());
-  }
-
-  TabSearchButton* tab_search_button() {
-    return browser_view()->GetTabSearchButton();
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-IN_PROC_BROWSER_TEST_P(TabSearchButtonBrowserTest, CreateAndClose) {
-  ASSERT_EQ(nullptr, tab_search_button()->bubble_for_testing());
-  tab_search_button()->ButtonPressed(tab_search_button(), GetDummyEvent());
-  ASSERT_NE(nullptr, tab_search_button()->bubble_for_testing());
-
-  // Close the tab search bubble widget, the bubble should be cleared from the
-  // TabSearchButton.
-  tab_search_button()->bubble_for_testing()->CloseWithReason(
-      views::Widget::ClosedReason::kUnspecified);
-  ASSERT_EQ(nullptr, tab_search_button()->bubble_for_testing());
-}
-
-IN_PROC_BROWSER_TEST_P(TabSearchButtonBrowserTest, TestBubbleVisible) {
-  EXPECT_FALSE(tab_search_button()->IsBubbleVisible());
-
-  ASSERT_EQ(nullptr, tab_search_button()->bubble_for_testing());
-  tab_search_button()->ButtonPressed(tab_search_button(), GetDummyEvent());
-  ASSERT_NE(nullptr, tab_search_button()->bubble_for_testing());
-
-  // The bubble should not be visible initially since the UI must notify the
-  // bubble it is ready before the bubble is shown.
-  EXPECT_FALSE(tab_search_button()->IsBubbleVisible());
-
-  // Trigger showing the bubble.
-  tab_search_button()->bubble_for_testing()->Show();
-
-  // The bubble should be visible after being shown.
-  EXPECT_TRUE(tab_search_button()->IsBubbleVisible());
-}
-
-// On macOS, most accelerators are handled by CommandDispatcher.
-#if !defined(OS_MAC)
-IN_PROC_BROWSER_TEST_P(TabSearchButtonBrowserTest, TestBubbleKeyboardShortcut) {
-  ASSERT_EQ(nullptr, tab_search_button()->bubble_for_testing());
-
-  auto accelerator = ui::Accelerator(
-      ui::VKEY_A, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR);
-  browser_view()->AcceleratorPressed(accelerator);
-
-  // Accelerator keys should have created the tab search bubble.
-  ASSERT_NE(nullptr, tab_search_button()->bubble_for_testing());
-
-  // Close the tab search bubble widget, the bubble should be cleared from the
-  // TabSearchButton.
-  tab_search_button()->bubble_for_testing()->CloseWithReason(
-      views::Widget::ClosedReason::kUnspecified);
-  ASSERT_EQ(nullptr, tab_search_button()->bubble_for_testing());
-}
-#endif
-
-INSTANTIATE_TEST_SUITE_P(All,
-                         TabSearchButtonBrowserTest,
-                         ::testing::Values(true, false));
diff --git a/chrome/browser/ui/views/tabs/tab_strip_browsertest.cc b/chrome/browser/ui/views/tabs/tab_strip_browsertest.cc
index 6a13c71..aa7e857 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_browsertest.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip_browsertest.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/tabs/tab_search_button.h"
 #include "chrome/browser/ui/views/tabs/tab_strip_controller.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/tab_groups/tab_group_id.h"
@@ -812,3 +813,28 @@
   tab_strip()->SelectTab(tab_strip()->tab_at(0), GetDummyEvent());
   EXPECT_FALSE(tab_strip()->controller()->IsGroupCollapsed(group));
 }
+
+class TabSearchButtonTest : public TabStripBrowsertest {
+ public:
+  void SetUp() override {
+    scoped_feature_list_.InitWithFeatureState(features::kTabSearch, true);
+    TabStripBrowsertest::SetUp();
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(TabSearchButtonTest, TabSearchBubble_CreateAndClose) {
+  TabSearchButton* tab_search_button = tab_strip()->tab_search_button();
+
+  DCHECK_EQ(nullptr, tab_search_button->bubble_for_testing());
+  tab_search_button->ButtonPressed(tab_search_button, GetDummyEvent());
+  DCHECK_NE(nullptr, tab_search_button->bubble_for_testing());
+
+  // Close the tab search bubble widget, the bubble should be cleared from the
+  // TabSearchButton.
+  tab_search_button->bubble_for_testing()->CloseWithReason(
+      views::Widget::ClosedReason::kUnspecified);
+  DCHECK_EQ(nullptr, tab_search_button->bubble_for_testing());
+}
diff --git a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
index 7194eecd..53725337 100644
--- a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
+++ b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
@@ -168,10 +168,13 @@
 
   content::WebContents* web_contents = nullptr;
 
+  // TODO(crbug.com/1129340): Remove these lines and make CCA resizeable after
+  // CCA supports responsive UI.
+  bool can_resize = app_type != SystemAppType::CAMERA;
   if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions)) {
     if (!browser)
       browser = CreateWebApplicationWindow(profile, params->app_id,
-                                           params->disposition);
+                                           params->disposition, can_resize);
 
     // Navigate application window to application's |url| if necessary.
     // Help app always navigates because its url might not match the url inside
@@ -184,7 +187,7 @@
     }
   } else {
     if (!browser)
-      browser = CreateApplicationWindow(profile, *params, url);
+      browser = CreateApplicationWindow(profile, *params, url, can_resize);
 
     // Navigate application window to application's |url| if necessary.
     // Help app always navigates because its url might not match the url inside
diff --git a/chrome/browser/ui/web_applications/web_app_launch_manager.cc b/chrome/browser/ui/web_applications/web_app_launch_manager.cc
index 31590a0..f6babbf 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_manager.cc
+++ b/chrome/browser/ui/web_applications/web_app_launch_manager.cc
@@ -76,7 +76,8 @@
 
 Browser* CreateWebApplicationWindow(Profile* profile,
                                     const std::string& app_id,
-                                    WindowOpenDisposition disposition) {
+                                    WindowOpenDisposition disposition,
+                                    bool can_resize) {
   std::string app_name = GenerateApplicationNameFromAppId(app_id);
   gfx::Rect initial_bounds;
   Browser::CreateParams browser_params =
@@ -88,6 +89,7 @@
                 app_name, /*trusted_source=*/true, initial_bounds, profile,
                 /*user_gesture=*/true);
   browser_params.initial_show_state = DetermineWindowShowState();
+  browser_params.can_resize = can_resize;
   return new Browser(browser_params);
 }
 
diff --git a/chrome/browser/ui/web_applications/web_app_launch_manager.h b/chrome/browser/ui/web_applications/web_app_launch_manager.h
index 3ff6ca1f..a9d0c587a 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_manager.h
+++ b/chrome/browser/ui/web_applications/web_app_launch_manager.h
@@ -66,7 +66,8 @@
 
 Browser* CreateWebApplicationWindow(Profile* profile,
                                     const std::string& app_id,
-                                    WindowOpenDisposition disposition);
+                                    WindowOpenDisposition disposition,
+                                    bool can_resize = true);
 
 content::WebContents* NavigateWebApplicationWindow(
     Browser* browser,
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc
index 0d48bc4e..bac67a83f 100644
--- a/chrome/browser/ui/webui/settings/settings_ui.cc
+++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -320,6 +320,8 @@
   auto plural_string_handler = std::make_unique<PluralStringHandler>();
   plural_string_handler->AddLocalizedString(
       "compromisedPasswords", IDS_SETTINGS_COMPROMISED_PASSWORDS_COUNT);
+  plural_string_handler->AddLocalizedString(
+      "insecurePasswords", IDS_SETTINGS_INSECURE_PASSWORDS_COUNT);
   web_ui->AddMessageHandler(std::move(plural_string_handler));
 
   // Add the metrics handler to write uma stats.
diff --git a/chrome/browser/web_applications/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_app_manager.cc
index 665f933..783beab 100644
--- a/chrome/browser/web_applications/system_web_app_manager.cc
+++ b/chrome/browser/web_applications/system_web_app_manager.cc
@@ -157,6 +157,7 @@
     infos.at(SystemAppType::HELP).additional_search_terms = {
         IDS_GENIUS_APP_NAME, IDS_HELP_APP_PERKS, IDS_HELP_APP_OFFERS};
     infos.at(SystemAppType::HELP).minimum_window_size = {600, 320};
+    infos.at(SystemAppType::HELP).capture_navigations = true;
   }
 
   if (SystemWebAppManager::IsAppEnabled(SystemAppType::MEDIA)) {
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 6c19ffe..dac9693 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-master-1600797595-fd8ddba8caaa456739bdf5b1d17d7be117d929dc.profdata
+chrome-linux-master-1600840405-46e4cd70bd3de973a171c7f611770f78487d203a.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 9de06df..bde3448 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-master-1600775907-1d0a614b540ad15c6823911f93c081428c564ce9.profdata
+chrome-mac-master-1600840405-f4d8e4031cebaee3fd15a03b0f21d18ea0743d9a.profdata
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 55622d9..83746d7 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -949,15 +949,15 @@
 const char kPerAppTimeLimitsAllowlistPolicy[] =
     "child_user.per_app_time_limits.whitelist";
 
-// Time pref to record the user engagement session start time for family user
-// metrics.
-const char kFamilyUserMetricsSessionEngagementStartTime[] =
-    "family_user.metrics.session_engagement_start_time";
-
 // Integer pref to record the day id (number of days since origin of time) when
 // family user metrics were last recorded.
 const char kFamilyUserMetricsDayId[] = "family_user.metrics.day_id";
 
+// TimeDelta pref to record the accumulated user session duration for family
+// user metrics.
+const char kFamilyUserMetricsSessionEngagementDuration[] =
+    "family_user.metrics.session_engagement_duration";
+
 // List of preconfigured network file shares.
 const char kNetworkFileSharesPreconfiguredShares[] =
     "network_file_shares.preconfigured_shares";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index f619661..c687068 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -324,8 +324,8 @@
 extern const char kPerAppTimeLimitsLatestLimitUpdateTime[];
 extern const char kPerAppTimeLimitsPolicy[];
 extern const char kPerAppTimeLimitsAllowlistPolicy[];
-extern const char kFamilyUserMetricsSessionEngagementStartTime[];
 extern const char kFamilyUserMetricsDayId[];
+extern const char kFamilyUserMetricsSessionEngagementDuration[];
 extern const char kDeviceWallpaperImageFilePath[];
 extern const char kKerberosRememberPasswordEnabled[];
 extern const char kKerberosAddAccountsAllowed[];
diff --git a/chrome/services/cups_proxy/BUILD.gn b/chrome/services/cups_proxy/BUILD.gn
index 88bdf62..beacb68 100644
--- a/chrome/services/cups_proxy/BUILD.gn
+++ b/chrome/services/cups_proxy/BUILD.gn
@@ -56,6 +56,7 @@
   sources = [
     "ipp_validator_unittest.cc",
     "printer_installer_unittest.cc",
+    "proxy_manager_unittest.cc",
     "socket_manager_unittest.cc",
   ]
 
@@ -71,6 +72,7 @@
     "//chrome/services/cups_proxy/public/cpp:unit_tests",
     "//chrome/services/cups_proxy/test:test_support",
     "//chromeos",
+    "//content/public/browser",
     "//testing/gmock",
     "//testing/gtest",
   ]
diff --git a/chrome/services/cups_proxy/proxy_manager.cc b/chrome/services/cups_proxy/proxy_manager.cc
index 8b54a05..9bc19aae 100644
--- a/chrome/services/cups_proxy/proxy_manager.cc
+++ b/chrome/services/cups_proxy/proxy_manager.cc
@@ -12,6 +12,7 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/containers/ring_buffer.h"
 #include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/task/post_task.h"
@@ -45,8 +46,16 @@
                    std::unique_ptr<CupsProxyServiceDelegate> delegate,
                    std::unique_ptr<IppValidator> ipp_validator,
                    std::unique_ptr<PrinterInstaller> printer_installer,
-                   std::unique_ptr<SocketManager> socket_manager);
-  ~ProxyManagerImpl() override;
+                   std::unique_ptr<SocketManager> socket_manager)
+      : delegate_(std::move(delegate)),
+        ipp_validator_(std::move(ipp_validator)),
+        printer_installer_(std::move(printer_installer)),
+        socket_manager_(std::move(socket_manager)),
+        receiver_(this, std::move(request)) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  }
+
+  ~ProxyManagerImpl() override = default;
 
   void ProxyRequest(const std::string& method,
                     const std::string& url,
@@ -85,6 +94,9 @@
   // Current in-flight request.
   std::unique_ptr<InFlightRequest> in_flight_;
 
+  // Timestamp ring buffer.
+  base::RingBuffer<base::TimeTicks, kRateLimit> timestamp_;
+
   // CupsIppParser Service handle.
   mojo::Remote<ipp_parser::mojom::IppParser> ipp_parser_;
 
@@ -125,22 +137,6 @@
   return ret;
 }
 
-ProxyManagerImpl::ProxyManagerImpl(
-    mojo::PendingReceiver<CupsProxier> receiver,
-    std::unique_ptr<CupsProxyServiceDelegate> delegate,
-    std::unique_ptr<IppValidator> ipp_validator,
-    std::unique_ptr<PrinterInstaller> printer_installer,
-    std::unique_ptr<SocketManager> socket_manager)
-    : delegate_(std::move(delegate)),
-      ipp_validator_(std::move(ipp_validator)),
-      printer_installer_(std::move(printer_installer)),
-      socket_manager_(std::move(socket_manager)),
-      receiver_(this, std::move(receiver)) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-ProxyManagerImpl::~ProxyManagerImpl() = default;
-
 void ProxyManagerImpl::ProxyRequest(
     const std::string& method,
     const std::string& url,
@@ -150,6 +146,23 @@
     ProxyRequestCallback cb) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
+  // Limit the rate of requests to kRateLimit per second.
+  // The way the algorithm works is if the number of times this method was
+  // called between a second ago and now, including the current call, exceeds
+  // kRateLimit, the request is blocked and the HTTP 429 Too Many Requests
+  // response status code is returned.
+  base::TimeTicks time = base::TimeTicks::Now();
+  bool block_request =
+      timestamp_.CurrentIndex() >= timestamp_.BufferSize() &&
+      time - timestamp_.ReadBuffer(0) < base::TimeDelta::FromSeconds(1);
+  timestamp_.SaveToBuffer(time);
+  if (block_request) {
+    DVLOG(1) << "CupsPrintService Error: Rate limit (" << kRateLimit
+             << ") exceeded";
+    std::move(cb).Run({}, {}, 429);  // HTTP_STATUS_TOO_MANY_REQUESTS
+    return;
+  }
+
   if (!delegate_->IsPrinterAccessAllowed()) {
     DVLOG(1) << "Printer access not allowed";
     std::move(cb).Run(/*headers=*/{}, /*ipp_message=*/{},
@@ -343,14 +356,12 @@
 std::unique_ptr<ProxyManager> ProxyManager::Create(
     mojo::PendingReceiver<mojom::CupsProxier> request,
     std::unique_ptr<CupsProxyServiceDelegate> delegate) {
-  // Setting up injected managers.
-  auto ipp_validator = std::make_unique<IppValidator>(delegate.get());
-  auto printer_installer = std::make_unique<PrinterInstaller>(delegate.get());
-  auto socket_manager = SocketManager::Create(delegate.get());
-
+  auto* delegate_ptr = delegate.get();
   return std::make_unique<ProxyManagerImpl>(
-      std::move(request), std::move(delegate), std::move(ipp_validator),
-      std::move(printer_installer), std::move(socket_manager));
+      std::move(request), std::move(delegate),
+      std::make_unique<IppValidator>(delegate_ptr),
+      std::make_unique<PrinterInstaller>(delegate_ptr),
+      SocketManager::Create(delegate_ptr));
 }
 
 std::unique_ptr<ProxyManager> ProxyManager::CreateForTesting(
diff --git a/chrome/services/cups_proxy/proxy_manager.h b/chrome/services/cups_proxy/proxy_manager.h
index ba3c599..76aae82 100644
--- a/chrome/services/cups_proxy/proxy_manager.h
+++ b/chrome/services/cups_proxy/proxy_manager.h
@@ -25,12 +25,15 @@
 // This handler's job is vetting incoming arbitrary CUPS IPP requests before
 // they reach the CUPS Daemon. Requests are parsed out-of-process, by the
 // CupsIppParser Service, and validated/rebuilt in-process before being proxied.
-// This handler must be created/accessed from a seqeunced context.
+// This handler must be created/accessed from a sequenced context.
 //
 // Note: This handler only supports processing one request at a time; any
 // concurrent requests will immediately fail with an empty response.
 class ProxyManager : public mojom::CupsProxier {
  public:
+  // Request rate limit per second.
+  static constexpr int kRateLimit = 10;
+
   // Factory function.
   static std::unique_ptr<ProxyManager> Create(
       mojo::PendingReceiver<mojom::CupsProxier> request,
diff --git a/chrome/services/cups_proxy/proxy_manager_unittest.cc b/chrome/services/cups_proxy/proxy_manager_unittest.cc
new file mode 100644
index 0000000..accccac
--- /dev/null
+++ b/chrome/services/cups_proxy/proxy_manager_unittest.cc
@@ -0,0 +1,116 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/services/cups_proxy/proxy_manager.h"
+
+#include <map>
+
+#include "base/test/task_environment.h"
+#include "chrome/services/cups_proxy/fake_cups_proxy_service_delegate.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cups_proxy {
+
+namespace {
+
+constexpr int kHttpTooManyRequests = 429;
+
+class MyFakeCupsProxyServiceDelegate : public FakeCupsProxyServiceDelegate {
+  bool IsPrinterAccessAllowed() const override { return false; }
+};
+
+class ProxyManagerTest : public testing::Test {
+ public:
+  ProxyManagerTest()
+      : manager_(ProxyManager::Create(
+            {},
+            std::make_unique<MyFakeCupsProxyServiceDelegate>())) {}
+
+  // Proxy a dummy request and add the response code to count_.
+  void ProxyRequest() const {
+    manager_->ProxyRequest({}, {}, {}, {}, {},
+                           base::BindOnce(&ProxyManagerTest::Callback,
+                                          weak_factory_.GetWeakPtr()));
+  }
+
+  // Return the number of times response code status has been received.
+  int NumRequestsByStatusCode(int32_t status) const {
+    const auto it = count_.find(status);
+    return it == count_.end() ? 0 : it->second;
+  }
+
+  // Fast forward the task environment's fake clock.
+  void FastForwardBy(base::TimeDelta delta) {
+    return task_environment_.FastForwardBy(delta);
+  }
+
+ private:
+  // Add the response code status to count_.
+  void Callback(const std::vector<ipp_converter::HttpHeader>&,
+                const std::vector<uint8_t>&,
+                int32_t status) {
+    count_[status]++;
+  }
+
+  base::test::TaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+
+  std::map<int32_t, int> count_;
+
+  std::unique_ptr<ProxyManager> manager_;
+
+  base::WeakPtrFactory<ProxyManagerTest> weak_factory_{this};
+};
+
+// Test a burst of simultaneous function calls.
+TEST_F(ProxyManagerTest, ProxyRequestRateLimitBurst) {
+  for (int i = 0; i < ProxyManager::kRateLimit + 3; i++)
+    ProxyRequest();
+  EXPECT_EQ(NumRequestsByStatusCode(kHttpTooManyRequests), 3);
+}
+
+// Test a 0.99s gap between two bursts of function calls.
+TEST_F(ProxyManagerTest, ProxyRequestRateLimitShortGap) {
+  for (int i = 0; i < ProxyManager::kRateLimit + 1; i++) {
+    if (i == ProxyManager::kRateLimit / 2)
+      FastForwardBy(base::TimeDelta::FromSecondsD(.99));
+    ProxyRequest();
+  }
+  EXPECT_EQ(NumRequestsByStatusCode(kHttpTooManyRequests), 1);
+}
+
+// Test that the rate limit is reset after 1.01s.
+TEST_F(ProxyManagerTest, ProxyRequestRateLimitLongGap) {
+  for (int i = 0; i < ProxyManager::kRateLimit + 1; i++)
+    ProxyRequest();
+  EXPECT_EQ(NumRequestsByStatusCode(kHttpTooManyRequests), 1);
+  FastForwardBy(base::TimeDelta::FromSecondsD(1.01));
+  for (int i = 0; i < ProxyManager::kRateLimit + 1; i++)
+    ProxyRequest();
+  EXPECT_EQ(NumRequestsByStatusCode(kHttpTooManyRequests), 2);
+}
+
+// Test that calls at a constant rate below the rate limit are allowed.
+TEST_F(ProxyManagerTest, ProxyRequestRateLimitBelow) {
+  for (int i = 0; i < ProxyManager::kRateLimit + 10; i++) {
+    FastForwardBy(
+        base::TimeDelta::FromSecondsD(1.01 / ProxyManager::kRateLimit));
+    ProxyRequest();
+  }
+  EXPECT_EQ(NumRequestsByStatusCode(kHttpTooManyRequests), 0);
+}
+
+// Test that calls at a constant rate above the rate limit are blocked.
+TEST_F(ProxyManagerTest, ProxyRequestRateLimitAbove) {
+  for (int i = 0; i < ProxyManager::kRateLimit + 10; i++) {
+    FastForwardBy(
+        base::TimeDelta::FromSecondsD(.99 / ProxyManager::kRateLimit));
+    ProxyRequest();
+  }
+  EXPECT_EQ(NumRequestsByStatusCode(kHttpTooManyRequests), 10);
+}
+
+}  // namespace
+
+}  // namespace cups_proxy
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 74bd3b6..4737b2a 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1454,7 +1454,6 @@
       "../browser/ui/views/sharing/shared_clipboard_browsertest.cc",
       "../browser/ui/views/sharing/sharing_browsertest.cc",
       "../browser/ui/views/sharing/sharing_browsertest.h",
-      "../browser/ui/views/tabs/tab_search_button_browsertest.cc",
       "../browser/ui/views/tabs/tab_strip_browsertest.cc",
       "../browser/ui/views/try_chrome_dialog_win/try_chrome_dialog_browsertest.cc",
       "../browser/ui/views/web_apps/web_app_frame_toolbar_browsertest.cc",
@@ -2605,6 +2604,7 @@
         "../browser/chromeos/startup_settings_cache_browsertest.cc",
         "../browser/chromeos/system/device_disabling_browsertest.cc",
         "../browser/chromeos/system/tray_accessibility_browsertest.cc",
+        "../browser/chromeos/web_applications/camera_app_integration_browsertest.cc",
         "../browser/chromeos/web_applications/diagnostics_app_integration_browsertest.cc",
         "../browser/chromeos/web_applications/help_app_integration_browsertest.cc",
         "../browser/chromeos/web_applications/media_app_integration_browsertest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/RevampedContextMenuUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/RevampedContextMenuUtils.java
index 984a70c..9a198de 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/RevampedContextMenuUtils.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/contextmenu/RevampedContextMenuUtils.java
@@ -116,6 +116,28 @@
     }
 
     /**
+     * Selects the context menu chip asserting that an intent will be sent with a
+     * specific package name.  Note that this method does not open the context menu.
+     * @param instrumentation       Instrumentation module used for executing test behavior.
+     * @param expectedActivity      The activity to assert for gaining focus after click or null.
+     * @param menuCoordinator       The menu coordinator which manages the context menu.
+     * @param openerDOMNodeId       The DOM node to long press to open the context menu for.
+     * @param itemId                The context menu item ID to select.
+     * @param expectedIntentPackage If firing an external intent the expected package name of the
+     *         target.
+     * @throws TimeoutException
+     */
+    public static void selectAlreadyOpenedContextMenuChipWithExpectedIntent(
+            Instrumentation instrumentation, Activity expectedActivity,
+            RevampedContextMenuCoordinator menuCoordinator, String openerDOMNodeId,
+            final int itemId, String expectedIntentPackage) throws TimeoutException {
+        Assert.assertNotNull("Menu coordinator was not provided.", menuCoordinator);
+
+        selectAlreadyOpenedContextMenuChip(
+                instrumentation, expectedActivity, menuCoordinator, itemId, expectedIntentPackage);
+    }
+
+    /**
      * Long presses to open and selects an item from a context menu.
      * @param instrumentation       Instrumentation module used for executing test behavior.
      * @param expectedActivity      The activity to assert for gaining focus after click or null.
@@ -183,4 +205,25 @@
             Intents.release();
         }
     }
+
+    private static void selectAlreadyOpenedContextMenuChip(Instrumentation instrumentation,
+            final Activity expectedActivity, final RevampedContextMenuCoordinator menuCoordinator,
+            final int itemId, final String expectedIntentPackage) {
+        if (expectedIntentPackage != null) {
+            Intents.init();
+        }
+
+        instrumentation.runOnMainSync(() -> menuCoordinator.clickChipForTesting());
+
+        if (expectedActivity != null) {
+            CriteriaHelper.pollInstrumentationThread(expectedActivity::hasWindowFocus);
+        }
+
+        if (expectedIntentPackage != null) {
+            // This line must only execute after all test behavior has completed
+            // or it will intefere with the expected behavior.
+            intended(IntentMatchers.hasPackage(expectedIntentPackage));
+            Intents.release();
+        }
+    }
 }
diff --git a/chrome/test/base/chrome_render_view_host_test_harness.cc b/chrome/test/base/chrome_render_view_host_test_harness.cc
index 4453824..b21500c 100644
--- a/chrome/test/base/chrome_render_view_host_test_harness.cc
+++ b/chrome/test/base/chrome_render_view_host_test_harness.cc
@@ -38,24 +38,11 @@
 
 std::unique_ptr<TestingProfile>
 ChromeRenderViewHostTestHarness::CreateTestingProfile() {
-  // Maintain the profile directory ourselves so that it isn't deleted along
-  // with TestingProfile.  RenderViewHostTestHarness::TearDown() will destroy
-  // the profile and also destroy the thread bundle to ensure that any tasks
-  // posted throughout the test run to completion.  By postponing the deletion
-  // of the profile directory until ~ChromeRenderViewHostTestHarness() we
-  // guarantee that no tasks will try to access the profile directory when it's
-  // (being) deleted.
-  auto temp_dir = std::make_unique<base::ScopedTempDir>();
-  CHECK(temp_dir->CreateUniqueTempDir());
-
   TestingProfile::Builder builder;
-  builder.SetPath(temp_dir->GetPath());
 
   for (auto& pair : GetTestingFactories())
     builder.AddTestingFactory(pair.first, pair.second);
 
-  temp_dirs_.push_back(std::move(temp_dir));
-
   return builder.Build();
 }
 
diff --git a/chrome/test/base/chrome_render_view_host_test_harness.h b/chrome/test/base/chrome_render_view_host_test_harness.h
index 7bbb3ea4..c779104 100644
--- a/chrome/test/base/chrome_render_view_host_test_harness.h
+++ b/chrome/test/base/chrome_render_view_host_test_harness.h
@@ -7,10 +7,8 @@
 
 #include <memory>
 #include <utility>
-#include <vector>
 
 #include "base/compiler_specific.h"
-#include "base/files/scoped_temp_dir.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_renderer_host.h"
 
@@ -43,9 +41,6 @@
 
   // content::RenderViewHostTestHarness.
   std::unique_ptr<content::BrowserContext> CreateBrowserContext() final;
-
- private:
-  std::vector<std::unique_ptr<base::ScopedTempDir>> temp_dirs_;
 };
 
 #endif  // CHROME_TEST_BASE_CHROME_RENDER_VIEW_HOST_TEST_HARNESS_H_
diff --git a/chrome/test/data/chromeos/file_manager/utf8.txt b/chrome/test/data/chromeos/file_manager/utf8.txt
new file mode 100644
index 0000000..43ab174
--- /dev/null
+++ b/chrome/test/data/chromeos/file_manager/utf8.txt
@@ -0,0 +1,5 @@
+Hello नोपहिनस्ति أن 害
+色は匂へど 散りぬるを
+κόσμε ᚹᛦᛗ コンニチハ
+волн ապակի Կրնամ
+їсти मुझे |∊☀✌✂♁ 🙂
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index b629157..6e5b36f 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -283,6 +283,7 @@
         "$root_gen_dir/chrome/test/data/webui/nearby_share/shared/nearby_visibility_page_test.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/ambient_mode_page_test.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/bluetooth_page_tests.m.js",
+        "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cellular_setup_dialog_test.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/date_time_page_tests.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/fake_bluetooth_private.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/fake_bluetooth.m.js",
@@ -290,6 +291,7 @@
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/fake_quick_unlock_private.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/input_method_options_page_test.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/input_page_test.m.js",
+        "$root_gen_dir/chrome/test/data/webui/settings/chromeos/internet_config_test.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/internet_known_networks_page_tests.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/localized_link_test.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/multidevice_feature_item_tests.m.js",
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn
index 86011e5..6d5782a 100644
--- a/chrome/test/data/webui/settings/chromeos/BUILD.gn
+++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -33,6 +33,7 @@
   input_files = [
     "ambient_mode_page_test.js",
     "bluetooth_page_tests.js",
+    "cellular_setup_dialog_test.js",
     "date_time_page_tests.js",
     "fake_bluetooth.js",
     "fake_bluetooth_private.js",
@@ -42,6 +43,7 @@
     "fake_user_action_recorder.js",
     "input_method_options_page_test.js",
     "input_page_test.js",
+    "internet_config_test.js",
     "internet_known_networks_page_tests.js",
     "localized_link_test.js",
     "multidevice_feature_item_tests.js",
diff --git a/chrome/test/data/webui/settings/chromeos/cellular_setup_dialog_test.js b/chrome/test/data/webui/settings/chromeos/cellular_setup_dialog_test.js
new file mode 100644
index 0000000..7548ecc0
--- /dev/null
+++ b/chrome/test/data/webui/settings/chromeos/cellular_setup_dialog_test.js
@@ -0,0 +1,28 @@
+// 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.
+
+// clang-format off
+// #import 'chrome://os-settings/chromeos/os_settings.js';
+
+// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+// clang-format on
+
+suite('CellularSetupDialog', function() {
+  test('Dialog opened on attach', function(done) {
+    /** @type {!OsSettingsCellularSetupDialog} */
+    const cellularSetupDialog =
+        document.createElement('os-settings-cellular-setup-dialog');
+
+    // Verify the dialog is opened.
+    cellularSetupDialog.addEventListener('cr-dialog-open', function(e) {
+      done();
+    });
+
+    // Attach the element to the DOM, which opens the dialog.
+    document.body.appendChild(cellularSetupDialog);
+    Polymer.dom.flush();
+
+    assertTrue(cellularSetupDialog.$.dialog.open);
+  });
+});
diff --git a/chrome/test/data/webui/settings/chromeos/internet_config_test.js b/chrome/test/data/webui/settings/chromeos/internet_config_test.js
new file mode 100644
index 0000000..6198cf66
--- /dev/null
+++ b/chrome/test/data/webui/settings/chromeos/internet_config_test.js
@@ -0,0 +1,41 @@
+// 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.
+
+// clang-format off
+// #import 'chrome://os-settings/chromeos/os_settings.js';
+
+// #import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.m.js';
+// #import {MojoInterfaceProviderImpl} from 'chrome://resources/cr_components/chromeos/network/mojo_interface_provider.m.js';
+// #import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js';
+// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+// clang-format on
+
+suite('InternetConfig', function() {
+  /** @type {!InternetConfig|undefined} */
+  let internetConfig;
+
+  /** @type {!chromeos.networkConfig.mojom.CrosNetworkConfigRemote|undefined} */
+  let mojoApi_;
+
+  suiteSetup(function() {
+    mojoApi_ = new FakeNetworkConfig();
+    network_config.MojoInterfaceProviderImpl.getInstance().remote_ = mojoApi_;
+  });
+
+  setup(function() {
+    internetConfig = document.createElement('internet-config');
+    internetConfig.type = OncMojo.getNetworkTypeString(
+        chromeos.networkConfig.mojom.NetworkType.kWiFi);
+    document.body.appendChild(internetConfig);
+    Polymer.dom.flush();
+  });
+
+  test('Cancel button closes the dialog', function() {
+    internetConfig.open();
+    assertTrue(internetConfig.$.dialog.open);
+
+    internetConfig.$$('cr-button.cancel-button').click();
+    assertFalse(internetConfig.$.dialog.open);
+  });
+});
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
index ce8ddbe..dc7fb57 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -732,6 +732,22 @@
 
 // Test fixture for settings-internet-detail-page.
 // eslint-disable-next-line no-var
+var OSSettingsInternetConfigTest = class extends OSSettingsBrowserTest {
+  /** @override */
+  get extraLibraries() {
+    return super.extraLibraries.concat([
+      BROWSER_SETTINGS_PATH + '../chromeos/fake_network_config_mojom.js',
+      'internet_config_test.js',
+    ]);
+  }
+};
+
+TEST_F('OSSettingsInternetConfigTest', 'All', () => {
+  mocha.run();
+});
+
+// Test fixture for settings-internet-detail-page.
+// eslint-disable-next-line no-var
 var OSSettingsInternetDetailPageTest = class extends OSSettingsBrowserTest {
   /** @override */
   get browsePreload() {
@@ -864,6 +880,37 @@
       mocha.run();
     });
 
+// Test fixture for settings-internet-known-networks-page.
+// eslint-disable-next-line no-var
+var OSSettingsCellularSetupDialogTest =
+    class extends OSSettingsBrowserTest {
+  /** @override */
+  get browsePreload() {
+    return super.browsePreload;/* +
+        'chromeos/internet_page/cellular_setup_dialog.html';*/
+  }
+
+  /** @override */
+  get featureList() {
+    return {enabled: ['chromeos::features::kUpdatedCellularActivationUi']};
+  }
+
+  /** @override */
+  get extraLibraries() {
+    return super.extraLibraries.concat([
+      '//ui/webui/resources/js/assert.js',
+      BROWSER_SETTINGS_PATH + '../test_util.js',
+      'cellular_setup_dialog_test.js',
+    ]);
+  }
+};
+
+TEST_F(
+    'OSSettingsCellularSetupDialogTest', 'CellularSetupDialog',
+    () => {
+      mocha.run();
+    });
+
 // Test fixture for the main settings page.
 // eslint-disable-next-line no-var
 var OSSettingsMainTest = class extends OSSettingsBrowserTest {
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 78a61b5..7299c010 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
@@ -32,6 +32,7 @@
     return {
       enabled: [
         'chromeos::features::kOsSettingsPolymer3',
+        'chromeos::features::kUpdatedCellularActivationUi',
       ],
     };
   }
@@ -92,8 +93,10 @@
 
 [['AmbientModePage', 'ambient_mode_page_test.m.js'],
  ['BluetoothPage', 'bluetooth_page_tests.m.js'],
+ ['CellularSetupDialog', 'cellular_setup_dialog_test.m.js'],
  ['DateTimePage', 'date_time_page_tests.m.js'],
  ['InputMethodOptionPage', 'input_method_options_page_test.m.js'],
+ ['InternetConfig', 'internet_config_test.m.js'],
  ['InternetKnownNetworksPage', 'internet_known_networks_page_tests.m.js'],
  ['LocalizedLink', 'localized_link_test.m.js'],
  ['MultideviceFeatureItem', 'multidevice_feature_item_tests.m.js'],
diff --git a/chrome/test/data/webui/settings/password_check_test.js b/chrome/test/data/webui/settings/password_check_test.js
index e5f9bb2a..8b250d3 100644
--- a/chrome/test/data/webui/settings/password_check_test.js
+++ b/chrome/test/data/webui/settings/password_check_test.js
@@ -10,9 +10,10 @@
 import {isChromeOS} from 'chrome://resources/js/cr.m.js';
 import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {PluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {OpenWindowProxyImpl, PasswordManagerImpl, PasswordManagerProxy, Router, routes} from 'chrome://settings/settings.js';
-import {makeCompromisedCredential,  makePasswordCheckStatus} from 'chrome://test/settings/passwords_and_autofill_fake_data.js';
+import {makeCompromisedCredential, makeInsecureCredential, makePasswordCheckStatus} from 'chrome://test/settings/passwords_and_autofill_fake_data.js';
 import {getSyncAllPrefs,simulateSyncStatus} from 'chrome://test/settings/sync_test_util.m.js';
 import {TestOpenWindowProxy} from 'chrome://test/settings/test_open_window_proxy.js';
 import {TestPasswordManagerProxy} from 'chrome://test/settings/test_password_manager_proxy.js';
@@ -493,8 +494,8 @@
     const spinner = checkPasswordSection.$$('paper-spinner-lite');
     expectFalse(isElementVisible(spinner));
     assertTrue(isElementVisible(icon));
-    expectFalse(icon.classList.contains('has-leaks'));
-    expectTrue(icon.classList.contains('no-leaks'));
+    expectFalse(icon.classList.contains('has-security-issues'));
+    expectTrue(icon.classList.contains('no-security-issues'));
   });
 
   // Tests that there is neither spinner nor icon if the check hasn't run yet.
@@ -527,8 +528,8 @@
     const spinner = checkPasswordSection.$$('paper-spinner-lite');
     expectFalse(isElementVisible(spinner));
     assertTrue(isElementVisible(icon));
-    expectTrue(icon.classList.contains('has-leaks'));
-    expectFalse(icon.classList.contains('no-leaks'));
+    expectTrue(icon.classList.contains('has-security-issues'));
+    expectFalse(icon.classList.contains('no-security-issues'));
   });
 
   // Tests that the spinner is replaced with a warning on errors.
@@ -545,8 +546,8 @@
     const spinner = checkPasswordSection.$$('paper-spinner-lite');
     expectFalse(isElementVisible(spinner));
     assertTrue(isElementVisible(icon));
-    expectFalse(icon.classList.contains('has-leaks'));
-    expectFalse(icon.classList.contains('no-leaks'));
+    expectFalse(icon.classList.contains('has-security-issues'));
+    expectFalse(icon.classList.contains('no-security-issues'));
   });
 
   // Tests that the spinner replaces any icon while the check is running.
@@ -619,6 +620,54 @@
     expectEquals(section.i18n('checkPasswordsProgress', 2, 5), title.innerText);
   });
 
+  // If passwords weakness check is enabled, shows count of insecure
+  // credentials.
+  test('showInsecurePasswordsCount', async function() {
+    loadTimeData.overrideValues({passwordsWeaknessCheck: true});
+    const data = passwordManager.data;
+    data.leakedCredentials = [
+      makeCompromisedCredential('one.com', 'test4', 'LEAKED'),
+    ];
+    data.weakCredentials = [
+      makeInsecureCredential('one.com', 'test4'),
+    ];
+
+    const section = createCheckPasswordSection();
+    await passwordManager.whenCalled('getPasswordCheckStatus');
+    flush();
+    const subtitle = section.$.subtitle;
+    assertTrue(isElementVisible(subtitle));
+
+    return PluralStringProxyImpl.getInstance()
+        .getPluralString('insecurePasswords', 2)
+        .then(count => {
+          expectEquals(count, subtitle.textContent.trim());
+        });
+  });
+
+  // If passwords weakness check is disabled, shows count of compromised
+  // credentials.
+  test('showCompromisedPasswordsCount', async function() {
+    loadTimeData.overrideValues({passwordsWeaknessCheck: false});
+    const data = passwordManager.data;
+    data.leakedCredentials = [
+      makeCompromisedCredential('one.com', 'test4', 'LEAKED'),
+    ];
+
+    const section = createCheckPasswordSection();
+    await passwordManager.whenCalled('getPasswordCheckStatus');
+    flush();
+
+    const subtitle = section.$.subtitle;
+    assertTrue(isElementVisible(subtitle));
+
+    return PluralStringProxyImpl.getInstance()
+        .getPluralString('compromisedPasswords', 1)
+        .then(count => {
+          expectEquals(count, subtitle.textContent.trim());
+        });
+  });
+
   // When canceled, show string explaining that and already found leak
   // count.
   test('showProgressAndLeaksAfterCanceled', async function() {
diff --git a/chrome/test/data/webui/settings/passwords_and_autofill_fake_data.js b/chrome/test/data/webui/settings/passwords_and_autofill_fake_data.js
index 6bc9740..285279a 100644
--- a/chrome/test/data/webui/settings/passwords_and_autofill_fake_data.js
+++ b/chrome/test/data/webui/settings/passwords_and_autofill_fake_data.js
@@ -244,6 +244,26 @@
 }
 
 /**
+ * Creates a new insecure credential.
+ * @param {string} url
+ * @param {string} username
+ * @param {number=} id
+ * @return {chrome.passwordsPrivate.InsecureCredential}
+ * @private
+ */
+export function makeInsecureCredential(url, username, id) {
+  return {
+    id: id || 0,
+    formattedOrigin: url,
+    changePasswordUrl: `http://${url}/`,
+    username: username,
+    detailedOrigin: '',
+    isAndroidCredential: false,
+    signonRealm: '',
+  };
+}
+
+/**
  * Creates a new compromised credential.
  * @param {string} url
  * @param {string} username
@@ -255,20 +275,13 @@
  */
 export function makeCompromisedCredential(
     url, username, type, id, elapsedMinSinceCompromise) {
-  return {
-    id: id || 0,
-    formattedOrigin: url,
-    changePasswordUrl: `http://${url}/`,
-    username: username,
-    compromisedInfo: {
-      compromiseTime: Date.now() - (elapsedMinSinceCompromise * 60000),
-      elapsedTimeSinceCompromise: `${elapsedMinSinceCompromise} minutes ago`,
-      compromiseType: type,
-    },
-    detailedOrigin: '',
-    isAndroidCredential: false,
-    signonRealm: '',
+  const credential = makeInsecureCredential(url, username, id);
+  credential.compromisedInfo = {
+    compromiseTime: Date.now() - (elapsedMinSinceCompromise * 60000),
+    elapsedTimeSinceCompromise: `${elapsedMinSinceCompromise} minutes ago`,
+    compromiseType: type,
   };
+  return credential;
 }
 
 /**
diff --git a/chrome/test/data/webui/settings/test_password_manager_proxy.js b/chrome/test/data/webui/settings/test_password_manager_proxy.js
index 8b4655606..a2b25078 100644
--- a/chrome/test/data/webui/settings/test_password_manager_proxy.js
+++ b/chrome/test/data/webui/settings/test_password_manager_proxy.js
@@ -47,6 +47,7 @@
       'startBulkPasswordCheck',
       'stopBulkPasswordCheck',
       'getCompromisedCredentials',
+      'getWeakCredentials',
       'getPasswordCheckStatus',
       'getPlaintextInsecurePassword',
       'changeInsecureCredential',
@@ -70,6 +71,7 @@
       passwords: [],
       exceptions: [],
       leakedCredentials: [],
+      weakCredentials: [],
       checkStatus: makePasswordCheckStatus(),
     };
 
@@ -80,6 +82,7 @@
       addExceptionListChangedListener: null,
       requestPlaintextPassword: null,
       addCompromisedCredentialsListener: null,
+      addWeakCredentialsListener: null,
       addAccountStorageOptInStateListener: null,
     };
 
@@ -242,6 +245,12 @@
   }
 
   /** @override */
+  getWeakCredentials() {
+    this.methodCalled('getWeakCredentials');
+    return Promise.resolve(this.data.weakCredentials);
+  }
+
+  /** @override */
   getPasswordCheckStatus() {
     this.methodCalled('getPasswordCheckStatus');
     return Promise.resolve(this.data.checkStatus);
@@ -256,6 +265,14 @@
   removeCompromisedCredentialsListener(listener) {}
 
   /** @override */
+  addWeakCredentialsListener(listener) {
+    this.lastCallback.addWeakCredentialsListener = listener;
+  }
+
+  /** @override */
+  removeWeakCredentialsListener(listener) {}
+
+  /** @override */
   addPasswordCheckStatusListener(listener) {
     this.lastCallback.addPasswordCheckStatusListener = listener;
   }
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn
index bd07af4..28640aa4f 100644
--- a/chromecast/BUILD.gn
+++ b/chromecast/BUILD.gn
@@ -613,6 +613,7 @@
     "SUPPORTS_MULTIZONE=$supports_multizone",
     "USE_ANDROID_USER_AGENT=$use_android_user_agent",
     "USE_CHROMECAST_CDMS=$use_chromecast_cdms",
+    "ENABLE_CHROMIUM_RUNTIME_CAST_RENDERER=$enable_chromium_runtime_cast_renderer",
   ]
 }
 
diff --git a/chromecast/chromecast.gni b/chromecast/chromecast.gni
index ea3ff09..f4e1033 100644
--- a/chromecast/chromecast.gni
+++ b/chromecast/chromecast.gni
@@ -141,6 +141,9 @@
   # Set to true to forward crashes to the system's crash handler instead of
   # handling them internally.  This disables the built-in crash handler.
   use_system_crash_handler = false
+
+  # True to use the Chromium runtime for cast rendering.
+  enable_chromium_runtime_cast_renderer = false
 }
 
 declare_args() {
diff --git a/chromecast/media/audio/BUILD.gn b/chromecast/media/audio/BUILD.gn
index 762458c..eb0dcda 100644
--- a/chromecast/media/audio/BUILD.gn
+++ b/chromecast/media/audio/BUILD.gn
@@ -108,6 +108,7 @@
     "//chromecast/base",
     "//chromecast/common/mojom",
     "//chromecast/media/api",
+    "//chromecast/media/audio/capture_service:common",
     "//chromecast/media/audio/capture_service:receiver",
     "//chromecast/media/audio/capture_service:utils",
     "//chromecast/media/audio/mixer_service:common",
diff --git a/chromecast/media/audio/capture_service/capture_service_receiver.cc b/chromecast/media/audio/capture_service/capture_service_receiver.cc
index d47ced4..3d2f417 100644
--- a/chromecast/media/audio/capture_service/capture_service_receiver.cc
+++ b/chromecast/media/audio/capture_service/capture_service_receiver.cc
@@ -91,10 +91,8 @@
 
 bool CaptureServiceReceiver::Socket::SendRequest() {
   DCHECK_EQ(state_, State::kInit);
-  auto request_buffer = capture_service::MakeMessage(
-      capture_service::PacketInfo{capture_service::MessageType::kHandshake,
-                                  request_stream_info_, 0 /* timestamp_us */},
-      nullptr /* data */, 0 /* data_size */);
+  auto request_buffer =
+      capture_service::MakeHandshakeMessage(request_stream_info_);
   if (!request_buffer) {
     return false;
   }
@@ -157,9 +155,9 @@
 
 bool CaptureServiceReceiver::Socket::HandleAck(char* data, size_t size) {
   DCHECK_EQ(state_, State::kWaitForAck);
-  capture_service::PacketInfo info;
-  if (!capture_service::ReadHeader(data, size, &info) ||
-      !delegate_->OnInitialStreamInfo(info.stream_info)) {
+  capture_service::StreamInfo info;
+  if (!capture_service::ReadHandshakeMessage(data, size, &info) ||
+      !delegate_->OnInitialStreamInfo(info)) {
     ReportErrorAndStop();
     return false;
   }
diff --git a/chromecast/media/audio/capture_service/capture_service_receiver_unittest.cc b/chromecast/media/audio/capture_service/capture_service_receiver_unittest.cc
index 7c7e36a..0e47cc5 100644
--- a/chromecast/media/audio/capture_service/capture_service_receiver_unittest.cc
+++ b/chromecast/media/audio/capture_service/capture_service_receiver_unittest.cc
@@ -34,30 +34,18 @@
                SampleFormat::PLANAR_FLOAT,
                16000,
                160};
-constexpr PacketHeader kHandshakePacketHeader =
-    PacketHeader{0,
-                 static_cast<uint8_t>(MessageType::kHandshake),
-                 static_cast<uint8_t>(kStreamInfo.stream_type),
-                 static_cast<uint8_t>(kStreamInfo.audio_codec),
-                 kStreamInfo.num_channels,
-                 kStreamInfo.sample_rate,
-                 kStreamInfo.frames_per_buffer};
-constexpr PacketHeader kPcmAudioPacketHeader =
-    PacketHeader{0,
-                 static_cast<uint8_t>(MessageType::kPcmAudio),
-                 static_cast<uint8_t>(kStreamInfo.stream_type),
-                 static_cast<uint8_t>(kStreamInfo.sample_format),
-                 kStreamInfo.num_channels,
-                 kStreamInfo.sample_rate,
-                 0};
-
-void FillHeader(char* buf, uint16_t size, const PacketHeader& header) {
-  base::WriteBigEndian(buf, size);
-  memcpy(buf + sizeof(size),
-         reinterpret_cast<const char*>(&header) +
-             offsetof(struct PacketHeader, message_type),
-         sizeof(header) - offsetof(struct PacketHeader, message_type));
-}
+constexpr HandshakePacket kHandshakePacket =
+    HandshakePacket{0,
+                    static_cast<uint8_t>(MessageType::kHandshake),
+                    static_cast<uint8_t>(kStreamInfo.stream_type),
+                    static_cast<uint8_t>(kStreamInfo.audio_codec),
+                    static_cast<uint8_t>(kStreamInfo.sample_format),
+                    kStreamInfo.num_channels,
+                    kStreamInfo.frames_per_buffer,
+                    kStreamInfo.sample_rate};
+constexpr PcmPacketHeader kPcmAudioPacketHeader =
+    PcmPacketHeader{0, static_cast<uint8_t>(MessageType::kPcmAudio),
+                    static_cast<uint8_t>(kStreamInfo.stream_type), 0};
 
 class MockStreamSocket : public chromecast::MockStreamSocket {
  public:
@@ -95,7 +83,7 @@
   auto socket1 = std::make_unique<MockStreamSocket>();
   auto socket2 = std::make_unique<MockStreamSocket>();
   EXPECT_CALL(*socket1, Connect).WillOnce(Return(net::OK));
-  EXPECT_CALL(*socket1, Write).WillOnce(Return(16));
+  EXPECT_CALL(*socket1, Write).WillOnce(Return(sizeof(HandshakePacket)));
   EXPECT_CALL(*socket1, Read).WillOnce(Return(net::ERR_IO_PENDING));
   EXPECT_CALL(*socket2, Connect).WillOnce(Return(net::OK));
 
@@ -135,17 +123,19 @@
       .WillOnce(Invoke([](net::IOBuffer* buf, int buf_len,
                           net::CompletionOnceCallback,
                           const net::NetworkTrafficAnnotationTag&) {
-        EXPECT_EQ(buf_len, static_cast<int>(sizeof(PacketHeader)));
+        EXPECT_EQ(buf_len, static_cast<int>(sizeof(HandshakePacket)));
         const char* data = buf->data();
         uint16_t size;
         base::ReadBigEndian(data, &size);
-        EXPECT_EQ(size, sizeof(PacketHeader) - sizeof(size));
-        PacketHeader header;
-        std::memcpy(&header, data, sizeof(PacketHeader));
-        EXPECT_EQ(header.message_type, kHandshakePacketHeader.message_type);
-        EXPECT_EQ(header.stream_type, kHandshakePacketHeader.stream_type);
-        EXPECT_EQ(header.codec_or_sample_format,
-                  kHandshakePacketHeader.codec_or_sample_format);
+        EXPECT_EQ(size, sizeof(HandshakePacket) - sizeof(size));
+        HandshakePacket packet;
+        std::memcpy(&packet, data, sizeof(HandshakePacket));
+        EXPECT_EQ(packet.message_type, kHandshakePacket.message_type);
+        EXPECT_EQ(packet.stream_type, kHandshakePacket.stream_type);
+        EXPECT_EQ(packet.audio_codec, kHandshakePacket.audio_codec);
+        EXPECT_EQ(packet.num_channels, kHandshakePacket.num_channels);
+        EXPECT_EQ(packet.num_frames, kHandshakePacket.num_frames);
+        EXPECT_EQ(packet.sample_rate, kHandshakePacket.sample_rate);
         return buf_len;
       }));
   EXPECT_CALL(*socket, Read).WillOnce(Return(net::ERR_IO_PENDING));
@@ -161,26 +151,24 @@
 TEST_F(CaptureServiceReceiverTest, ReceivePcmAudioMessage) {
   auto socket = std::make_unique<MockStreamSocket>();
   EXPECT_CALL(*socket, Connect).WillOnce(Return(net::OK));
-  EXPECT_CALL(*socket, Write).WillOnce(Return(16));
+  EXPECT_CALL(*socket, Write).WillOnce(Return(sizeof(HandshakePacket)));
   EXPECT_CALL(*socket, Read)
       // Ack message.
       .WillOnce(Invoke(
           [](net::IOBuffer* buf, int buf_len, net::CompletionOnceCallback) {
-            int total_size = sizeof(PacketHeader);
+            int total_size = sizeof(HandshakePacket);
             EXPECT_GE(buf_len, total_size);
-            uint16_t size = total_size - sizeof(uint16_t);
-            PacketHeader header = kHandshakePacketHeader;
-            FillHeader(buf->data(), size, header);
+            FillBuffer(buf->data(), total_size, &kHandshakePacket.message_type,
+                       sizeof(HandshakePacket) - sizeof(uint16_t));
             return total_size;
           }))
       // Audio message.
       .WillOnce(Invoke([](net::IOBuffer* buf, int buf_len,
                           net::CompletionOnceCallback) {
-        int total_size = sizeof(PacketHeader) + DataSizeInBytes(kStreamInfo);
+        int total_size = sizeof(PcmPacketHeader) + DataSizeInBytes(kStreamInfo);
         EXPECT_GE(buf_len, total_size);
-        uint16_t size = total_size - sizeof(uint16_t);
-        PacketHeader header = kPcmAudioPacketHeader;
-        FillHeader(buf->data(), size, header);
+        FillBuffer(buf->data(), total_size, &kPcmAudioPacketHeader.message_type,
+                   sizeof(PcmPacketHeader) - sizeof(uint16_t));
         return total_size;  // No need to fill audio frames.
       }))
       .WillOnce(Return(net::ERR_IO_PENDING));
@@ -198,7 +186,7 @@
 TEST_F(CaptureServiceReceiverTest, ReceiveMetadataMessage) {
   auto socket = std::make_unique<MockStreamSocket>();
   EXPECT_CALL(*socket, Connect).WillOnce(Return(net::OK));
-  EXPECT_CALL(*socket, Write).WillOnce(Return(16));
+  EXPECT_CALL(*socket, Write).WillOnce(Return(sizeof(HandshakePacket)));
   EXPECT_CALL(*socket, Read)
       .WillOnce(Invoke(
           [](net::IOBuffer* buf, int buf_len, net::CompletionOnceCallback) {
@@ -223,7 +211,7 @@
 TEST_F(CaptureServiceReceiverTest, ReceiveError) {
   auto socket = std::make_unique<MockStreamSocket>();
   EXPECT_CALL(*socket, Connect).WillOnce(Return(net::OK));
-  EXPECT_CALL(*socket, Write).WillOnce(Return(16));
+  EXPECT_CALL(*socket, Write).WillOnce(Return(sizeof(HandshakePacket)));
   EXPECT_CALL(*socket, Read).WillOnce(Return(net::ERR_CONNECTION_RESET));
   EXPECT_CALL(delegate_, OnCaptureError);
 
@@ -234,7 +222,7 @@
 TEST_F(CaptureServiceReceiverTest, ReceiveEosMessage) {
   auto socket = std::make_unique<MockStreamSocket>();
   EXPECT_CALL(*socket, Connect).WillOnce(Return(net::OK));
-  EXPECT_CALL(*socket, Write).WillOnce(Return(16));
+  EXPECT_CALL(*socket, Write).WillOnce(Return(sizeof(HandshakePacket)));
   EXPECT_CALL(*socket, Read).WillOnce(Return(0));
   EXPECT_CALL(delegate_, OnCaptureError);
 
diff --git a/chromecast/media/audio/capture_service/constants.h b/chromecast/media/audio/capture_service/constants.h
index fc44325b..e87050bb0 100644
--- a/chromecast/media/audio/capture_service/constants.h
+++ b/chromecast/media/audio/capture_service/constants.h
@@ -78,20 +78,8 @@
   int frames_per_buffer = 0;
 };
 
-// Info describes the message packet. PacketInfo is only for message types that
-// support packet header, i.e., kHandshake and kPcmAudio. |timestamp_us| is
-// about when the buffer is captured. If the audio source is from ALSA, i.e.,
-// stream type is raw mic, it's the ALSA capture timestamp; otherwise, it may be
-// shifted based on the samples and sample rate upon raw mic input.
-struct PacketInfo {
-  MessageType message_type;
-  StreamInfo stream_info;
-  int64_t timestamp_us = 0;
-};
-
-// Size of a message header. The header can be parsed into PacketInfo with
-// methods in message_parsing_utils.h
-constexpr size_t kMessageHeaderBytes = 14;
+// Size of a PCM audio message header.
+constexpr size_t kPcmAudioHeaderBytes = 10;
 
 }  // namespace capture_service
 }  // namespace media
diff --git a/chromecast/media/audio/capture_service/message_parsing_fuzzer.cc b/chromecast/media/audio/capture_service/message_parsing_fuzzer.cc
index c21c697..f8ec5ce4 100644
--- a/chromecast/media/audio/capture_service/message_parsing_fuzzer.cc
+++ b/chromecast/media/audio/capture_service/message_parsing_fuzzer.cc
@@ -14,8 +14,8 @@
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   static Environment env;
-  PacketInfo info;
-  chromecast::media::capture_service::ReadHeader(
+  StreamInfo info;
+  chromecast::media::capture_service::ReadHandshakeMessage(
       reinterpret_cast<const char*>(data), size, &info);
   return 0;
 }
diff --git a/chromecast/media/audio/capture_service/message_parsing_utils.cc b/chromecast/media/audio/capture_service/message_parsing_utils.cc
index 57f148f..78d07de 100644
--- a/chromecast/media/audio/capture_service/message_parsing_utils.cc
+++ b/chromecast/media/audio/capture_service/message_parsing_utils.cc
@@ -10,6 +10,8 @@
 #include <limits>
 
 #include "base/big_endian.h"
+#include "base/check.h"
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/notreached.h"
 #include "chromecast/media/audio/capture_service/constants.h"
@@ -21,12 +23,18 @@
 namespace capture_service {
 namespace {
 
-// Size in bytes of the total message header.
-constexpr size_t kTotalHeaderBytes = kMessageHeaderBytes + sizeof(uint16_t);
+// Size in bytes of the header part of a handshake message.
+constexpr size_t kHandshakeHeaderBytes =
+    sizeof(HandshakePacket) - sizeof(uint16_t);
 
-static_assert(sizeof(PacketHeader) == kTotalHeaderBytes,
-              "Invalid packet header size.");
-static_assert(offsetof(struct PacketHeader, message_type) == sizeof(uint16_t),
+static_assert(kPcmAudioHeaderBytes ==
+                  sizeof(PcmPacketHeader) - sizeof(uint16_t),
+              "Invalid message header size.");
+static_assert(offsetof(struct PcmPacketHeader, message_type) ==
+                  sizeof(uint16_t),
+              "Invalid message header offset.");
+static_assert(offsetof(struct HandshakePacket, message_type) ==
+                  sizeof(uint16_t),
               "Invalid message header offset.");
 
 // Check if audio data is properly aligned and has valid frame size. Return the
@@ -141,110 +149,97 @@
   return false;
 }
 
-bool HasPacketHeader(MessageType type) {
-  // Packet header is only for the messages generated from packet info. For
-  // other message type such as kOpusAudio and kMetadata, the packet does not
-  // contain the packet header and only contains the message type and serialized
-  // data.
-  return type == MessageType::kHandshake || type == MessageType::kPcmAudio;
-}
-
 }  // namespace
 
-char* PopulateHeader(char* data, size_t size, const PacketInfo& packet_info) {
-  DCHECK(HasPacketHeader(packet_info.message_type));
-  const StreamInfo& stream_info = packet_info.stream_info;
-  PacketHeader header;
-  header.message_type = static_cast<uint8_t>(packet_info.message_type);
-  header.stream_type = static_cast<uint8_t>(stream_info.stream_type);
-  header.num_channels = stream_info.num_channels;
-  header.sample_rate = stream_info.sample_rate;
-  // In request/ack message, the header contains a codec field and a
-  // frames_per_buffer field, while in PCM audio message, it instead contains a
-  // sample format field and a timestamp field.
-  if (packet_info.message_type == MessageType::kHandshake) {
-    header.codec_or_sample_format =
-        static_cast<uint8_t>(stream_info.audio_codec);
-    header.timestamp_or_frames = stream_info.frames_per_buffer;
-  } else if (packet_info.message_type == MessageType::kPcmAudio) {
-    header.codec_or_sample_format =
-        static_cast<uint8_t>(stream_info.sample_format);
-    header.timestamp_or_frames = packet_info.timestamp_us;
-  } else {
-    NOTREACHED();
-  }
+void FillBuffer(char* buf,
+                size_t buf_size,
+                const void* data,
+                size_t data_size) {
+  DCHECK_LE(data_size, buf_size - sizeof(uint16_t));
   base::WriteBigEndian(  // Deduct the size of |size| itself.
-      data, static_cast<uint16_t>(size - sizeof(uint16_t)));
-  DCHECK_EQ(sizeof(header), kTotalHeaderBytes);
-  memcpy(data + sizeof(uint16_t), &header.message_type, kMessageHeaderBytes);
-  return data + kTotalHeaderBytes;
+      buf, static_cast<uint16_t>(buf_size - sizeof(uint16_t)));
+  memcpy(buf + sizeof(uint16_t), data, data_size);
 }
 
-bool ReadHeader(const char* data, size_t size, PacketInfo* packet_info) {
-  DCHECK(packet_info);
-  if (size < kMessageHeaderBytes) {
-    LOG(ERROR) << "Message doesn't have a complete header.";
+char* PopulatePcmAudioHeader(char* data,
+                             size_t size,
+                             StreamType stream_type,
+                             int64_t timestamp_us) {
+  PcmPacketHeader header;
+  header.message_type = static_cast<uint8_t>(MessageType::kPcmAudio);
+  header.stream_type = static_cast<uint8_t>(stream_type);
+  header.timestamp_us = timestamp_us;
+  FillBuffer(data, size, &header.message_type,
+             sizeof(header) - sizeof(uint16_t));
+  return data + sizeof(header);
+}
+
+void PopulateHandshakeMessage(char* data,
+                              size_t size,
+                              const StreamInfo& stream_info) {
+  HandshakePacket packet;
+  packet.message_type = static_cast<uint8_t>(MessageType::kHandshake);
+  packet.stream_type = static_cast<uint8_t>(stream_info.stream_type);
+  packet.audio_codec = static_cast<uint8_t>(stream_info.audio_codec);
+  packet.sample_format = static_cast<uint8_t>(stream_info.sample_format);
+  packet.num_channels = stream_info.num_channels;
+  packet.num_frames = stream_info.frames_per_buffer;
+  packet.sample_rate = stream_info.sample_rate;
+  FillBuffer(data, size, &packet.message_type,
+             sizeof(packet) - sizeof(uint16_t));
+}
+
+bool ReadPcmAudioHeader(const char* data,
+                        size_t size,
+                        const StreamInfo& stream_info,
+                        int64_t* timestamp_us) {
+  DCHECK(timestamp_us);
+  if (size < kPcmAudioHeaderBytes) {
+    LOG(ERROR) << "Message doesn't have a complete header: " << size << " v.s. "
+               << kPcmAudioHeaderBytes << ".";
     return false;
   }
-  PacketHeader header;
-  memcpy(&header.message_type, data, kMessageHeaderBytes);
-  MessageType message_type = static_cast<MessageType>(header.message_type);
-  uint8_t last_codec_or_sample_format =
-      (message_type == MessageType::kHandshake)
-          ? static_cast<uint8_t>(AudioCodec::kLastCodec)
-          : static_cast<uint8_t>(SampleFormat::LAST_FORMAT);
-  if (!HasPacketHeader(message_type) ||
-      header.stream_type > static_cast<uint8_t>(StreamType::kLastType) ||
-      header.codec_or_sample_format > last_codec_or_sample_format) {
-    LOG(ERROR) << "Invalid message header.";
+  PcmPacketHeader header;
+  memcpy(&header.message_type, data, kPcmAudioHeaderBytes);
+  if (static_cast<MessageType>(header.message_type) != MessageType::kPcmAudio) {
+    LOG(ERROR) << "Message type mismatch.";
     return false;
   }
-  if (header.num_channels > ::media::limits::kMaxChannels) {
-    LOG(ERROR) << "Invalid number of channels: " << header.num_channels;
+  if (static_cast<StreamType>(header.stream_type) != stream_info.stream_type) {
+    LOG(ERROR) << "Stream type mistach.";
     return false;
   }
-  packet_info->message_type = message_type;
-  packet_info->stream_info.stream_type =
-      static_cast<StreamType>(header.stream_type);
-  packet_info->stream_info.num_channels = header.num_channels;
-  packet_info->stream_info.sample_rate = header.sample_rate;
-  if (message_type == MessageType::kHandshake) {
-    packet_info->stream_info.audio_codec =
-        static_cast<AudioCodec>(header.codec_or_sample_format);
-    packet_info->stream_info.frames_per_buffer = header.timestamp_or_frames;
-  } else if (message_type == MessageType::kPcmAudio) {
-    packet_info->stream_info.sample_format =
-        static_cast<SampleFormat>(header.codec_or_sample_format);
-    packet_info->timestamp_us = header.timestamp_or_frames;
-  } else {
-    NOTREACHED();
-  }
+  *timestamp_us = header.timestamp_us;
   return true;
 }
 
-scoped_refptr<net::IOBufferWithSize> MakeMessage(const PacketInfo& packet_info,
-                                                 const char* data,
-                                                 size_t data_size) {
-  if (!HasPacketHeader(packet_info.message_type)) {
-    LOG(ERROR)
-        << "Only kHandshake and kPcmAudio message have packet header, use "
-           "MakeSerializedMessage otherwise.";
-    return nullptr;
-  }
-  const size_t total_size = kTotalHeaderBytes + data_size;
+scoped_refptr<net::IOBufferWithSize> MakePcmAudioMessage(StreamType stream_type,
+                                                         int64_t timestamp_us,
+                                                         const char* data,
+                                                         size_t data_size) {
+  const size_t total_size = sizeof(PcmPacketHeader) + data_size;
   DCHECK_LE(total_size, std::numeric_limits<uint16_t>::max());
   auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(total_size);
-  char* ptr = PopulateHeader(io_buffer->data(), io_buffer->size(), packet_info);
+  char* ptr = PopulatePcmAudioHeader(io_buffer->data(), io_buffer->size(),
+                                     stream_type, timestamp_us);
   if (!ptr) {
     return nullptr;
   }
-  if (packet_info.message_type == MessageType::kPcmAudio && data_size > 0) {
+  if (data_size > 0) {
     DCHECK(data);
     std::copy(data, data + data_size, ptr);
   }
   return io_buffer;
 }
 
+scoped_refptr<net::IOBufferWithSize> MakeHandshakeMessage(
+    const StreamInfo& stream_info) {
+  auto io_buffer =
+      base::MakeRefCounted<net::IOBufferWithSize>(sizeof(HandshakePacket));
+  PopulateHandshakeMessage(io_buffer->data(), io_buffer->size(), stream_info);
+  return io_buffer;
+}
+
 scoped_refptr<net::IOBufferWithSize> MakeSerializedMessage(
     MessageType message_type,
     const char* data,
@@ -278,22 +273,51 @@
   DCHECK(audio_bus);
   DCHECK_EQ(stream_info.num_channels, audio_bus->channels());
   return ConvertData(stream_info.num_channels, stream_info.sample_format,
-                     data + kMessageHeaderBytes, size - kMessageHeaderBytes,
+                     data + kPcmAudioHeaderBytes, size - kPcmAudioHeaderBytes,
                      audio_bus);
 }
 
 bool ReadPcmAudioMessage(const char* data,
                          size_t size,
-                         PacketInfo* packet_info,
+                         const StreamInfo& stream_info,
+                         int64_t* timestamp_us,
                          ::media::AudioBus* audio_bus) {
-  if (!ReadHeader(data, size, packet_info)) {
+  if (!ReadPcmAudioHeader(data, size, stream_info, timestamp_us)) {
     return false;
   }
-  if (packet_info->message_type != MessageType::kPcmAudio) {
-    LOG(WARNING) << "Received non-pcm-audio message.";
+  return ReadDataToAudioBus(stream_info, data, size, audio_bus);
+}
+
+bool ReadHandshakeMessage(const char* data,
+                          size_t size,
+                          StreamInfo* stream_info) {
+  DCHECK(stream_info);
+  if (size != kHandshakeHeaderBytes) {
+    LOG(ERROR) << "Message doesn't have a complete handshake packet: " << size
+               << " v.s. " << kHandshakeHeaderBytes << ".";
     return false;
   }
-  return ReadDataToAudioBus(packet_info->stream_info, data, size, audio_bus);
+  HandshakePacket packet;
+  memcpy(&packet.message_type, data, kHandshakeHeaderBytes);
+  MessageType message_type = static_cast<MessageType>(packet.message_type);
+  if (message_type != MessageType::kHandshake ||
+      packet.stream_type > static_cast<uint8_t>(StreamType::kLastType) ||
+      packet.audio_codec > static_cast<uint8_t>(AudioCodec::kLastCodec) ||
+      packet.sample_format > static_cast<uint8_t>(SampleFormat::LAST_FORMAT)) {
+    LOG(ERROR) << "Invalid message header.";
+    return false;
+  }
+  if (packet.num_channels > ::media::limits::kMaxChannels) {
+    LOG(ERROR) << "Invalid number of channels: " << packet.num_channels;
+    return false;
+  }
+  stream_info->stream_type = static_cast<StreamType>(packet.stream_type);
+  stream_info->audio_codec = static_cast<AudioCodec>(packet.audio_codec);
+  stream_info->sample_format = static_cast<SampleFormat>(packet.sample_format);
+  stream_info->num_channels = packet.num_channels;
+  stream_info->frames_per_buffer = packet.num_frames;
+  stream_info->sample_rate = packet.sample_rate;
+  return true;
 }
 
 size_t DataSizeInBytes(const StreamInfo& stream_info) {
diff --git a/chromecast/media/audio/capture_service/message_parsing_utils.h b/chromecast/media/audio/capture_service/message_parsing_utils.h
index 9140b42..3aef84f 100644
--- a/chromecast/media/audio/capture_service/message_parsing_utils.h
+++ b/chromecast/media/audio/capture_service/message_parsing_utils.h
@@ -16,31 +16,33 @@
 namespace media {
 namespace capture_service {
 
-// Read message header to |packet_info|, and return whether success.
-// The header of the message consists of <uint8_t message_type>
-// <uint8_t stream_type> <uint8_t audio_codec|sample_format> <uint8_t channels>
-// <uint16_t sample_rate> <uint64_t frames_per_buffer|timestamp_us>.
-// If |message_type| is kHandshake, it is a handshake message that has
-// |audio_codec| and |frames_per_buffer|, otherwise if |message_type| is
-// kPcmAudio, it's a PCM audio data message that has |sample_format| and
-// |timestamp_us|. Note it cannot be used to read kOpusAudio or kMetadata
-// messages, which don't have header besides |message_type| bits. Note
-// |packet_info| will be untouched if fails to read header. Note unsigned
-// |timestamp_us| will be converted to signed |timestamp| if valid. Note |data|
-// here has been parsed firstly by SmallMessageSocket, and thus doesn't have
-// <uint16_t size> bits.
-bool ReadHeader(const char* data, size_t size, PacketInfo* packet_info);
+// Read message header, check if it matches |stream_info|, retrieve timestamp,
+// and return whether success.
+// Note |data| here has been parsed firstly by SmallMessageSocket, and thus
+// doesn't have <uint16_t size> bits.
+bool ReadPcmAudioHeader(const char* data,
+                        size_t size,
+                        const StreamInfo& stream_info,
+                        int64_t* timestamp_us);
 
-// Make a IO buffer for stream message. It will populate the header with
-// |packet_info|, and copy |data| into the message if packet has audio and
-// |data| is not null. The returned buffer will have a length of |data_size| +
-// header size. Return nullptr if fails. Caller must guarantee the memory of
-// |data| has at least |data_size| when has audio.
+// Make a IO buffer for stream message. It will populate the header and copy
+// |data| into the message if packet has audio and |data| is not null. The
+// returned buffer will have a length of |data_size| + header size. Return
+// nullptr if fails. Caller must guarantee the memory of |data| has at least
+// |data_size| when has audio.
 // Note buffer will be sent with SmallMessageSocket, and thus contains a uint16
 // size field in the very first.
-scoped_refptr<net::IOBufferWithSize> MakeMessage(const PacketInfo& packet_info,
-                                                 const char* data,
-                                                 size_t data_size);
+scoped_refptr<net::IOBufferWithSize> MakePcmAudioMessage(StreamType stream_type,
+                                                         int64_t timestamp_us,
+                                                         const char* data,
+                                                         size_t data_size);
+
+// Make a IO buffer for handshake message. It will populate the header with
+// |stream_info|. Return nullptr if fails.
+// Note buffer will be sent with SmallMessageSocket, and thus contains a uint16
+// size field in the very first.
+scoped_refptr<net::IOBufferWithSize> MakeHandshakeMessage(
+    const StreamInfo& stream_info);
 
 // Make a IO buffer for serialized message. It will populate message size and
 // type fields, and copy |data| into the message. The returned buffer will have
@@ -60,21 +62,43 @@
                         size_t size,
                         ::media::AudioBus* audio_bus);
 
-// Read the header part of the PCM audio message to packet info and the audio
-// data part to audio bus, and return whether success. This will run
-// ReadHeader() and ReadDataToAudioBus() in the underlying implementation.
+// Read the PCM audio message and copy the audio data to audio bus, as well as
+// the timestamp. Return whether success. This will run ReadPcmAudioHeader() and
+// ReadDataToAudioBus() in the underlying implementation.
 bool ReadPcmAudioMessage(const char* data,
                          size_t size,
-                         PacketInfo* packet_info,
+                         const StreamInfo& stream_info,
+                         int64_t* timestamp_us,
                          ::media::AudioBus* audio_bus);
 
-// Populate header of the message, including the SmallMessageSocket size bits.
-// Note this is used by unittest, user should use MakeMessage directly.
-char* PopulateHeader(char* data, size_t size, const PacketInfo& stream_info);
+// Read the handshake message to |stream_info|, and return true on success.
+bool ReadHandshakeMessage(const char* data,
+                          size_t size,
+                          StreamInfo* stream_info);
 
 // Return the expected size of the data of a stream message with |stream_info|.
 size_t DataSizeInBytes(const StreamInfo& stream_info);
 
+// Following methods are exposed for unittests:
+
+// Write |buf_size|, in big-endian order, to |buf|, and fill |data| to |buf|
+// afterward.
+void FillBuffer(char* buf, size_t buf_size, const void* data, size_t data_size);
+
+// Populate header of the PCM audio message, including the SmallMessageSocket
+// size bits.
+// Note this is used by unittest, user should use MakePcmAudioMessage directly.
+char* PopulatePcmAudioHeader(char* data,
+                             size_t size,
+                             StreamType stream_type,
+                             int64_t timestamp_us);
+
+// Populate the handshake message, including the SmallMessageSocket size bits.
+// Note this is used by unittest, user should use MakeHandshakeMessage directly.
+void PopulateHandshakeMessage(char* data,
+                              size_t size,
+                              const StreamInfo& stream_info);
+
 }  // namespace capture_service
 }  // namespace media
 }  // namespace chromecast
diff --git a/chromecast/media/audio/capture_service/message_parsing_utils_unittest.cc b/chromecast/media/audio/capture_service/message_parsing_utils_unittest.cc
index 8ed8fa7..ed6feafe 100644
--- a/chromecast/media/audio/capture_service/message_parsing_utils_unittest.cc
+++ b/chromecast/media/audio/capture_service/message_parsing_utils_unittest.cc
@@ -16,7 +16,6 @@
 namespace capture_service {
 namespace {
 
-constexpr size_t kTotalHeaderBytes = 16;
 constexpr size_t kFrames = 10;
 constexpr size_t kChannels = 2;
 constexpr StreamInfo kStreamInfo =
@@ -26,37 +25,72 @@
                SampleFormat::PLANAR_FLOAT,
                16000,
                kFrames};
-constexpr PacketInfo kHandshakePacketInfo = {MessageType::kHandshake,
-                                             kStreamInfo, 0};
-constexpr PacketInfo kPcmAudioPacketInfo = {MessageType::kPcmAudio, kStreamInfo,
-                                            0};
+
+class PacketHeaderTest
+    : public testing::TestWithParam<
+          std::tuple<StreamType, AudioCodec, int, SampleFormat, int, int>> {
+ protected:
+  StreamInfo GetStreamInfo() {
+    StreamInfo info;
+    info.stream_type = std::get<0>(GetParam());
+    info.audio_codec = std::get<1>(GetParam());
+    info.num_channels = std::get<2>(GetParam());
+    info.sample_format = std::get<3>(GetParam());
+    info.sample_rate = std::get<4>(GetParam());
+    info.frames_per_buffer = std::get<5>(GetParam());
+    return info;
+  }
+};
+
+TEST_P(PacketHeaderTest, HandshakeMessage) {
+  std::vector<char> data(sizeof(HandshakePacket), 0);
+  StreamInfo stream_info = GetStreamInfo();
+  PopulateHandshakeMessage(data.data(), data.size(), stream_info);
+
+  StreamInfo info_out;
+  bool success =
+      ReadHandshakeMessage(data.data() + sizeof(uint16_t),
+                           data.size() - sizeof(uint16_t), &info_out);
+  EXPECT_TRUE(success);
+  EXPECT_EQ(info_out.stream_type, stream_info.stream_type);
+  EXPECT_EQ(info_out.audio_codec, stream_info.audio_codec);
+  EXPECT_EQ(info_out.sample_format, stream_info.sample_format);
+  EXPECT_EQ(info_out.num_channels, stream_info.num_channels);
+  EXPECT_EQ(info_out.sample_rate, stream_info.sample_rate);
+  EXPECT_EQ(info_out.frames_per_buffer, stream_info.frames_per_buffer);
+}
+
+TEST(MessageParsingUtilsTest, PcmAudioMessage) {
+  size_t data_size = sizeof(PcmPacketHeader) / sizeof(float);
+  std::vector<float> data(data_size, 1.0f);
+  int64_t timestamp_us = 100;
+  PopulatePcmAudioHeader(reinterpret_cast<char*>(data.data()),
+                         data.size() * sizeof(float), kStreamInfo.stream_type,
+                         timestamp_us);
+
+  int64_t timestamp_out = 0;
+  bool success = ReadPcmAudioHeader(
+      reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
+      data_size * sizeof(float) - sizeof(uint16_t), kStreamInfo,
+      &timestamp_out);
+  EXPECT_TRUE(success);
+  EXPECT_EQ(timestamp_out, timestamp_us);
+}
 
 TEST(MessageParsingUtilsTest, ValidPlanarFloat) {
-  size_t data_size = kTotalHeaderBytes / sizeof(float) + kFrames * kChannels;
+  size_t data_size =
+      sizeof(PcmPacketHeader) / sizeof(float) + kFrames * kChannels;
   std::vector<float> data(data_size, .0f);
-  PopulateHeader(reinterpret_cast<char*>(data.data()),
-                 data.size() * sizeof(float), kPcmAudioPacketInfo);
+  PopulatePcmAudioHeader(reinterpret_cast<char*>(data.data()),
+                         data.size() * sizeof(float), kStreamInfo.stream_type,
+                         0);
   // Fill the last k frames, i.e., the second channel, with 0.5f.
   for (size_t i = data_size - kFrames; i < data_size; i++) {
     data[i] = .5f;
   }
 
-  // Audio header.
-  PacketInfo info;
-  bool success =
-      ReadHeader(reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
-                 data_size * sizeof(float) - sizeof(uint16_t), &info);
-  EXPECT_TRUE(success);
-  EXPECT_EQ(info.message_type, kPcmAudioPacketInfo.message_type);
-  EXPECT_EQ(info.stream_info.stream_type, kStreamInfo.stream_type);
-  EXPECT_EQ(info.stream_info.num_channels, kStreamInfo.num_channels);
-  EXPECT_EQ(info.stream_info.sample_format, kStreamInfo.sample_format);
-  EXPECT_EQ(info.stream_info.sample_rate, kStreamInfo.sample_rate);
-  EXPECT_EQ(info.timestamp_us, kPcmAudioPacketInfo.timestamp_us);
-
-  // Audio data.
   auto audio_bus = ::media::AudioBus::Create(kChannels, kFrames);
-  success = ReadDataToAudioBus(
+  bool success = ReadDataToAudioBus(
       kStreamInfo, reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
       data_size * sizeof(float) - sizeof(uint16_t), audio_bus.get());
   EXPECT_TRUE(success);
@@ -67,22 +101,23 @@
 }
 
 TEST(MessageParsingUtilsTest, ValidInterleavedInt16) {
-  size_t data_size = kTotalHeaderBytes / sizeof(int16_t) + kFrames * kChannels;
+  size_t data_size =
+      sizeof(PcmPacketHeader) / sizeof(int16_t) + kFrames * kChannels;
   std::vector<int16_t> data(data_size, std::numeric_limits<int16_t>::max());
-  PacketInfo packet_info = kPcmAudioPacketInfo;
-  packet_info.stream_info.sample_format = SampleFormat::INTERLEAVED_INT16;
-  PopulateHeader(reinterpret_cast<char*>(data.data()),
-                 data.size() * sizeof(int16_t), packet_info);
+  PopulatePcmAudioHeader(reinterpret_cast<char*>(data.data()),
+                         data.size() * sizeof(int16_t), kStreamInfo.stream_type,
+                         0);
   // Fill the second channel with min().
-  for (size_t i = kTotalHeaderBytes / sizeof(int16_t) + 1; i < data_size;
+  for (size_t i = sizeof(PcmPacketHeader) / sizeof(int16_t) + 1; i < data_size;
        i += 2) {
     data[i] = std::numeric_limits<int16_t>::min();
   }
 
   auto audio_bus = ::media::AudioBus::Create(kChannels, kFrames);
+  StreamInfo stream_info = kStreamInfo;
+  stream_info.sample_format = SampleFormat::INTERLEAVED_INT16;
   bool success = ReadDataToAudioBus(
-      packet_info.stream_info,
-      reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
+      stream_info, reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
       data_size * sizeof(int16_t) - sizeof(uint16_t), audio_bus.get());
   EXPECT_TRUE(success);
   for (size_t f = 0; f < kFrames; f++) {
@@ -92,22 +127,23 @@
 }
 
 TEST(MessageParsingUtilsTest, ValidInterleavedInt32) {
-  size_t data_size = kTotalHeaderBytes / sizeof(int32_t) + kFrames * kChannels;
+  size_t data_size =
+      sizeof(PcmPacketHeader) / sizeof(int32_t) + kFrames * kChannels;
   std::vector<int32_t> data(data_size, std::numeric_limits<int32_t>::min());
-  PacketInfo packet_info = kPcmAudioPacketInfo;
-  packet_info.stream_info.sample_format = SampleFormat::INTERLEAVED_INT32;
-  PopulateHeader(reinterpret_cast<char*>(data.data()),
-                 data.size() * sizeof(int32_t), packet_info);
+  PopulatePcmAudioHeader(reinterpret_cast<char*>(data.data()),
+                         data.size() * sizeof(int32_t), kStreamInfo.stream_type,
+                         0);
   // Fill the second channel with max().
-  for (size_t i = kTotalHeaderBytes / sizeof(int32_t) + 1; i < data_size;
+  for (size_t i = sizeof(PcmPacketHeader) / sizeof(int32_t) + 1; i < data_size;
        i += 2) {
     data[i] = std::numeric_limits<int32_t>::max();
   }
 
   auto audio_bus = ::media::AudioBus::Create(kChannels, kFrames);
+  StreamInfo stream_info = kStreamInfo;
+  stream_info.sample_format = SampleFormat::INTERLEAVED_INT32;
   bool success = ReadDataToAudioBus(
-      packet_info.stream_info,
-      reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
+      stream_info, reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
       data_size * sizeof(int32_t) - sizeof(uint16_t), audio_bus.get());
   EXPECT_TRUE(success);
   for (size_t f = 0; f < kFrames; f++) {
@@ -116,92 +152,68 @@
   }
 }
 
-TEST(MessageParsingUtilsTest, InvalidType) {
-  size_t data_size = kTotalHeaderBytes / sizeof(float);
-  std::vector<float> data(data_size, 1.0f);
-  // Request packet
-  PacketInfo request_packet_info = kHandshakePacketInfo;
-  PopulateHeader(reinterpret_cast<char*>(data.data()),
-                 data.size() * sizeof(float), request_packet_info);
+TEST(MessageParsingUtilsTest, InvalidTypeHandshake) {
+  std::vector<char> data(sizeof(HandshakePacket), 0);
+  StreamInfo stream_info = kStreamInfo;
+  PopulateHandshakeMessage(data.data(), data.size(), stream_info);
   *(reinterpret_cast<uint8_t*>(data.data()) +
-    offsetof(struct PacketHeader, stream_type)) =
+    offsetof(struct HandshakePacket, stream_type)) =
       static_cast<uint8_t>(StreamType::kLastType) + 1;
-  bool success = ReadHeader(
-      reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
-      data_size * sizeof(float) - sizeof(uint16_t), &request_packet_info);
+  bool success =
+      ReadHandshakeMessage(data.data() + sizeof(uint16_t),
+                           data.size() - sizeof(uint16_t), &stream_info);
   EXPECT_FALSE(success);
+}
 
-  // PCM audio packet
-  PacketInfo pcm_audio_packet_info = kPcmAudioPacketInfo;
-  PopulateHeader(reinterpret_cast<char*>(data.data()),
-                 data.size() * sizeof(float), pcm_audio_packet_info);
+TEST(MessageParsingUtilsTest, InvalidTypePcmAudio) {
+  size_t data_size = sizeof(PcmPacketHeader) / sizeof(float);
+  std::vector<float> data(data_size, 1.0f);
+  PopulatePcmAudioHeader(reinterpret_cast<char*>(data.data()),
+                         data.size() * sizeof(float), kStreamInfo.stream_type,
+                         0);
   *(reinterpret_cast<uint8_t*>(data.data()) +
-    offsetof(struct PacketHeader, stream_type)) =
+    offsetof(struct PcmPacketHeader, stream_type)) =
       static_cast<uint8_t>(StreamType::kLastType) + 1;
-  success = ReadHeader(reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
-                       data_size * sizeof(float) - sizeof(uint16_t),
-                       &pcm_audio_packet_info);
+  int64_t timestamp_us;
+  bool success = ReadPcmAudioHeader(
+      reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
+      data_size * sizeof(float) - sizeof(uint16_t), kStreamInfo, &timestamp_us);
   EXPECT_FALSE(success);
 }
 
 TEST(MessageParsingUtilsTest, InvalidCodec) {
-  size_t data_size = kTotalHeaderBytes / sizeof(float);
-  std::vector<float> data(data_size, 1.0f);
-  PacketInfo packet_info = kHandshakePacketInfo;
-  PopulateHeader(reinterpret_cast<char*>(data.data()),
-                 data.size() * sizeof(float), packet_info);
+  std::vector<char> data(sizeof(HandshakePacket), 0);
+  StreamInfo stream_info = kStreamInfo;
+  PopulateHandshakeMessage(data.data(), data.size(), stream_info);
   *(reinterpret_cast<uint8_t*>(data.data()) +
-    offsetof(struct PacketHeader, codec_or_sample_format)) =
+    offsetof(struct HandshakePacket, audio_codec)) =
       static_cast<uint8_t>(AudioCodec::kLastCodec) + 1;
-
   bool success =
-      ReadHeader(reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
-                 data_size * sizeof(float) - sizeof(uint16_t), &packet_info);
+      ReadHandshakeMessage(data.data() + sizeof(uint16_t),
+                           data.size() - sizeof(uint16_t), &stream_info);
   EXPECT_FALSE(success);
 }
 
 TEST(MessageParsingUtilsTest, InvalidFormat) {
-  size_t data_size = kTotalHeaderBytes / sizeof(float);
-  std::vector<float> data(data_size, 1.0f);
-  PacketInfo packet_info = kPcmAudioPacketInfo;
-  PopulateHeader(reinterpret_cast<char*>(data.data()),
-                 data.size() * sizeof(float), packet_info);
+  std::vector<char> data(sizeof(HandshakePacket), 0);
+  StreamInfo stream_info = kStreamInfo;
+  PopulateHandshakeMessage(data.data(), data.size(), stream_info);
   *(reinterpret_cast<uint8_t*>(data.data()) +
-    offsetof(struct PacketHeader, codec_or_sample_format)) =
+    offsetof(struct HandshakePacket, sample_format)) =
       static_cast<uint8_t>(SampleFormat::LAST_FORMAT) + 1;
-
   bool success =
-      ReadHeader(reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
-                 data_size * sizeof(float) - sizeof(uint16_t), &packet_info);
+      ReadHandshakeMessage(data.data() + sizeof(uint16_t),
+                           data.size() - sizeof(uint16_t), &stream_info);
   EXPECT_FALSE(success);
 }
 
-TEST(MessageParsingUtilsTest, RequestMessage) {
-  size_t data_size = kTotalHeaderBytes / sizeof(float);
-  std::vector<float> data(data_size, 1.0f);
-  PacketInfo packet_info = kHandshakePacketInfo;
-  PopulateHeader(reinterpret_cast<char*>(data.data()),
-                 data.size() * sizeof(float), packet_info);
-
-  PacketInfo info;
-  bool success =
-      ReadHeader(reinterpret_cast<char*>(data.data()) + sizeof(uint16_t),
-                 data_size * sizeof(float) - sizeof(uint16_t), &info);
-  EXPECT_TRUE(success);
-  EXPECT_EQ(info.message_type, kHandshakePacketInfo.message_type);
-  EXPECT_EQ(info.stream_info.stream_type, kStreamInfo.stream_type);
-  EXPECT_EQ(info.stream_info.audio_codec, kStreamInfo.audio_codec);
-  EXPECT_EQ(info.stream_info.num_channels, kStreamInfo.num_channels);
-  EXPECT_EQ(info.stream_info.sample_rate, kStreamInfo.sample_rate);
-  EXPECT_EQ(info.stream_info.frames_per_buffer, kStreamInfo.frames_per_buffer);
-}
-
 TEST(MessageParsingUtilsTest, InvalidDataLength) {
   size_t data_size =
-      kTotalHeaderBytes / sizeof(float) + kFrames * kChannels + 1;
+      sizeof(PcmPacketHeader) / sizeof(float) + kFrames * kChannels + 1;
   std::vector<float> data(data_size, 1.0f);
-  PopulateHeader(reinterpret_cast<char*>(data.data()),
-                 data.size() * sizeof(float), kPcmAudioPacketInfo);
+  PopulatePcmAudioHeader(reinterpret_cast<char*>(data.data()),
+                         data.size() * sizeof(float), kStreamInfo.stream_type,
+                         0);
 
   auto audio_bus = ::media::AudioBus::Create(kChannels, kFrames);
   bool success = ReadDataToAudioBus(
@@ -212,10 +224,11 @@
 
 TEST(MessageParsingUtilsTest, NotAlignedData) {
   size_t data_size =
-      kTotalHeaderBytes / sizeof(float) + kFrames * kChannels + 1;
+      sizeof(PcmPacketHeader) / sizeof(float) + kFrames * kChannels + 1;
   std::vector<float> data(data_size, 1.0f);
-  PopulateHeader(reinterpret_cast<char*>(data.data()) + 1,
-                 data.size() * sizeof(float) - 1, kPcmAudioPacketInfo);
+  PopulatePcmAudioHeader(reinterpret_cast<char*>(data.data()) + 1,
+                         data.size() * sizeof(float) - 1,
+                         kStreamInfo.stream_type, 0);
 
   auto audio_bus = ::media::AudioBus::Create(kChannels, kFrames);
   bool success = ReadDataToAudioBus(
@@ -224,6 +237,18 @@
   EXPECT_FALSE(success);
 }
 
+INSTANTIATE_TEST_SUITE_P(
+    MessageParsingUtilsTest,
+    PacketHeaderTest,
+    testing::Combine(testing::Values(StreamType::kMicRaw,
+                                     StreamType::kHardwareEchoRescaled),
+                     testing::Values(AudioCodec::kPcm, AudioCodec::kOpus),
+                     testing::Values(1, 8),
+                     testing::Values(SampleFormat::INTERLEAVED_INT16,
+                                     SampleFormat::PLANAR_FLOAT),
+                     testing::Values(16000, 96000),
+                     testing::Values(0, 32761)));
+
 }  // namespace
 }  // namespace capture_service
 }  // namespace media
diff --git a/chromecast/media/audio/capture_service/packet_header.h b/chromecast/media/audio/capture_service/packet_header.h
index dee72c9..2f5b6ec 100644
--- a/chromecast/media/audio/capture_service/packet_header.h
+++ b/chromecast/media/audio/capture_service/packet_header.h
@@ -11,19 +11,29 @@
 namespace media {
 namespace capture_service {
 
-// Memory block of a packet header. Changes to it need to make sure about the
-// memory alignment to avoid extra paddings being inserted. It reflects real
-// packet header structure, however, the |size| bits are in big-endian order,
-// and thus is only for padding purpose in this struct, when all bytes after it
-// represent a message header.
-struct __attribute__((__packed__)) PacketHeader {
+// Memory block of a PCM audio packet header. Changes to it need to ensure the
+// size is a multiple of 4 bytes. It reflects real packet header structure,
+// however, the |size| bits are in big-endian order, and thus is only for
+// padding purpose in this struct, when all bytes after it represent a message
+// header.
+struct __attribute__((__packed__)) PcmPacketHeader {
   uint16_t size;
   uint8_t message_type;
   uint8_t stream_type;
-  uint8_t codec_or_sample_format;
+  int64_t timestamp_us;
+};
+
+// Memory block of a handshake packet. There is no size restriction for this
+// structure.
+struct __attribute__((__packed__)) HandshakePacket {
+  uint16_t size;
+  uint8_t message_type;
+  uint8_t stream_type;
+  uint8_t audio_codec;
+  uint8_t sample_format;
   uint8_t num_channels;
-  uint16_t sample_rate;
-  int64_t timestamp_or_frames;
+  uint16_t num_frames;
+  uint32_t sample_rate;
 };
 
 }  // namespace capture_service
diff --git a/chromecast/media/audio/cast_audio_input_stream.cc b/chromecast/media/audio/cast_audio_input_stream.cc
index e8607101..12c7629 100644
--- a/chromecast/media/audio/cast_audio_input_stream.cc
+++ b/chromecast/media/audio/cast_audio_input_stream.cc
@@ -48,14 +48,14 @@
 
   audio_bus_ = ::media::AudioBus::Create(audio_params_.channels(),
                                          audio_params_.frames_per_buffer());
-  capture_service_receiver_ = std::make_unique<CaptureServiceReceiver>(
-      capture_service::StreamInfo{
-          capture_service::StreamType::kSoftwareEchoCancelled,
-          capture_service::AudioCodec::kPcm, audio_params_.channels(),
-          // Format doesn't matter in the request.
-          capture_service::SampleFormat::LAST_FORMAT,
-          audio_params_.sample_rate(), audio_params_.frames_per_buffer()},
-      this);
+  stream_info_ = capture_service::StreamInfo{
+      capture_service::StreamType::kSoftwareEchoCancelled,
+      capture_service::AudioCodec::kPcm, audio_params_.channels(),
+      // Format doesn't matter in the request.
+      capture_service::SampleFormat::LAST_FORMAT, audio_params_.sample_rate(),
+      audio_params_.frames_per_buffer()};
+  capture_service_receiver_ =
+      std::make_unique<CaptureServiceReceiver>(stream_info_, this);
   return true;
 }
 
@@ -117,33 +117,40 @@
 bool CastAudioInputStream::OnInitialStreamInfo(
     const capture_service::StreamInfo& stream_info) {
   const bool is_params_match =
-      stream_info.stream_type ==
-          capture_service::StreamType::kSoftwareEchoCancelled &&
-      stream_info.audio_codec == capture_service::AudioCodec::kPcm &&
-      stream_info.num_channels == audio_params_.channels() &&
-      stream_info.sample_rate == audio_params_.sample_rate() &&
-      stream_info.frames_per_buffer == audio_params_.frames_per_buffer();
+      stream_info.stream_type == stream_info_.stream_type &&
+      stream_info.audio_codec == stream_info_.audio_codec &&
+      stream_info.num_channels == stream_info_.num_channels &&
+      stream_info.sample_rate == stream_info_.sample_rate &&
+      stream_info.frames_per_buffer == stream_info_.frames_per_buffer;
   LOG_IF(ERROR, !is_params_match)
-      << "Got different parameters from sender, sample_rate: "
-      << audio_params_.sample_rate() << " Hz -> " << stream_info.sample_rate
-      << " Hz, num_channels: " << audio_params_.channels() << " -> "
+      << "Got different parameters from sender, stream_type: "
+      << static_cast<int>(stream_info_.stream_type) << " -> "
+      << static_cast<int>(stream_info.stream_type)
+      << ", audio_codec: " << static_cast<int>(stream_info_.audio_codec)
+      << " -> " << static_cast<int>(stream_info.audio_codec)
+      << ", sample_rate: " << stream_info_.sample_rate << " Hz -> "
+      << stream_info.sample_rate
+      << " Hz, num_channels: " << stream_info_.num_channels << " -> "
       << stream_info.num_channels
-      << ", frames_per_buffer: " << audio_params_.frames_per_buffer() << " -> "
+      << ", frames_per_buffer: " << stream_info_.frames_per_buffer << " -> "
       << stream_info.frames_per_buffer << ".";
+  stream_info_.sample_format = stream_info.sample_format;
+  LOG(INFO) << "Set sample_format: "
+            << static_cast<int>(stream_info.sample_format);
   return is_params_match;
 }
 
 bool CastAudioInputStream::OnCaptureData(const char* data, size_t size) {
-  capture_service::PacketInfo info;
-  if (!capture_service::ReadPcmAudioMessage(data, size, &info,
-                                            audio_bus_.get())) {
+  int64_t timestamp_us;
+  if (!capture_service::ReadPcmAudioMessage(data, size, stream_info_,
+                                            &timestamp_us, audio_bus_.get())) {
     return false;
   }
 
   DCHECK(input_callback_);
   input_callback_->OnData(
       audio_bus_.get(),
-      base::TimeTicks() + base::TimeDelta::FromMicroseconds(info.timestamp_us),
+      base::TimeTicks() + base::TimeDelta::FromMicroseconds(timestamp_us),
       /* volume */ 1.0);
   return true;
 }
diff --git a/chromecast/media/audio/cast_audio_input_stream.h b/chromecast/media/audio/cast_audio_input_stream.h
index 7d222029..4f06e1e 100644
--- a/chromecast/media/audio/cast_audio_input_stream.h
+++ b/chromecast/media/audio/cast_audio_input_stream.h
@@ -10,6 +10,7 @@
 
 #include "base/threading/thread_checker.h"
 #include "chromecast/media/audio/capture_service/capture_service_receiver.h"
+#include "chromecast/media/audio/capture_service/constants.h"
 #include "media/audio/audio_io.h"
 #include "media/base/audio_bus.h"
 #include "media/base/audio_parameters.h"
@@ -58,6 +59,7 @@
   // may be null, if |this| is not created by audio manager, e.g., in unit test.
   ::media::AudioManagerBase* const audio_manager_;
   const ::media::AudioParameters audio_params_;
+  capture_service::StreamInfo stream_info_;
   std::unique_ptr<CaptureServiceReceiver> capture_service_receiver_;
   AudioInputCallback* input_callback_ = nullptr;
   std::unique_ptr<::media::AudioBus> audio_bus_;
diff --git a/chromecast/media/cma/BUILD.gn b/chromecast/media/cma/BUILD.gn
index 0a26786..901ac35 100644
--- a/chromecast/media/cma/BUILD.gn
+++ b/chromecast/media/cma/BUILD.gn
@@ -51,6 +51,7 @@
   testonly = true
   sources = [
     "backend/audio_video_pipeline_device_unittest.cc",
+    "backend/proxy/cma_backend_proxy_unittest.cc",
     "base/balanced_media_task_runner_unittest.cc",
     "base/buffering_controller_unittest.cc",
     "base/buffering_frame_provider_unittest.cc",
@@ -71,6 +72,7 @@
     "//chromecast/media:libcast_media",
     "//chromecast/media/api",
     "//chromecast/media/api:test_support",
+    "//chromecast/media/cma/backend/proxy",
     "//media",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/chromecast/media/cma/backend/BUILD.gn b/chromecast/media/cma/backend/BUILD.gn
index 8a1f641..f19c87b 100644
--- a/chromecast/media/cma/backend/BUILD.gn
+++ b/chromecast/media/cma/backend/BUILD.gn
@@ -44,6 +44,10 @@
     "//chromecast/media/cma/decoder",
   ]
 
+  if (enable_chromium_runtime_cast_renderer) {
+    deps += [ "//chromecast/media/cma/backend/proxy" ]
+  }
+
   if (have_full_mixer) {
     sources += [ "media_pipeline_backend_manager_mixer.cc" ]
     deps += [ "//chromecast/media/audio/mixer_service:control_connection" ]
diff --git a/chromecast/media/cma/backend/android/audio_sink_android.cc b/chromecast/media/cma/backend/android/audio_sink_android.cc
index 88da3e2e..54ccaf6 100644
--- a/chromecast/media/cma/backend/android/audio_sink_android.cc
+++ b/chromecast/media/cma/backend/android/audio_sink_android.cc
@@ -12,22 +12,6 @@
 namespace media {
 
 // static
-const char* GetAudioContentTypeName(const AudioContentType type) {
-  switch (type) {
-    case AudioContentType::kMedia:
-      return "kMedia";
-    case AudioContentType::kAlarm:
-      return "kAlarm";
-    case AudioContentType::kCommunication:
-      return "kCommunication";
-    case AudioContentType::kOther:
-      return "kOther";
-    default:
-      return "Unknown";
-  }
-}
-
-// static
 bool AudioSinkAndroid::GetSessionIds(SinkType sink_type,
                                      int* media_id,
                                      int* communication_id) {
diff --git a/chromecast/media/cma/backend/android/audio_sink_android.h b/chromecast/media/cma/backend/android/audio_sink_android.h
index acf9d61..f9cd4c6 100644
--- a/chromecast/media/cma/backend/android/audio_sink_android.h
+++ b/chromecast/media/cma/backend/android/audio_sink_android.h
@@ -20,8 +20,6 @@
 
 const int kDefaultSlewTimeMs = 15;
 
-const char* GetAudioContentTypeName(const AudioContentType type);
-
 class DecoderBufferBase;
 
 // Input handle to the sink. All methods (including constructor and destructor)
@@ -101,7 +99,6 @@
   virtual bool primary() const = 0;
   virtual std::string device_id() const = 0;
   virtual AudioContentType content_type() const = 0;
-  virtual const char* GetContentTypeName() const = 0;
 };
 
 // Implementation of "managed" AudioSinkAndroid* object that is
diff --git a/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc b/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc
index a7406492..ab71a3c 100644
--- a/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc
+++ b/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc
@@ -100,7 +100,7 @@
             << " num_channels_=" << num_channels_
             << " input_samples_per_second_=" << input_samples_per_second_
             << " primary_=" << primary_ << " device_id_=" << device_id_
-            << " content_type__=" << GetContentTypeName();
+            << " content_type_=" << content_type_;
   DCHECK(delegate_);
   DCHECK_GT(num_channels_, 0);
 
@@ -149,10 +149,6 @@
   return content_type_;
 }
 
-const char* AudioSinkAndroidAudioTrackImpl::GetContentTypeName() const {
-  return GetAudioContentTypeName(content_type_);
-}
-
 void AudioSinkAndroidAudioTrackImpl::FinalizeOnFeederThread() {
   RUN_ON_FEEDER_THREAD(FinalizeOnFeederThread);
   if (j_audio_sink_audiotrack_impl_.is_null()) {
diff --git a/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.h b/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.h
index 4c222a35..572b8d05 100644
--- a/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.h
+++ b/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.h
@@ -70,7 +70,6 @@
   bool primary() const override;
   std::string device_id() const override;
   AudioContentType content_type() const override;
-  const char* GetContentTypeName() const override;
 
   // Prevents any further calls to the delegate (ie, called when the delegate
   // is being destroyed).
diff --git a/chromecast/media/cma/backend/android/audio_sink_manager.cc b/chromecast/media/cma/backend/android/audio_sink_manager.cc
index 4b584cf..b3f58cb 100644
--- a/chromecast/media/cma/backend/android/audio_sink_manager.cc
+++ b/chromecast/media/cma/backend/android/audio_sink_manager.cc
@@ -51,7 +51,7 @@
 
   LOG(INFO) << __func__ << " sink(" << sink << "): id=" << sink->device_id()
             << " primary=" << sink->primary()
-            << " type=" << sink->GetContentTypeName();
+            << " type=" << sink->content_type();
 
   base::AutoLock lock(lock_);
   UpdateLimiterMultiplier(sink);
@@ -62,7 +62,7 @@
   DCHECK(sink);
 
   LOG(INFO) << __func__ << " sink(" << sink << "): id=" << sink->device_id()
-            << " type=" << sink->GetContentTypeName();
+            << " type=" << sink->content_type();
 
   base::AutoLock lock(lock_);
 
@@ -75,8 +75,7 @@
 }
 
 void AudioSinkManager::SetTypeVolumeDb(AudioContentType type, float level_db) {
-  LOG(INFO) << __func__ << ": level_db=" << level_db
-            << " type=" << GetAudioContentTypeName(type);
+  LOG(INFO) << __func__ << ": level_db=" << level_db << " type=" << type;
   base::AutoLock lock(lock_);
   volume_info_[type].volume_db = level_db;
   // Since the type volume changed we need to reflect that in the limiter
@@ -85,8 +84,7 @@
 }
 
 void AudioSinkManager::SetOutputLimitDb(AudioContentType type, float limit_db) {
-  LOG(INFO) << __func__ << ": limit_db=" << limit_db
-            << " type=" << GetAudioContentTypeName(type);
+  LOG(INFO) << __func__ << ": limit_db=" << limit_db << " type=" << type;
   base::AutoLock lock(lock_);
   volume_info_[type].limit_db = limit_db;
   UpdateAllLimiterMultipliers(type);
diff --git a/chromecast/media/cma/backend/cma_backend_factory_impl.cc b/chromecast/media/cma/backend/cma_backend_factory_impl.cc
index a0f6ba7..f0d53be 100644
--- a/chromecast/media/cma/backend/cma_backend_factory_impl.cc
+++ b/chromecast/media/cma/backend/cma_backend_factory_impl.cc
@@ -4,8 +4,12 @@
 
 #include "chromecast/media/cma/backend/cma_backend_factory_impl.h"
 
+#include "chromecast/chromecast_buildflags.h"
 #include "chromecast/media/api/cma_backend.h"
 #include "chromecast/media/cma/backend/media_pipeline_backend_manager.h"
+#if BUILDFLAG(ENABLE_CHROMIUM_RUNTIME_CAST_RENDERER)
+#include "chromecast/media/cma/backend/proxy/cma_backend_proxy.h"  // nogncheck
+#endif  // BUILDFLAG(ENABLE_CHROMIUM_RUNTIME_CAST_RENDERER)
 #include "chromecast/public/media/media_pipeline_device_params.h"
 
 namespace chromecast {
@@ -21,7 +25,14 @@
 
 std::unique_ptr<CmaBackend> CmaBackendFactoryImpl::CreateBackend(
     const MediaPipelineDeviceParams& params) {
-  return media_pipeline_backend_manager_->CreateBackend(params);
+  std::unique_ptr<CmaBackend> backend =
+      media_pipeline_backend_manager_->CreateBackend(params);
+
+#if BUILDFLAG(ENABLE_CHROMIUM_RUNTIME_CAST_RENDERER)
+  backend = std::make_unique<CmaBackendProxy>(std::move(backend));
+#endif  // BUILDFLAG(ENABLE_CHROMIUM_RUNTIME_CAST_RENDERER)
+
+  return backend;
 }
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/mixer_input_connection.cc b/chromecast/media/cma/backend/mixer/mixer_input_connection.cc
index be5d9bd..ca54705 100644
--- a/chromecast/media/cma/backend/mixer/mixer_input_connection.cc
+++ b/chromecast/media/cma/backend/mixer/mixer_input_connection.cc
@@ -51,17 +51,6 @@
 
 constexpr int kRateShifterOutputFrames = 4096;
 
-std::string AudioContentTypeToString(media::AudioContentType type) {
-  switch (type) {
-    case media::AudioContentType::kAlarm:
-      return "alarm";
-    case media::AudioContentType::kCommunication:
-      return "communication";
-    default:
-      return "media";
-  }
-}
-
 int64_t SamplesToMicroseconds(double samples, int sample_rate) {
   return std::round(samples * 1000000 / sample_rate);
 }
@@ -206,9 +195,8 @@
   weak_this_ = weak_factory_.GetWeakPtr();
 
   LOG(INFO) << "Create " << this << " (" << device_id_
-            << "), content type: " << AudioContentTypeToString(content_type_)
-            << ", focus type: " << AudioContentTypeToString(focus_type_)
-            << ", fill size: " << fill_size_
+            << "), content type: " << content_type_
+            << ", focus type: " << focus_type_ << ", fill size: " << fill_size_
             << ", algorithm fill size: " << algorithm_fill_size_
             << ", channel count: " << num_channels_
             << ", input sample rate: " << input_samples_per_second_
diff --git a/chromecast/media/cma/backend/proxy/BUILD.gn b/chromecast/media/cma/backend/proxy/BUILD.gn
index a2cab83..30ee1bb 100644
--- a/chromecast/media/cma/backend/proxy/BUILD.gn
+++ b/chromecast/media/cma/backend/proxy/BUILD.gn
@@ -6,8 +6,11 @@
 
 cast_source_set("proxy") {
   sources = [
-    "multizone_audio_decoder_proxy.cc",
+    "cma_backend_proxy.cc",
+    "cma_backend_proxy.h",
     "multizone_audio_decoder_proxy.h",
+    "multizone_audio_decoder_proxy_impl.cc",
+    "multizone_audio_decoder_proxy_impl.h",
   ]
 
   deps = [
diff --git a/chromecast/media/cma/backend/proxy/cma_backend_proxy.cc b/chromecast/media/cma/backend/proxy/cma_backend_proxy.cc
new file mode 100644
index 0000000..8fff8f7
--- /dev/null
+++ b/chromecast/media/cma/backend/proxy/cma_backend_proxy.cc
@@ -0,0 +1,158 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/media/cma/backend/proxy/cma_backend_proxy.h"
+
+#include <algorithm>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/notreached.h"
+#include "chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.h"
+#include "chromecast/public/media/decoder_config.h"
+
+namespace chromecast {
+namespace media {
+namespace {
+
+// The maximum allowed difference between the audio and video decoders used for
+// the CmaBackendProxy.
+// TODO(b/168748626): Determine the correct value for this variable
+// experimentally.
+int64_t kMaxAllowedPtsDrift = 500;
+
+}  // namespace
+
+CmaBackendProxy::CmaBackendProxy(
+    std::unique_ptr<CmaBackend> delegated_video_pipeline)
+    : CmaBackendProxy(
+          std::move(delegated_video_pipeline),
+          base::BindOnce([]() -> std::unique_ptr<MultizoneAudioDecoderProxy> {
+            return std::make_unique<MultizoneAudioDecoderProxyImpl>();
+          })) {}
+
+CmaBackendProxy::CmaBackendProxy(
+    std::unique_ptr<CmaBackend> delegated_video_pipeline,
+    CmaBackendProxy::AudioDecoderFactoryCB audio_decoder_factory)
+    : delegated_video_pipeline_(std::move(delegated_video_pipeline)),
+      audio_decoder_factory_(std::move(audio_decoder_factory)) {
+  DCHECK(delegated_video_pipeline_);
+  DCHECK(audio_decoder_factory_);
+}
+
+CmaBackendProxy::~CmaBackendProxy() = default;
+
+CmaBackend::AudioDecoder* CmaBackendProxy::CreateAudioDecoder() {
+  DCHECK(!audio_decoder_);
+  DCHECK(audio_decoder_factory_);
+  audio_decoder_ = std::move(audio_decoder_factory_).Run();
+  return audio_decoder_.get();
+}
+
+CmaBackend::VideoDecoder* CmaBackendProxy::CreateVideoDecoder() {
+  has_video_decoder_ = true;
+  return delegated_video_pipeline_->CreateVideoDecoder();
+}
+
+bool CmaBackendProxy::Initialize() {
+  if (has_video_decoder_ && !delegated_video_pipeline_->Initialize()) {
+    return false;
+  }
+
+  return !audio_decoder_ || audio_decoder_->Initialize();
+}
+
+bool CmaBackendProxy::Start(int64_t start_pts) {
+  if (has_video_decoder_ && !delegated_video_pipeline_->Start(start_pts)) {
+    return false;
+  }
+
+  return !audio_decoder_ || audio_decoder_->Start(start_pts);
+}
+
+void CmaBackendProxy::Stop() {
+  if (has_video_decoder_) {
+    delegated_video_pipeline_->Stop();
+  }
+
+  if (audio_decoder_) {
+    audio_decoder_->Stop();
+  }
+}
+
+bool CmaBackendProxy::Pause() {
+  bool result = true;
+
+  if (has_video_decoder_) {
+    result &= delegated_video_pipeline_->Pause();
+  }
+
+  if (audio_decoder_) {
+    result &= audio_decoder_->Pause();
+  }
+
+  return result;
+}
+
+bool CmaBackendProxy::Resume() {
+  if (has_video_decoder_ && !delegated_video_pipeline_->Resume()) {
+    return false;
+  }
+
+  return !audio_decoder_ || audio_decoder_->Resume();
+}
+
+int64_t CmaBackendProxy::GetCurrentPts() {
+  if (audio_decoder_ && has_video_decoder_) {
+    const int64_t audio_pts = audio_decoder_->GetCurrentPts();
+    const int64_t video_pts = delegated_video_pipeline_->GetCurrentPts();
+    const int64_t min = std::min(audio_pts, video_pts);
+    LOG_IF(WARNING, std::max(audio_pts, video_pts) - min > kMaxAllowedPtsDrift);
+    return min;
+  } else if (audio_decoder_) {
+    return audio_decoder_->GetCurrentPts();
+  } else if (has_video_decoder_) {
+    return delegated_video_pipeline_->GetCurrentPts();
+  } else {
+    return std::numeric_limits<int64_t>::min();
+  }
+}
+
+bool CmaBackendProxy::SetPlaybackRate(float rate) {
+  bool result = true;
+
+  if (has_video_decoder_) {
+    result &= delegated_video_pipeline_->SetPlaybackRate(rate);
+  }
+
+  if (audio_decoder_) {
+    result &= audio_decoder_->SetPlaybackRate(rate);
+  }
+
+  return result;
+}
+
+void CmaBackendProxy::LogicalPause() {
+  if (has_video_decoder_) {
+    delegated_video_pipeline_->LogicalPause();
+  }
+
+  if (audio_decoder_) {
+    audio_decoder_->LogicalPause();
+  }
+}
+
+void CmaBackendProxy::LogicalResume() {
+  if (has_video_decoder_) {
+    delegated_video_pipeline_->LogicalResume();
+  }
+
+  if (audio_decoder_) {
+    audio_decoder_->LogicalResume();
+  }
+}
+
+}  // namespace media
+}  // namespace chromecast
diff --git a/chromecast/media/cma/backend/proxy/cma_backend_proxy.h b/chromecast/media/cma/backend/proxy/cma_backend_proxy.h
new file mode 100644
index 0000000..342272d
--- /dev/null
+++ b/chromecast/media/cma/backend/proxy/cma_backend_proxy.h
@@ -0,0 +1,78 @@
+// 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 CHROMECAST_MEDIA_CMA_BACKEND_PROXY_CMA_BACKEND_PROXY_H_
+#define CHROMECAST_MEDIA_CMA_BACKEND_PROXY_CMA_BACKEND_PROXY_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/optional.h"
+#include "chromecast/media/api/cma_backend.h"
+#include "chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy.h"
+
+namespace chromecast {
+namespace media {
+
+// This class is used to proxy audio data to an external
+// CmaBackend::AudioDecoder over gRPC, while delegating video decoding to an
+// alternate CMA Backend.
+// NOTE: By design, this class does NOT handle a/v sync drift between
+// |audio_decoder_| and |delegated_video_pipeline_|.
+class CmaBackendProxy : public CmaBackend {
+ public:
+  using AudioDecoderFactoryCB =
+      base::OnceCallback<std::unique_ptr<MultizoneAudioDecoderProxy>()>;
+
+  // Creates a new CmaBackendProxy such that all video processing is delegated
+  // to |delegated_video_pipeline|.
+  explicit CmaBackendProxy(
+      std::unique_ptr<CmaBackend> delegated_video_pipeline);
+  ~CmaBackendProxy() override;
+
+  // MediaPipelineBackend implementation:
+  CmaBackend::AudioDecoder* CreateAudioDecoder() override;
+  CmaBackend::VideoDecoder* CreateVideoDecoder() override;
+  bool Initialize() override;
+  bool Start(int64_t start_pts) override;
+  void Stop() override;
+  bool Pause() override;
+  bool Resume() override;
+  int64_t GetCurrentPts() override;
+  bool SetPlaybackRate(float rate) override;
+  void LogicalPause() override;
+  void LogicalResume() override;
+
+ private:
+  friend class CmaBackendProxyTest;
+
+  // Creates a new CmaBackendProxy such that all video processing is delegated
+  // to |delegated_video_pipeline| and all audio processing is delegated to a
+  // new MultizoneAudioDecoderProxy created by |audio_decoder_factory|.
+  CmaBackendProxy(std::unique_ptr<CmaBackend> delegated_video_pipeline,
+                  AudioDecoderFactoryCB audio_decoder_factory);
+
+  // The audio decoder to which audio operations should be delegated.
+  std::unique_ptr<MultizoneAudioDecoderProxy> audio_decoder_;
+
+  // The CMA Backend to which all video decoding is delegated.
+  std::unique_ptr<CmaBackend> delegated_video_pipeline_;
+
+  // Determines whether a video decoder is being used. If not, calls should not
+  // be delegated to the |delegated_video_pipeline_|, as it may not behave as
+  // expected when neither the audio or video decoders are initialized.
+  bool has_video_decoder_ = false;
+
+  // The factory to use to populate the |audio_decoder_| object when needed.
+  AudioDecoderFactoryCB audio_decoder_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(CmaBackendProxy);
+};
+
+}  // namespace media
+}  // namespace chromecast
+
+#endif  // CHROMECAST_MEDIA_CMA_BACKEND_PROXY_CMA_BACKEND_PROXY_H_
diff --git a/chromecast/media/cma/backend/proxy/cma_backend_proxy_unittest.cc b/chromecast/media/cma/backend/proxy/cma_backend_proxy_unittest.cc
new file mode 100644
index 0000000..ea3ffc2
--- /dev/null
+++ b/chromecast/media/cma/backend/proxy/cma_backend_proxy_unittest.cc
@@ -0,0 +1,305 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/media/cma/backend/proxy/cma_backend_proxy.h"
+
+#include "base/bind.h"
+#include "base/memory/ref_counted.h"
+#include "chromecast/media/api/cma_backend.h"
+#include "chromecast/media/api/decoder_buffer_base.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::Return;
+using testing::StrictMock;
+
+namespace chromecast {
+namespace media {
+namespace {
+
+class MockCmaBackend : public CmaBackend {
+ public:
+  MOCK_METHOD0(CreateAudioDecoder, CmaBackend::AudioDecoder*());
+  MOCK_METHOD0(CreateVideoDecoder, CmaBackend::VideoDecoder*());
+  MOCK_METHOD0(Initialize, bool());
+  MOCK_METHOD1(Start, bool(int64_t));
+  MOCK_METHOD0(Stop, void());
+  MOCK_METHOD0(Pause, bool());
+  MOCK_METHOD0(Resume, bool());
+  MOCK_METHOD0(GetCurrentPts, int64_t());
+  MOCK_METHOD1(SetPlaybackRate, bool(float rate));
+  MOCK_METHOD0(LogicalPause, void());
+  MOCK_METHOD0(LogicalResume, void());
+};
+
+class MockMultizoneAudioDecoderProxy : public MultizoneAudioDecoderProxy {
+ public:
+  MOCK_METHOD0(Initialize, bool());
+  MOCK_METHOD1(Start, bool(int64_t));
+  MOCK_METHOD0(Stop, void());
+  MOCK_METHOD0(Pause, bool());
+  MOCK_METHOD0(Resume, bool());
+  MOCK_CONST_METHOD0(GetCurrentPts, int64_t());
+  MOCK_METHOD1(SetPlaybackRate, bool(float rate));
+  MOCK_METHOD0(LogicalPause, void());
+  MOCK_METHOD0(LogicalResume, void());
+  MOCK_METHOD1(SetDelegate, void(Delegate*));
+  MOCK_METHOD1(PushBuffer, BufferStatus(scoped_refptr<DecoderBufferBase>));
+  MOCK_METHOD1(SetConfig, bool(const AudioConfig&));
+  MOCK_METHOD1(SetVolume, bool(float));
+  MOCK_METHOD0(GetRenderingDelay, RenderingDelay());
+  MOCK_METHOD1(GetStatistics, void(Statistics*));
+  MOCK_METHOD0(RequiresDecryption, bool());
+  MOCK_METHOD1(SetObserver, void(Observer*));
+};
+
+}  // namespace
+
+class CmaBackendProxyTest : public testing::Test {
+ public:
+  CmaBackendProxyTest() {
+    auto delegated_video_backend =
+        std::make_unique<StrictMock<MockCmaBackend>>();
+    auto audio_decoder =
+        std::make_unique<StrictMock<MockMultizoneAudioDecoderProxy>>();
+
+    delegated_video_backend_ = delegated_video_backend.get();
+    audio_decoder_ = audio_decoder.get();
+
+    CmaBackendProxy::AudioDecoderFactoryCB factory = base::BindOnce(
+        [](std::unique_ptr<MultizoneAudioDecoderProxy> ptr) { return ptr; },
+        std::move(audio_decoder));
+    CmaBackendProxy* proxy = new CmaBackendProxy(
+        std::move(delegated_video_backend), std::move(factory));
+    backend_.reset(proxy);
+  }
+
+ protected:
+  void CreateVideoDecoder() {
+    EXPECT_CALL(*delegated_video_backend_, CreateVideoDecoder()).Times(1);
+    backend_->CreateVideoDecoder();
+    testing::Mock::VerifyAndClearExpectations(delegated_video_backend_);
+  }
+
+  std::unique_ptr<CmaBackendProxy> backend_;
+  MockCmaBackend* delegated_video_backend_;
+  MockMultizoneAudioDecoderProxy* audio_decoder_;
+};
+
+TEST_F(CmaBackendProxyTest, Initialize) {
+  EXPECT_TRUE(backend_->Initialize());
+
+  ASSERT_EQ(backend_->CreateAudioDecoder(), audio_decoder_);
+
+  EXPECT_CALL(*audio_decoder_, Initialize())
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  EXPECT_TRUE(backend_->Initialize());
+  EXPECT_FALSE(backend_->Initialize());
+  testing::Mock::VerifyAndClearExpectations(audio_decoder_);
+
+  CreateVideoDecoder();
+  EXPECT_CALL(*audio_decoder_, Initialize())
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  EXPECT_CALL(*delegated_video_backend_, Initialize())
+      .WillOnce(Return(true))
+      .WillOnce(Return(true))
+      .WillOnce(Return(false))
+      .WillOnce(Return(false));
+
+  EXPECT_TRUE(backend_->Initialize());
+  EXPECT_FALSE(backend_->Initialize());
+  testing::Mock::VerifyAndClearExpectations(audio_decoder_);
+
+  EXPECT_FALSE(backend_->Initialize());
+  EXPECT_FALSE(backend_->Initialize());
+}
+
+TEST_F(CmaBackendProxyTest, Start) {
+  constexpr float kStartPts = 42;
+  EXPECT_TRUE(backend_->Start(kStartPts));
+
+  ASSERT_EQ(backend_->CreateAudioDecoder(), audio_decoder_);
+
+  EXPECT_CALL(*audio_decoder_, Start(kStartPts))
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  EXPECT_TRUE(backend_->Start(kStartPts));
+  EXPECT_FALSE(backend_->Start(kStartPts));
+  testing::Mock::VerifyAndClearExpectations(audio_decoder_);
+
+  CreateVideoDecoder();
+  EXPECT_CALL(*audio_decoder_, Start(kStartPts))
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  EXPECT_CALL(*delegated_video_backend_, Start(kStartPts))
+      .WillOnce(Return(true))
+      .WillOnce(Return(true))
+      .WillOnce(Return(false))
+      .WillOnce(Return(false));
+
+  EXPECT_TRUE(backend_->Start(kStartPts));
+  EXPECT_FALSE(backend_->Start(kStartPts));
+  EXPECT_FALSE(backend_->Start(kStartPts));
+  EXPECT_FALSE(backend_->Start(kStartPts));
+}
+
+TEST_F(CmaBackendProxyTest, Stop) {
+  backend_->Stop();
+
+  ASSERT_EQ(backend_->CreateAudioDecoder(), audio_decoder_);
+
+  EXPECT_CALL(*audio_decoder_, Stop());
+  backend_->Stop();
+  testing::Mock::VerifyAndClearExpectations(audio_decoder_);
+
+  CreateVideoDecoder();
+  EXPECT_CALL(*audio_decoder_, Stop());
+  EXPECT_CALL(*delegated_video_backend_, Stop());
+  backend_->Stop();
+}
+
+TEST_F(CmaBackendProxyTest, Pause) {
+  EXPECT_TRUE(backend_->Pause());
+
+  ASSERT_EQ(backend_->CreateAudioDecoder(), audio_decoder_);
+
+  EXPECT_CALL(*audio_decoder_, Pause())
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  EXPECT_TRUE(backend_->Pause());
+  EXPECT_FALSE(backend_->Pause());
+  testing::Mock::VerifyAndClearExpectations(audio_decoder_);
+
+  CreateVideoDecoder();
+  EXPECT_CALL(*audio_decoder_, Pause())
+      .WillOnce(Return(true))
+      .WillOnce(Return(false))
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  EXPECT_CALL(*delegated_video_backend_, Pause())
+      .WillOnce(Return(true))
+      .WillOnce(Return(true))
+      .WillOnce(Return(false))
+      .WillOnce(Return(false));
+
+  EXPECT_TRUE(backend_->Pause());
+  EXPECT_FALSE(backend_->Pause());
+  EXPECT_FALSE(backend_->Pause());
+  EXPECT_FALSE(backend_->Pause());
+}
+
+TEST_F(CmaBackendProxyTest, Resume) {
+  EXPECT_TRUE(backend_->Resume());
+
+  ASSERT_EQ(backend_->CreateAudioDecoder(), audio_decoder_);
+
+  EXPECT_CALL(*audio_decoder_, Resume())
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  EXPECT_TRUE(backend_->Resume());
+  EXPECT_FALSE(backend_->Resume());
+  testing::Mock::VerifyAndClearExpectations(audio_decoder_);
+
+  CreateVideoDecoder();
+  EXPECT_CALL(*audio_decoder_, Resume())
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  EXPECT_CALL(*delegated_video_backend_, Resume())
+      .WillOnce(Return(true))
+      .WillOnce(Return(true))
+      .WillOnce(Return(false))
+      .WillOnce(Return(false));
+
+  EXPECT_TRUE(backend_->Resume());
+  EXPECT_FALSE(backend_->Resume());
+  EXPECT_FALSE(backend_->Resume());
+  EXPECT_FALSE(backend_->Resume());
+}
+
+TEST_F(CmaBackendProxyTest, GetCurrentPts) {
+  EXPECT_EQ(backend_->GetCurrentPts(), std::numeric_limits<int64_t>::min());
+
+  ASSERT_EQ(backend_->CreateAudioDecoder(), audio_decoder_);
+
+  EXPECT_CALL(*audio_decoder_, GetCurrentPts()).WillOnce(Return(42));
+  EXPECT_EQ(backend_->GetCurrentPts(), 42);
+  testing::Mock::VerifyAndClearExpectations(audio_decoder_);
+
+  CreateVideoDecoder();
+  EXPECT_CALL(*audio_decoder_, GetCurrentPts())
+      .WillOnce(Return(42))
+      .WillOnce(Return(42));
+  EXPECT_CALL(*delegated_video_backend_, GetCurrentPts())
+      .WillOnce(Return(16))
+      .WillOnce(Return(360));
+
+  EXPECT_EQ(backend_->GetCurrentPts(), 16);
+  EXPECT_EQ(backend_->GetCurrentPts(), 42);
+}
+
+TEST_F(CmaBackendProxyTest, SetPlaybackRate) {
+  constexpr float kSetPlaybackRatePts = 0.5;
+  EXPECT_TRUE(backend_->SetPlaybackRate(kSetPlaybackRatePts));
+
+  ASSERT_EQ(backend_->CreateAudioDecoder(), audio_decoder_);
+
+  EXPECT_CALL(*audio_decoder_, SetPlaybackRate(kSetPlaybackRatePts))
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  EXPECT_TRUE(backend_->SetPlaybackRate(kSetPlaybackRatePts));
+  EXPECT_FALSE(backend_->SetPlaybackRate(kSetPlaybackRatePts));
+  testing::Mock::VerifyAndClearExpectations(audio_decoder_);
+
+  CreateVideoDecoder();
+  EXPECT_CALL(*audio_decoder_, SetPlaybackRate(kSetPlaybackRatePts))
+      .WillOnce(Return(true))
+      .WillOnce(Return(false))
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  EXPECT_CALL(*delegated_video_backend_, SetPlaybackRate(kSetPlaybackRatePts))
+      .WillOnce(Return(true))
+      .WillOnce(Return(true))
+      .WillOnce(Return(false))
+      .WillOnce(Return(false));
+
+  EXPECT_TRUE(backend_->SetPlaybackRate(kSetPlaybackRatePts));
+  EXPECT_FALSE(backend_->SetPlaybackRate(kSetPlaybackRatePts));
+  EXPECT_FALSE(backend_->SetPlaybackRate(kSetPlaybackRatePts));
+  EXPECT_FALSE(backend_->SetPlaybackRate(kSetPlaybackRatePts));
+}
+
+TEST_F(CmaBackendProxyTest, LogicalPause) {
+  backend_->LogicalPause();
+
+  ASSERT_EQ(backend_->CreateAudioDecoder(), audio_decoder_);
+
+  EXPECT_CALL(*audio_decoder_, LogicalPause());
+  backend_->LogicalPause();
+  testing::Mock::VerifyAndClearExpectations(audio_decoder_);
+
+  CreateVideoDecoder();
+  EXPECT_CALL(*audio_decoder_, LogicalPause());
+  EXPECT_CALL(*delegated_video_backend_, LogicalPause());
+  backend_->LogicalPause();
+}
+
+TEST_F(CmaBackendProxyTest, LogicalResume) {
+  backend_->LogicalResume();
+
+  ASSERT_EQ(backend_->CreateAudioDecoder(), audio_decoder_);
+
+  EXPECT_CALL(*audio_decoder_, LogicalResume());
+  backend_->LogicalResume();
+  testing::Mock::VerifyAndClearExpectations(audio_decoder_);
+
+  CreateVideoDecoder();
+  EXPECT_CALL(*audio_decoder_, LogicalResume());
+  EXPECT_CALL(*delegated_video_backend_, LogicalResume());
+  backend_->LogicalResume();
+}
+
+}  // namespace media
+}  // namespace chromecast
diff --git a/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy.cc b/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy.cc
deleted file mode 100644
index eca3b07..0000000
--- a/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy.h"
-
-#include "base/notreached.h"
-#include "chromecast/public/media/decoder_config.h"
-
-namespace chromecast {
-namespace media {
-
-void MultizoneAudioDecoderProxy::SetDelegate(Delegate* delegate) {
-  NOTREACHED();
-}
-
-MultizoneAudioDecoderProxy::BufferStatus MultizoneAudioDecoderProxy::PushBuffer(
-    scoped_refptr<DecoderBufferBase> buffer) {
-  NOTREACHED();
-  return BufferStatus::kBufferSuccess;
-}
-
-bool MultizoneAudioDecoderProxy::SetConfig(const AudioConfig& config) {
-  NOTREACHED();
-  return true;
-}
-
-bool MultizoneAudioDecoderProxy::SetVolume(float multiplier) {
-  NOTREACHED();
-  return true;
-}
-
-MultizoneAudioDecoderProxy::RenderingDelay
-MultizoneAudioDecoderProxy::GetRenderingDelay() {
-  NOTREACHED();
-  return RenderingDelay{};
-}
-
-void MultizoneAudioDecoderProxy::GetStatistics(Statistics* statistics) {
-  NOTREACHED();
-}
-
-bool MultizoneAudioDecoderProxy::RequiresDecryption() {
-  NOTREACHED();
-  return true;
-}
-
-void MultizoneAudioDecoderProxy::SetObserver(Observer* observer) {
-  NOTREACHED();
-}
-
-}  // namespace media
-}  // namespace chromecast
diff --git a/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy.h b/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy.h
index c67e5593..5b1f5a3 100644
--- a/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy.h
+++ b/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy.h
@@ -5,6 +5,9 @@
 #ifndef CHROMECAST_MEDIA_CMA_BACKEND_PROXY_MULTIZONE_AUDIO_DECODER_PROXY_H_
 #define CHROMECAST_MEDIA_CMA_BACKEND_PROXY_MULTIZONE_AUDIO_DECODER_PROXY_H_
 
+#include <limits>
+
+#include "base/callback.h"
 #include "base/memory/ref_counted.h"
 #include "chromecast/media/api/cma_backend.h"
 #include "chromecast/media/api/decoder_buffer_base.h"
@@ -12,8 +15,6 @@
 namespace chromecast {
 namespace media {
 
-struct AudioConfig;
-
 // This class is used to decrypt then proxy audio data to an external
 // CmaBackend::AudioDecoder over gRPC.
 class MultizoneAudioDecoderProxy : public CmaBackend::AudioDecoder {
@@ -24,17 +25,17 @@
   using RenderingDelay = CmaBackend::AudioDecoder::RenderingDelay;
   using Statistics = CmaBackend::AudioDecoder::Statistics;
 
-  ~MultizoneAudioDecoderProxy() override;
+  ~MultizoneAudioDecoderProxy() override = default;
 
-  // CmaBackend::AudioDecoder implementation:
-  void SetDelegate(Delegate* delegate) override;
-  BufferStatus PushBuffer(scoped_refptr<DecoderBufferBase> buffer) override;
-  bool SetConfig(const AudioConfig& config) override;
-  bool SetVolume(float multiplier) override;
-  RenderingDelay GetRenderingDelay() override;
-  void GetStatistics(Statistics* statistics) override;
-  bool RequiresDecryption() override;
-  void SetObserver(Observer* observer) override;
+  virtual bool Initialize() = 0;
+  virtual bool Start(int64_t start_pts) = 0;
+  virtual void Stop() = 0;
+  virtual bool Pause() = 0;
+  virtual bool Resume() = 0;
+  virtual bool SetPlaybackRate(float rate) = 0;
+  virtual void LogicalPause() = 0;
+  virtual void LogicalResume() = 0;
+  virtual int64_t GetCurrentPts() const = 0;
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.cc b/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.cc
new file mode 100644
index 0000000..2df82c3
--- /dev/null
+++ b/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.cc
@@ -0,0 +1,99 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.h"
+
+#include "base/notreached.h"
+#include "chromecast/public/media/decoder_config.h"
+
+namespace chromecast {
+namespace media {
+
+MultizoneAudioDecoderProxyImpl::MultizoneAudioDecoderProxyImpl() = default;
+
+MultizoneAudioDecoderProxyImpl::~MultizoneAudioDecoderProxyImpl() = default;
+
+bool MultizoneAudioDecoderProxyImpl::Initialize() {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+bool MultizoneAudioDecoderProxyImpl::Start(int64_t start_pts) {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+void MultizoneAudioDecoderProxyImpl::Stop() {
+  NOTIMPLEMENTED();
+}
+
+bool MultizoneAudioDecoderProxyImpl::Pause() {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+bool MultizoneAudioDecoderProxyImpl::Resume() {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+bool MultizoneAudioDecoderProxyImpl::SetPlaybackRate(float rate) {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+void MultizoneAudioDecoderProxyImpl::LogicalPause() {
+  NOTIMPLEMENTED();
+}
+
+void MultizoneAudioDecoderProxyImpl::LogicalResume() {
+  NOTIMPLEMENTED();
+}
+
+int64_t MultizoneAudioDecoderProxyImpl::GetCurrentPts() const {
+  return pts_offset_;
+}
+
+void MultizoneAudioDecoderProxyImpl::SetDelegate(Delegate* delegate) {
+  NOTIMPLEMENTED();
+}
+
+MultizoneAudioDecoderProxy::BufferStatus
+MultizoneAudioDecoderProxyImpl::PushBuffer(
+    scoped_refptr<DecoderBufferBase> buffer) {
+  NOTIMPLEMENTED();
+  return BufferStatus::kBufferSuccess;
+}
+
+bool MultizoneAudioDecoderProxyImpl::SetConfig(const AudioConfig& config) {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+bool MultizoneAudioDecoderProxyImpl::SetVolume(float multiplier) {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+MultizoneAudioDecoderProxyImpl::RenderingDelay
+MultizoneAudioDecoderProxyImpl::GetRenderingDelay() {
+  NOTIMPLEMENTED();
+  return RenderingDelay{};
+}
+
+void MultizoneAudioDecoderProxyImpl::GetStatistics(Statistics* statistics) {
+  NOTIMPLEMENTED();
+}
+
+bool MultizoneAudioDecoderProxyImpl::RequiresDecryption() {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+void MultizoneAudioDecoderProxyImpl::SetObserver(Observer* observer) {
+  NOTIMPLEMENTED();
+}
+
+}  // namespace media
+}  // namespace chromecast
diff --git a/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.h b/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.h
new file mode 100644
index 0000000..e1cb3ba2
--- /dev/null
+++ b/chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy_impl.h
@@ -0,0 +1,59 @@
+// 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 CHROMECAST_MEDIA_CMA_BACKEND_PROXY_MULTIZONE_AUDIO_DECODER_PROXY_IMPL_H_
+#define CHROMECAST_MEDIA_CMA_BACKEND_PROXY_MULTIZONE_AUDIO_DECODER_PROXY_IMPL_H_
+
+#include <limits>
+
+#include "base/memory/ref_counted.h"
+#include "chromecast/media/api/cma_backend.h"
+#include "chromecast/media/api/decoder_buffer_base.h"
+#include "chromecast/media/cma/backend/proxy/multizone_audio_decoder_proxy.h"
+
+namespace chromecast {
+namespace media {
+
+struct AudioConfig;
+
+// This class is used to proxy audio data to an external
+// CmaBackend::AudioDecoder over gRPC.
+class MultizoneAudioDecoderProxyImpl : public MultizoneAudioDecoderProxy {
+ public:
+  // Creates a new MultizoneAudioDecoderProxy, such that in the event of an
+  // unrecoverable error, |fatal_error_callback| will be called. Fallowing this
+  // call, this instance will be in an undefined state.
+  MultizoneAudioDecoderProxyImpl();
+  ~MultizoneAudioDecoderProxyImpl() override;
+
+  // MultizoneAudioDecoderProxy implementation:
+  bool Initialize() override;
+  bool Start(int64_t start_pts) override;
+  void Stop() override;
+  bool Pause() override;
+  bool Resume() override;
+  int64_t GetCurrentPts() const override;
+  bool SetPlaybackRate(float rate) override;
+  void LogicalPause() override;
+  void LogicalResume() override;
+  void SetDelegate(Delegate* delegate) override;
+  BufferStatus PushBuffer(scoped_refptr<DecoderBufferBase> buffer) override;
+  bool SetConfig(const AudioConfig& config) override;
+  bool SetVolume(float multiplier) override;
+  RenderingDelay GetRenderingDelay() override;
+  void GetStatistics(Statistics* statistics) override;
+  bool RequiresDecryption() override;
+  void SetObserver(Observer* observer) override;
+
+ private:
+  // The PTS offset as determined by the receiver of the gRPC endpoint wrapped
+  // by this class. This value is updated as new PTS values are received over
+  // the IPC.
+  int64_t pts_offset_ = std::numeric_limits<int64_t>::min();
+};
+
+}  // namespace media
+}  // namespace chromecast
+
+#endif  // CHROMECAST_MEDIA_CMA_BACKEND_PROXY_MULTIZONE_AUDIO_DECODER_PROXY_IMPL_H_
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 829b44f..6edf245 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-13477.0.0
\ No newline at end of file
+13485.0.0
\ No newline at end of file
diff --git a/chromeos/components/diagnostics_ui/backend/system_data_provider.cc b/chromeos/components/diagnostics_ui/backend/system_data_provider.cc
index de4a3a7..caac24f 100644
--- a/chromeos/components/diagnostics_ui/backend/system_data_provider.cc
+++ b/chromeos/components/diagnostics_ui/backend/system_data_provider.cc
@@ -65,6 +65,14 @@
   out_system_info.device_capabilities = std::move(capabilities);
 }
 
+void PopulateBatteryInfo(const healthd::BatteryInfo& battery_info,
+                         mojom::BatteryInfo& out_battery_info) {
+  out_battery_info.manufacturer = battery_info.vendor;
+  // Multiply by 1000 to convert amps to milliamps.
+  out_battery_info.charge_full_design_milliamp_hours =
+      battery_info.charge_full_design * 1000;
+}
+
 }  // namespace
 
 SystemDataProvider::SystemDataProvider() = default;
@@ -80,6 +88,15 @@
                      base::Unretained(this), std::move(callback)));
 }
 
+void SystemDataProvider::GetBatteryInfo(GetBatteryInfoCallback callback) {
+  BindCrosHealthdProbeServiceIfNeccessary();
+
+  probe_service_->ProbeTelemetryInfo(
+      {ProbeCategories::kBattery},
+      base::BindOnce(&SystemDataProvider::OnBatteryInfoProbeResponse,
+                     base::Unretained(this), std::move(callback)));
+}
+
 void SystemDataProvider::OnSystemInfoProbeResponse(
     GetSystemInfoCallback callback,
     healthd::TelemetryInfoPtr info_ptr) {
@@ -124,6 +141,29 @@
   std::move(callback).Run(std::move(system_info));
 }
 
+void SystemDataProvider::OnBatteryInfoProbeResponse(
+    GetBatteryInfoCallback callback,
+    healthd::TelemetryInfoPtr info_ptr) {
+  mojom::BatteryInfoPtr battery_info = mojom::BatteryInfo::New();
+
+  if (info_ptr.is_null()) {
+    LOG(ERROR) << "Null response from croshealthd::ProbeTelemetryInfo.";
+    std::move(callback).Run(std::move(battery_info));
+    return;
+  }
+
+  const healthd::BatteryInfo* battery_info_ptr =
+      diagnostics::GetBatteryInfo(*info_ptr);
+  if (!battery_info_ptr) {
+    LOG(ERROR) << "BatteryInfo requested by device does not have a battery.";
+    std::move(callback).Run(std::move(battery_info));
+    return;
+  }
+
+  PopulateBatteryInfo(*battery_info_ptr, *battery_info.get());
+  std::move(callback).Run(std::move(battery_info));
+}
+
 void SystemDataProvider::BindCrosHealthdProbeServiceIfNeccessary() {
   if (!probe_service_ || !probe_service_.is_connected()) {
     cros_healthd::ServiceConnection::GetInstance()->GetProbeService(
diff --git a/chromeos/components/diagnostics_ui/backend/system_data_provider.h b/chromeos/components/diagnostics_ui/backend/system_data_provider.h
index a2146b6..b3ed40696 100644
--- a/chromeos/components/diagnostics_ui/backend/system_data_provider.h
+++ b/chromeos/components/diagnostics_ui/backend/system_data_provider.h
@@ -23,6 +23,7 @@
 
   // mojom::SystemDataProvider:
   void GetSystemInfo(GetSystemInfoCallback callback) override;
+  void GetBatteryInfo(GetBatteryInfoCallback callback) override;
 
  private:
   void BindCrosHealthdProbeServiceIfNeccessary();
@@ -33,6 +34,10 @@
       GetSystemInfoCallback callback,
       cros_healthd::mojom::TelemetryInfoPtr info_ptr);
 
+  void OnBatteryInfoProbeResponse(
+      GetBatteryInfoCallback callback,
+      cros_healthd::mojom::TelemetryInfoPtr info_ptr);
+
   mojo::Remote<cros_healthd::mojom::CrosHealthdProbeService> probe_service_;
 };
 
diff --git a/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc b/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc
index 5c43966..79c874c 100644
--- a/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc
+++ b/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc
@@ -22,6 +22,33 @@
 namespace diagnostics {
 namespace {
 
+void SetProbeTelemetryInfoResponse(
+    cros_healthd::mojom::BatteryInfoPtr battery_info,
+    cros_healthd::mojom::CpuInfoPtr cpu_info,
+    cros_healthd::mojom::MemoryInfoPtr memory_info,
+    cros_healthd::mojom::SystemInfoPtr system_info) {
+  auto info = cros_healthd::mojom::TelemetryInfo::New();
+  if (system_info) {
+    info->system_result = cros_healthd::mojom::SystemResult::NewSystemInfo(
+        std::move(system_info));
+  }
+  if (battery_info) {
+    info->battery_result = cros_healthd::mojom::BatteryResult::NewBatteryInfo(
+        std::move(battery_info));
+  }
+  if (memory_info) {
+    info->memory_result = cros_healthd::mojom::MemoryResult::NewMemoryInfo(
+        std::move(memory_info));
+  }
+  if (cpu_info) {
+    info->cpu_result =
+        cros_healthd::mojom::CpuResult::NewCpuInfo(std::move(cpu_info));
+  }
+
+  cros_healthd::FakeCrosHealthdClient::Get()
+      ->SetProbeTelemetryInfoResponseForTesting(info);
+}
+
 void SetCrosHealthdSystemInfoResponse(const std::string& board_name,
                                       const std::string& cpu_model,
                                       uint32_t total_memory_kib,
@@ -50,17 +77,66 @@
   cpu_info->num_total_threads = cpu_threads_count;
   cpu_info->physical_cpus.emplace_back(std::move(physical_cpu_info));
 
-  auto info = cros_healthd::mojom::TelemetryInfo::New();
-  info->system_result =
-      cros_healthd::mojom::SystemResult::NewSystemInfo(std::move(system_info));
-  info->battery_result = cros_healthd::mojom::BatteryResult::NewBatteryInfo(
-      std::move(battery_info));
-  info->memory_result =
-      cros_healthd::mojom::MemoryResult::NewMemoryInfo(std::move(memory_info));
-  info->cpu_result =
-      cros_healthd::mojom::CpuResult::NewCpuInfo(std::move(cpu_info));
-  cros_healthd::FakeCrosHealthdClient::Get()
-      ->SetProbeTelemetryInfoResponseForTesting(info);
+  SetProbeTelemetryInfoResponse(std::move(battery_info), std::move(cpu_info),
+                                std::move(memory_info), std::move(system_info));
+}
+
+// Constructs a BatteryInfoPtr. If |temperature| = 0, it will be omitted from
+// the response to simulate an empty temperature field.
+cros_healthd::mojom::BatteryInfoPtr CreateCrosHealthdBatteryInfoResponse(
+    int64_t cycle_count,
+    double voltage_now,
+    const std::string& vendor,
+    const std::string& serial_number,
+    double charge_full_design,
+    double charge_full,
+    double voltage_min_design,
+    const std::string& model_name,
+    double charge_now,
+    double current_now,
+    const std::string& technology,
+    const std::string& status,
+    const base::Optional<std::string>& manufacture_date,
+    uint64_t temperature) {
+  cros_healthd::mojom::UInt64ValuePtr temp_value_ptr(
+      cros_healthd::mojom::UInt64Value::New());
+  if (temperature != 0) {
+    temp_value_ptr->value = temperature;
+  }
+  auto battery_info = cros_healthd::mojom::BatteryInfo::New(
+      cycle_count, voltage_now, vendor, serial_number, charge_full_design,
+      charge_full, voltage_min_design, model_name, charge_now, current_now,
+      technology, status, manufacture_date, std::move(temp_value_ptr));
+  return battery_info;
+}
+
+cros_healthd::mojom::BatteryInfoPtr CreateCrosHealthdBatteryInfoResponse(
+    const std::string& vendor,
+    double charge_full_design) {
+  return CreateCrosHealthdBatteryInfoResponse(
+      /*cycle_count=*/0,
+      /*voltage_now=*/0,
+      /*vendor=*/vendor,
+      /*serial_number=*/"",
+      /*charge_full_design=*/charge_full_design,
+      /*charge_full=*/0,
+      /*voltage_min_design=*/0,
+      /*model_name=*/"",
+      /*charge_now=*/0,
+      /*current_now=*/0,
+      /*technology=*/"",
+      /*status=*/"",
+      /*manufacture_date=*/base::nullopt,
+      /*temperature=*/0);
+}
+
+void SetCrosHealthdBatteryInfoResponse(const std::string& vendor,
+                                       double charge_full_design) {
+  cros_healthd::mojom::BatteryInfoPtr battery_info =
+      CreateCrosHealthdBatteryInfoResponse(vendor, charge_full_design);
+  SetProbeTelemetryInfoResponse(std::move(battery_info), /*cpu_info=*/nullptr,
+                                /*memory_info=*/nullptr,
+                                /*memory_info=*/nullptr);
 }
 
 }  // namespace
@@ -144,5 +220,28 @@
   run_loop.Run();
 }
 
+TEST_F(SystemDataProviderTest, BatteryInfo) {
+  const std::string expected_manufacturer = "manufacturer";
+  const double charge_full_amp_hours = 25;
+
+  SetCrosHealthdBatteryInfoResponse(expected_manufacturer,
+                                    charge_full_amp_hours);
+
+  const uint32_t expected_charge_full_design_milliamp_hours =
+      charge_full_amp_hours * 1000;
+
+  base::RunLoop run_loop;
+  system_data_provider_->GetBatteryInfo(
+      base::BindLambdaForTesting([&](mojom::BatteryInfoPtr ptr) {
+        ASSERT_TRUE(ptr);
+        EXPECT_EQ(expected_manufacturer, ptr->manufacturer);
+        EXPECT_EQ(expected_charge_full_design_milliamp_hours,
+                  ptr->charge_full_design_milliamp_hours);
+
+        run_loop.Quit();
+      }));
+  run_loop.Run();
+}
+
 }  // namespace diagnostics
 }  // namespace chromeos
diff --git a/chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom b/chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom
index be8b10e..1e55f33 100644
--- a/chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom
+++ b/chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom
@@ -24,10 +24,21 @@
   DeviceCapabilities device_capabilities;
 };
 
+// Contains information about the battery.
+struct BatteryInfo {
+  string manufacturer;
+  uint32 charge_full_design_milliamp_hours;
+};
+
 // Provides telemetric information about the system. This API is exposed to the
 // Diagnostics SWA.
 interface SystemDataProvider {
   // Returns a snapshot of system information. |system_info| is static
   // information that does not change during the lifetime of the service.
   GetSystemInfo() => (SystemInfo system_info);
+
+  // Returns information about the battery. |battery_info| is static
+  // information that does not change during the lifetime fo the service.
+  // If the device does not have a battery, returns an empty BatteryInfo.
+  GetBatteryInfo() => (BatteryInfo battery_info);
 };
diff --git a/components/autofill/android/provider/autofill_provider_android.cc b/components/autofill/android/provider/autofill_provider_android.cc
index 408ff96..85b68d3d 100644
--- a/components/autofill/android/provider/autofill_provider_android.cc
+++ b/components/autofill/android/provider/autofill_provider_android.cc
@@ -337,25 +337,7 @@
 
 void AutofillProviderAndroid::OnFormsSeen(AutofillHandlerProxy* handler,
                                           const std::vector<FormData>& forms,
-                                          const base::TimeTicks) {
-  handler_for_testing_ = handler->GetWeakPtr();
-  if (!check_submission_)
-    return;
-
-  if (handler != handler_.get())
-    return;
-
-  if (form_.get() == nullptr)
-    return;
-
-  for (auto const& form : forms) {
-    if (form_->SimilarFormAs(form))
-      return;
-  }
-  // The form_ disappeared after it was submitted, we consider the submission
-  // succeeded.
-  FireSuccessfulSubmission(pending_submission_source_);
-}
+                                          const base::TimeTicks timestamp) {}
 
 void AutofillProviderAndroid::OnHidePopup(AutofillHandlerProxy* handler) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -372,6 +354,12 @@
 void AutofillProviderAndroid::Reset(AutofillHandlerProxy* handler) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (handler == handler_.get()) {
+    // If we previously received a notification from the renderer that the form
+    // was likely submitted and no event caused a reset of state in the interim,
+    // we consider this navigation to be resulting from the submission.
+    if (check_submission_ && form_.get())
+      FireSuccessfulSubmission(pending_submission_source_);
+
     JNIEnv* env = AttachCurrentThread();
     ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
     if (obj.is_null())
diff --git a/components/autofill/android/provider/autofill_provider_android.h b/components/autofill/android/provider/autofill_provider_android.h
index b0830e23..5ed22d4 100644
--- a/components/autofill/android/provider/autofill_provider_android.h
+++ b/components/autofill/android/provider/autofill_provider_android.h
@@ -118,8 +118,6 @@
   // Valid only if check_submission_ is true.
   mojom::SubmissionSource pending_submission_source_;
 
-  base::WeakPtr<AutofillHandlerProxy> handler_for_testing_;
-
   DISALLOW_COPY_AND_ASSIGN(AutofillProviderAndroid);
 };
 }  // namespace autofill
diff --git a/components/browser_ui/site_settings/OWNERS b/components/browser_ui/site_settings/OWNERS
index b8659d3..51a2813f 100644
--- a/components/browser_ui/site_settings/OWNERS
+++ b/components/browser_ui/site_settings/OWNERS
@@ -1,7 +1,6 @@
 finnur@chromium.org
 hkamila@chromium.org
 andypaicu@chromium.org
-
-per-file CookieControls*=dullweber@chromium.org
+dullweber@chromium.org
 
 # COMPONENT: UI>Browser>Mobile>Settings
diff --git a/components/content_capture/common/content_capture_features.cc b/components/content_capture/common/content_capture_features.cc
index 58832c3..3258e664 100644
--- a/components/content_capture/common/content_capture_features.cc
+++ b/components/content_capture/common/content_capture_features.cc
@@ -16,7 +16,7 @@
                                     base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kContentCaptureTriggeringForExperiment{
-    "ContentCaptureTriggeringForExperiment", base::FEATURE_ENABLED_BY_DEFAULT};
+    "ContentCaptureTriggeringForExperiment", base::FEATURE_DISABLED_BY_DEFAULT};
 #else
 const base::Feature kContentCapture{"ContentCapture",
                                     base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc
index 859a792b..81f6995 100644
--- a/components/omnibox/browser/autocomplete_match.cc
+++ b/components/omnibox/browser/autocomplete_match.cc
@@ -973,6 +973,8 @@
       return OmniboxEventProto::Suggestion::CLIPBOARD_TEXT;
     case AutocompleteMatchType::CLIPBOARD_IMAGE:
       return OmniboxEventProto::Suggestion::CLIPBOARD_IMAGE;
+    case AutocompleteMatchType::TILE_SUGGESTION:
+      return OmniboxEventProto::Suggestion::TILE_SUGGESTION;
     case AutocompleteMatchType::VOICE_SUGGEST:
       // VOICE_SUGGEST matches are only used in Java and are not logged,
       // so we should never reach this case.
@@ -980,7 +982,6 @@
     case AutocompleteMatchType::PHYSICAL_WEB_DEPRECATED:
     case AutocompleteMatchType::PHYSICAL_WEB_OVERFLOW_DEPRECATED:
     case AutocompleteMatchType::TAB_SEARCH_DEPRECATED:
-    case AutocompleteMatchType::TILE_SUGGESTION:
     case AutocompleteMatchType::NUM_TYPES:
       break;
   }
diff --git a/components/page_info/page_info_ui.cc b/components/page_info/page_info_ui.cc
index 3da415e..982612b 100644
--- a/components/page_info/page_info_ui.cc
+++ b/components/page_info/page_info_ui.cc
@@ -639,7 +639,7 @@
       icon = &vector_icons::kVideogameAssetIcon;
       break;
     case ContentSettingsType::IDLE_DETECTION:
-      icon = &vector_icons::kIdleDetectionIcon;
+      icon = &vector_icons::kPersonIcon;
       break;
     default:
       // All other |ContentSettingsType|s do not have icons on desktop or are
diff --git a/components/permissions/android/res/drawable/permission_idle_detection.xml b/components/permissions/android/res/drawable/permission_idle_detection.xml
index 48b03075..301f353 100644
--- a/components/permissions/android/res/drawable/permission_idle_detection.xml
+++ b/components/permissions/android/res/drawable/permission_idle_detection.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--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.-->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools" tools:targetApi="21" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
-  <path android:pathData="M21,10.12h-6.78l2.74,-2.82c-2.73,-2.7 -7.15,-2.8 -9.88,-0.1c-2.73,2.71 -2.73,7.08 0,9.79s7.15,2.71 9.88,0C18.32,15.65 19,14.08 19,12.1h2c0,1.98 -0.88,4.55 -2.64,6.29c-3.51,3.48 -9.21,3.48 -12.72,0c-3.5,-3.47 -3.53,-9.11 -0.02,-12.58s9.14,-3.47 12.65,0L21,3V10.12zM12.5,8v4.25l3.5,2.08l-0.72,1.21L11,13V8H12.5z" android:fillColor="#000000"/>
+  <path android:pathData="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" android:fillColor="#000000"/>
 </vector>
diff --git a/components/permissions/permission_request_impl.cc b/components/permissions/permission_request_impl.cc
index fac2ab16..d2dc71ac 100644
--- a/components/permissions/permission_request_impl.cc
+++ b/components/permissions/permission_request_impl.cc
@@ -105,7 +105,7 @@
     case ContentSettingsType::FONT_ACCESS:
       return vector_icons::kFontDownloadIcon;
     case ContentSettingsType::IDLE_DETECTION:
-      return vector_icons::kIdleDetectionIcon;
+      return vector_icons::kPersonIcon;
     default:
       NOTREACHED();
       return vector_icons::kExtensionIcon;
diff --git a/components/vector_icons/BUILD.gn b/components/vector_icons/BUILD.gn
index 224f4217..9bc67ec 100644
--- a/components/vector_icons/BUILD.gn
+++ b/components/vector_icons/BUILD.gn
@@ -42,7 +42,6 @@
     "headset.icon",
     "help.icon",
     "help_outline.icon",
-    "idle_detection.icon",
     "info_outline.icon",
     "insert_drive_file_outline.icon",
     "launch.icon",
@@ -65,6 +64,7 @@
     "open_in_new.icon",
     "page_info_content_paste.icon",
     "pause.icon",
+    "person.icon",
     "photo.icon",
     "play_arrow.icon",
     "protected_content.icon",
diff --git a/components/vector_icons/idle_detection.icon b/components/vector_icons/idle_detection.icon
deleted file mode 100644
index 80aafb0..0000000
--- a/components/vector_icons/idle_detection.icon
+++ /dev/null
@@ -1,28 +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.
-
-CANVAS_DIMENSIONS, 24,
-MOVE_TO, 21, 10.12f,
-R_H_LINE_TO, -6.78f,
-R_LINE_TO, 2.74f, -2.82f,
-R_CUBIC_TO, -2.73f, -2.7f, -7.15f, -2.8f, -9.88f, -0.1f,
-R_CUBIC_TO, -2.73f, 2.71f, -2.73f, 7.08f, 0, 9.79f,
-R_CUBIC_TO, 2.73f, 2.71f, 7.15f, 2.71f, 9.88f, 0,
-CUBIC_TO, 18.32f, 15.65f, 19, 14.08f, 19, 12.1f,
-R_H_LINE_TO, 2,
-R_CUBIC_TO, 0, 1.98f, -0.88f, 4.55f, -2.64f, 6.29f,
-R_CUBIC_TO, -3.51f, 3.48f, -9.21f, 3.48f, -12.72f, 0,
-R_CUBIC_TO, -3.5f, -3.47f, -3.53f, -9.11f, -0.02f, -12.58f,
-R_CUBIC_TO, 3.51f, -3.47f, 9.14f, -3.47f, 12.65f, 0,
-LINE_TO, 21, 3,
-V_LINE_TO, 10.12f,
-CLOSE,
-MOVE_TO, 12.5f, 8,
-R_V_LINE_TO, 4.25f,
-R_LINE_TO, 3.5f, 2.08f,
-R_LINE_TO, -0.72f, 1.21f,
-LINE_TO, 11, 13,
-V_LINE_TO, 8,
-H_LINE_TO, 12.5f,
-CLOSE
diff --git a/components/vector_icons/person.icon b/components/vector_icons/person.icon
new file mode 100644
index 0000000..2a06e2a
--- /dev/null
+++ b/components/vector_icons/person.icon
@@ -0,0 +1,18 @@
+// 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.
+
+CANVAS_DIMENSIONS, 24,
+MOVE_TO, 12, 12,
+R_CUBIC_TO, 2.21f, 0, 4, -1.79f, 4, -4,
+R_CUBIC_TO, 0, -2.21f, -1.79f, -4, -4, -4,
+R_CUBIC_TO, -2.21f, 0, -4, 1.79f, -4, 4,
+R_CUBIC_TO, 0, 2.21f, 1.79f, 4, 4, 4,
+CLOSE,
+R_MOVE_TO, 0, 2,
+R_CUBIC_TO, -2.67f, 0, -8, 1.34f, -8, 4,
+R_V_LINE_TO, 2,
+R_H_LINE_TO, 16,
+R_V_LINE_TO, -2,
+R_CUBIC_TO, 0, -2.66f, -5.33f, -4, -8, -4,
+CLOSE
diff --git a/content/browser/loader/quic_transport_browsertest.cc b/content/browser/loader/quic_transport_browsertest.cc
index 7c3f53a..73ec95f2 100644
--- a/content/browser/loader/quic_transport_browsertest.cc
+++ b/content/browser/loader/quic_transport_browsertest.cc
@@ -422,5 +422,76 @@
   ASSERT_TRUE(WaitForTitle(ASCIIToUTF16("PASS"), {ASCIIToUTF16("FAIL")}));
 }
 
+IN_PROC_BROWSER_TEST_F(QuicTransportBrowserTest, ReceiveBidirectionalStream) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  ASSERT_TRUE(
+      NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html")));
+
+  ASSERT_TRUE(WaitForTitle(ASCIIToUTF16("Title Of Awesomeness")));
+
+  ASSERT_TRUE(ExecuteScript(
+      shell(), base::StringPrintf(R"JS(
+    async function run() {
+      const transport = new QuicTransport(
+        'quic-transport://localhost:%d/receive-bidirectional');
+
+      await transport.ready;
+
+      // Trigger the server to create a bidirectional stream.
+      const sendStream = await transport.createSendStream();
+      // Need to actually write some data to inform the server.
+      sendStream.writable.getWriter().write(new Uint8Array([1]));
+
+      const streams = transport.receiveBidirectionalStreams();
+      const reader = streams.getReader();
+      const {value, done} = await reader.read();
+      if (done) {
+        throw new Error('bidirectional streams should not be closed');
+      }
+      await testBidiStream(value);
+    }
+
+    async function testBidiStream(bidiStream) {
+      // Consume the initial "hello" that is sent by the server.
+      const reader = bidiStream.readable.getReader();
+      const {value: valueAsBinary, done: done0} = await reader.read();
+      if (done0) {
+        throw new Error('at least one read should happen');
+      }
+      const valueAsString = new TextDecoder().decode(valueAsBinary);
+      if (valueAsString !== 'hello') {
+        throw new Error(`expected 'hello', got '${valueAsString}'`);
+      }
+
+      const data = [65, 66, 67];
+
+      const writer = bidiStream.writable.getWriter();
+      await writer.write(new Uint8Array(data));
+
+      const {value, done: done1} = await reader.read();
+      if (done1) {
+        throw new Error('reading should not be done');
+      }
+      const actual = Array.from(value);
+      if (JSON.stringify(actual) !== JSON.stringify(data)) {
+        throw new Error('arrays do not match');
+      }
+
+      await writer.close();
+
+      const {done: done2} = await reader.read();
+      if (!done2) {
+        throw new Error('receiveStream should be done');
+      }
+    }
+
+    run().then(() => { document.title = 'PASS'; },
+               (e) => { console.log(e); document.title = 'FAIL'; });
+)JS",
+                                  server_.server_address().port())));
+
+  ASSERT_TRUE(WaitForTitle(ASCIIToUTF16("PASS"), {ASCIIToUTF16("FAIL")}));
+}
+
 }  // namespace
 }  // namespace content
diff --git a/content/browser/payments/payment_app_browsertest.cc b/content/browser/payments/payment_app_browsertest.cc
index 81f7db3a..08e6dae 100644
--- a/content/browser/payments/payment_app_browsertest.cc
+++ b/content/browser/payments/payment_app_browsertest.cc
@@ -295,8 +295,9 @@
   ClearStoragePartitionData();
 }
 
-// TODO(crbug.com/869790) Flakes on linux-chromeos-dbg
-#if defined(OS_CHROMEOS) && !defined(NDEBUG)
+// TODO(https://crbug.com/1129411) Fix flake on all desktop platforms.
+#if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MAC) || \
+    defined(OS_WIN)
 #define MAYBE_CanMakePayment DISABLED_CanMakePayment
 #else
 #define MAYBE_CanMakePayment CanMakePayment
@@ -351,8 +352,9 @@
   ClearStoragePartitionData();
 }
 
-// TODO(crbug.com/869790) Flakes on linux-chromeos-dbg
-#if defined(OS_CHROMEOS) && !defined(NDEBUG)
+// TODO(https://crbug.com/1129411) Fix flake on all desktop platforms.
+#if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MAC) || \
+    defined(OS_WIN)
 #define MAYBE_PaymentAppInvocation DISABLED_PaymentAppInvocation
 #else
 #define MAYBE_PaymentAppInvocation PaymentAppInvocation
@@ -393,8 +395,9 @@
             PopConsoleString() /* instrumentKey */);
 }
 
-// TODO(crbug.com/869790) Flakes on linux-chromeos-dbg
-#if defined(OS_CHROMEOS) && !defined(NDEBUG)
+// TODO(https://crbug.com/1129411) Fix flake on all desktop platforms.
+#if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_MAC) || \
+    defined(OS_WIN)
 #define MAYBE_PaymentAppOpenWindowFailed DISABLED_PaymentAppOpenWindowFailed
 #else
 #define MAYBE_PaymentAppOpenWindowFailed PaymentAppOpenWindowFailed
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 54f63e0..00365af8 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -4473,32 +4473,19 @@
     render_process_host = GetUnusedProcessHostForServiceWorker(site_instance);
   }
 
-  if (render_process_host) {
-    site_instance->set_process_assignment(
-        SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS);
-  }
-
   // See if the spare RenderProcessHost can be used.
   auto& spare_process_manager = SpareRenderProcessHostManager::GetInstance();
   bool spare_was_taken = false;
   if (!render_process_host) {
     render_process_host = spare_process_manager.MaybeTakeSpareRenderProcessHost(
         browser_context, site_instance);
-    if (render_process_host) {
-      site_instance->set_process_assignment(
-          SiteInstanceProcessAssignment::USED_SPARE_PROCESS);
-      spare_was_taken = true;
-    }
+    spare_was_taken = (render_process_host != nullptr);
   }
 
   // If not (or if none found), see if we should reuse an existing process.
   if (!render_process_host && ShouldTryToUseExistingProcessHost(
                                   browser_context, site_info.site_url())) {
     render_process_host = GetExistingProcessHost(site_instance);
-    if (render_process_host) {
-      site_instance->set_process_assignment(
-          SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS);
-    }
   }
 
   // If we found a process to reuse, sanity check that it is suitable for
@@ -4524,9 +4511,6 @@
     // issues as TestBrowserContext initialization is done on the main thread.
     render_process_host =
         CreateRenderProcessHost(browser_context, site_instance);
-
-    site_instance->set_process_assignment(
-        SiteInstanceProcessAssignment::CREATED_NEW_PROCESS);
   }
 
   // It is important to call PrepareForFutureRequests *after* potentially
diff --git a/content/browser/renderer_host/render_process_host_unittest.cc b/content/browser/renderer_host/render_process_host_unittest.cc
index 2a0b3b0..e9c43852 100644
--- a/content/browser/renderer_host/render_process_host_unittest.cc
+++ b/content/browser/renderer_host/render_process_host_unittest.cc
@@ -81,7 +81,7 @@
   // Verify that the renderer sharing will happen.
   GURL test_url("http://foo.com");
   EXPECT_TRUE(RenderProcessHostImpl::ShouldTryToUseExistingProcessHost(
-      browser_context(), test_url));
+        browser_context(), test_url));
 }
 #endif
 
@@ -97,7 +97,7 @@
   // Verify that the renderer sharing still won't happen.
   GURL test_url("http://foo.com");
   EXPECT_FALSE(RenderProcessHostImpl::ShouldTryToUseExistingProcessHost(
-      browser_context(), test_url));
+        browser_context(), test_url));
 }
 #endif
 
@@ -112,8 +112,6 @@
       SiteInstanceImpl::CreateReusableInstanceForTesting(browser_context(),
                                                          kUrl1);
   EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess());
-  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            site_instance->GetLastProcessAssignmentOutcome());
 
   // Have the main frame navigate to the first url. Getting a RenderProcessHost
   // with the REUSE_PENDING_OR_COMMITTED_SITE policy should now return the
@@ -122,8 +120,6 @@
   site_instance = SiteInstanceImpl::CreateReusableInstanceForTesting(
       browser_context(), kUrl1);
   EXPECT_EQ(main_test_rfh()->GetProcess(), site_instance->GetProcess());
-  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
-            site_instance->GetLastProcessAssignmentOutcome());
 
   // Navigate away. Getting a RenderProcessHost with the
   // REUSE_PENDING_OR_COMMITTED_SITE policy should again return a new process.
@@ -131,11 +127,6 @@
   site_instance = SiteInstanceImpl::CreateReusableInstanceForTesting(
       browser_context(), kUrl1);
   EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess());
-  EXPECT_EQ(RenderProcessHostImpl::IsSpareProcessKeptAtAllTimes()
-                ? SiteInstanceProcessAssignment::USED_SPARE_PROCESS
-                : SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            site_instance->GetLastProcessAssignmentOutcome());
-
   // Now add a subframe that navigates to kUrl1. Getting a RenderProcessHost
   // with the REUSE_PENDING_OR_COMMITTED_SITE policy for kUrl1 should now
   // return the process of the subframe RFH.
@@ -155,8 +146,6 @@
   site_instance = SiteInstanceImpl::CreateReusableInstanceForTesting(
       browser_context(), kUrl1);
   EXPECT_EQ(subframe->GetProcess(), site_instance->GetProcess());
-  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
-            site_instance->GetLastProcessAssignmentOutcome());
 }
 
 // Check that only new processes that haven't yet hosted any web content are
@@ -196,8 +185,6 @@
   scoped_refptr<SiteInstanceImpl> sw_site_instance1 =
       SiteInstanceImpl::CreateForServiceWorker(browser_context(), kUrl);
   RenderProcessHost* sw_host1 = sw_site_instance1->GetProcess();
-  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            sw_site_instance1->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a service worker with DEFAULT reuse policy
   // should not reuse the existing service worker's process. We create this
@@ -206,16 +193,12 @@
       SiteInstanceImpl::CreateForServiceWorker(browser_context(), kUrl);
   RenderProcessHost* sw_host2 = sw_site_instance2->GetProcess();
   EXPECT_NE(sw_host1, sw_host2);
-  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            sw_site_instance2->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a navigation to the same site must reuse
   // the newest unmatched service worker's process (i.e., sw_host2).
   scoped_refptr<SiteInstanceImpl> site_instance1 =
       SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
   EXPECT_EQ(sw_host2, site_instance1->GetProcess());
-  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
-            site_instance1->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a navigation to the same site must reuse
   // the newest unmatched service worker's process (i.e., sw_host1). sw_host2
@@ -224,8 +207,6 @@
   scoped_refptr<SiteInstanceImpl> site_instance2 =
       SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
   EXPECT_EQ(sw_host1, site_instance2->GetProcess());
-  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
-            site_instance2->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a navigation should return a new process
   // because there is no unmatched service worker's process.
@@ -233,8 +214,6 @@
       SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
   EXPECT_NE(sw_host1, site_instance3->GetProcess());
   EXPECT_NE(sw_host2, site_instance3->GetProcess());
-  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            site_instance3->GetLastProcessAssignmentOutcome());
 }
 
 class UnsuitableHostContentBrowserClient : public ContentBrowserClient {
@@ -259,8 +238,6 @@
   scoped_refptr<SiteInstanceImpl> sw_site_instance =
       SiteInstanceImpl::CreateForServiceWorker(browser_context(), kUrl);
   RenderProcessHost* sw_host = sw_site_instance->GetProcess();
-  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            sw_site_instance->GetLastProcessAssignmentOutcome());
 
   // Simulate a situation where |sw_host| won't be considered suitable for
   // future navigations to |kUrl|.  In https://crbug.com/782349, this happened
@@ -281,8 +258,6 @@
   scoped_refptr<SiteInstanceImpl> site_instance =
       SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
   EXPECT_NE(sw_host, site_instance->GetProcess());
-  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            sw_site_instance->GetLastProcessAssignmentOutcome());
 
   SetBrowserClientForTesting(regular_client);
 }
@@ -295,8 +270,6 @@
       SiteInstanceImpl::CreateForServiceWorker(browser_context(), kUrl,
                                                /* can_reuse_process */ true);
   RenderProcessHost* sw_host1 = sw_site_instance1->GetProcess();
-  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            sw_site_instance1->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a service worker with DEFAULT reuse policy
   // should not reuse the existing service worker's process. This is because
@@ -307,8 +280,6 @@
       SiteInstanceImpl::CreateForServiceWorker(browser_context(), kUrl);
   RenderProcessHost* sw_host2 = sw_site_instance2->GetProcess();
   EXPECT_NE(sw_host1, sw_host2);
-  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            sw_site_instance2->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a service worker of the same site with
   // REUSE_PENDING_OR_COMMITTED_SITE reuse policy should reuse the newest
@@ -318,8 +289,6 @@
                                                /* can_reuse_process */ true);
   RenderProcessHost* sw_host3 = sw_site_instance3->GetProcess();
   EXPECT_EQ(sw_host2, sw_host3);
-  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
-            sw_site_instance3->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a service worker of the same site with
   // REUSE_PENDING_OR_COMMITTED_SITE reuse policy should reuse the newest
@@ -331,16 +300,12 @@
                                                /* can_reuse_process */ true);
   RenderProcessHost* sw_host4 = sw_site_instance4->GetProcess();
   EXPECT_EQ(sw_host2, sw_host4);
-  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
-            sw_site_instance4->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a navigation to the same site must reuse
   // the newest unmatched service worker's process (i.e., sw_host2).
   scoped_refptr<SiteInstanceImpl> site_instance1 =
       SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
   EXPECT_EQ(sw_host2, site_instance1->GetProcess());
-  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
-            site_instance1->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a navigation to the same site must reuse
   // the newest unmatched service worker's process (i.e., sw_host1). sw_host2
@@ -349,8 +314,6 @@
   scoped_refptr<SiteInstanceImpl> site_instance2 =
       SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
   EXPECT_EQ(sw_host1, site_instance2->GetProcess());
-  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
-            site_instance2->GetLastProcessAssignmentOutcome());
 }
 
 TEST_F(RenderProcessHostUnitTest,
@@ -363,8 +326,6 @@
   scoped_refptr<SiteInstanceImpl> sw_site_instance1 =
       SiteInstanceImpl::CreateForServiceWorker(browser_context(), kUrl);
   RenderProcessHost* sw_host1 = sw_site_instance1->GetProcess();
-  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            sw_site_instance1->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a service worker of the same site with
   // process-per-site flag should reuse the unmatched service worker's process.
@@ -372,8 +333,6 @@
       SiteInstanceImpl::CreateForServiceWorker(browser_context(), kUrl);
   RenderProcessHost* sw_host2 = sw_site_instance2->GetProcess();
   EXPECT_EQ(sw_host1, sw_host2);
-  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
-            sw_site_instance2->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a navigation to the same site with
   // process-per-site flag should reuse the unmatched service worker's process.
@@ -381,8 +340,6 @@
       SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
   RenderProcessHost* sw_host3 = sw_site_instance3->GetProcess();
   EXPECT_EQ(sw_host1, sw_host3);
-  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
-            sw_site_instance3->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a navigation to the same site again with
   // process-per-site flag should reuse the unmatched service worker's process.
@@ -390,8 +347,6 @@
       SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
   RenderProcessHost* sw_host4 = sw_site_instance4->GetProcess();
   EXPECT_EQ(sw_host1, sw_host4);
-  EXPECT_EQ(SiteInstanceProcessAssignment::REUSED_EXISTING_PROCESS,
-            sw_site_instance4->GetLastProcessAssignmentOutcome());
 }
 
 TEST_F(RenderProcessHostUnitTest, DoNotReuseOtherSiteServiceWorkerProcess) {
@@ -402,16 +357,12 @@
   scoped_refptr<SiteInstanceImpl> sw_site_instance1 =
       SiteInstanceImpl::CreateForServiceWorker(browser_context(), kUrl1);
   RenderProcessHost* sw_host1 = sw_site_instance1->GetProcess();
-  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            sw_site_instance1->GetLastProcessAssignmentOutcome());
 
   // Getting a RenderProcessHost for a service worker of a different site should
   // return a new process because there is no reusable process.
   scoped_refptr<SiteInstanceImpl> sw_site_instance2 =
       SiteInstanceImpl::CreateForURL(browser_context(), kUrl2);
   EXPECT_NE(sw_host1, sw_site_instance2->GetProcess());
-  EXPECT_EQ(SiteInstanceProcessAssignment::CREATED_NEW_PROCESS,
-            sw_site_instance2->GetLastProcessAssignmentOutcome());
 }
 
 // Tests that RenderProcessHost will not consider reusing a process that has
@@ -915,18 +866,6 @@
   }
 }
 
-// Checks that SiteInstanceProcessAssignment::UNKNOWN is used as the zero-value
-// when no renderer process has been assigned to the SiteInstance yet.
-TEST_F(RenderProcessHostUnitTest, ProcessAssignmentDefault) {
-  const GURL kUrl("https://foo.com");
-
-  scoped_refptr<SiteInstanceImpl> site_instance =
-      SiteInstanceImpl::CreateForURL(browser_context(), kUrl);
-  EXPECT_EQ(SiteInstanceProcessAssignment::UNKNOWN,
-            site_instance->GetLastProcessAssignmentOutcome());
-  EXPECT_FALSE(site_instance->HasProcess());
-}
-
 class SpareRenderProcessHostUnitTest : public RenderViewHostImplTestHarness {
  public:
   SpareRenderProcessHostUnitTest() {}
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc
index 7eb2353..ed973ac9 100644
--- a/content/browser/site_instance_impl.cc
+++ b/content/browser/site_instance_impl.cc
@@ -163,8 +163,7 @@
       has_site_(false),
       process_reuse_policy_(ProcessReusePolicy::DEFAULT),
       is_for_service_worker_(false),
-      is_guest_(false),
-      process_assignment_(SiteInstanceProcessAssignment::UNKNOWN) {
+      is_guest_(false) {
   DCHECK(browsing_instance);
 }
 
@@ -499,8 +498,8 @@
 void SiteInstanceImpl::SetSite(const GURL& url) {
   // TODO(creis): Consider calling ShouldAssignSiteForURL internally, rather
   // than before multiple call sites.  See https://crbug.com/949220.
-  TRACE_EVENT2("navigation", "SiteInstanceImpl::SetSite", "site id", id_, "url",
-               url.possibly_invalid_spec());
+  TRACE_EVENT2("navigation", "SiteInstanceImpl::SetSite",
+               "site id", id_, "url", url.possibly_invalid_spec());
   // A SiteInstance's site should not change.
   // TODO(creis): When following links or script navigations, we can currently
   // render pages from other sites in this SiteInstance.  This will eventually
@@ -581,11 +580,6 @@
   SetSite(url);
 }
 
-SiteInstanceProcessAssignment
-SiteInstanceImpl::GetLastProcessAssignmentOutcome() {
-  return process_assignment_;
-}
-
 const GURL& SiteInstanceImpl::GetSiteURL() {
   return site_info_.site_url();
 }
@@ -613,9 +607,8 @@
 }
 
 bool SiteInstanceImpl::IsRelatedSiteInstance(const SiteInstance* instance) {
-  return browsing_instance_.get() ==
-         static_cast<const SiteInstanceImpl*>(instance)
-             ->browsing_instance_.get();
+  return browsing_instance_.get() == static_cast<const SiteInstanceImpl*>(
+                                         instance)->browsing_instance_.get();
 }
 
 size_t SiteInstanceImpl::GetRelatedActiveContentsCount() {
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h
index c8ae97da..ecebcc5 100644
--- a/content/browser/site_instance_impl.h
+++ b/content/browser/site_instance_impl.h
@@ -236,13 +236,6 @@
   bool RequiresDedicatedProcess() override;
   bool IsSameSiteWithURL(const GURL& url) override;
   bool IsGuest() override;
-  SiteInstanceProcessAssignment GetLastProcessAssignmentOutcome() override;
-
-  // This is called every time a renderer process is assigned to a SiteInstance
-  // and is used by the content embedder for collecting metrics.
-  void set_process_assignment(SiteInstanceProcessAssignment assignment) {
-    process_assignment_ = assignment;
-  }
 
   // The policy to apply when selecting a RenderProcessHost for the
   // SiteInstance. If no suitable RenderProcessHost for the SiteInstance exists
@@ -458,7 +451,8 @@
   // hosts.
   // Only public so that we can make a consistent process swap decision in
   // RenderFrameHostManager.
-  static GURL GetEffectiveURL(BrowserContext* browser_context, const GURL& url);
+  static GURL GetEffectiveURL(BrowserContext* browser_context,
+                              const GURL& url);
 
   // Returns true if pages loaded from |site_info| ought to be handled only by a
   // renderer process isolated from other sites. If --site-per-process is used,
@@ -693,9 +687,6 @@
   // TODO(734722): Move this into the SecurityPrincipal once it is available.
   bool is_guest_;
 
-  // How |this| was last assigned to a renderer process.
-  SiteInstanceProcessAssignment process_assignment_;
-
   base::ObserverList<Observer, true>::Unchecked observers_;
 
   DISALLOW_COPY_AND_ASSIGN(SiteInstanceImpl);
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index 309e4a8..e9202703 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -341,7 +341,6 @@
     "shared_worker_instance.h",
     "shared_worker_service.h",
     "site_instance.h",
-    "site_instance_process_assignment.h",
     "site_isolation_policy.cc",
     "site_isolation_policy.h",
     "sms_fetcher.h",
diff --git a/content/public/browser/site_instance.h b/content/public/browser/site_instance.h
index a721f2f..0e6c3d0 100644
--- a/content/public/browser/site_instance.h
+++ b/content/public/browser/site_instance.h
@@ -10,7 +10,6 @@
 
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
-#include "content/public/browser/site_instance_process_assignment.h"
 #include "url/gurl.h"
 
 namespace content {
@@ -170,12 +169,6 @@
   // Returns true if this object is used for a <webview> guest.
   virtual bool IsGuest() = 0;
 
-  // Returns how this SiteInstance was assigned to a renderer process the most
-  // recent time that such an assignment was done. This allows the content
-  // embedder to collect metrics on how renderer process starting or reuse
-  // affects performance.
-  virtual SiteInstanceProcessAssignment GetLastProcessAssignmentOutcome() = 0;
-
   // Factory method to create a new SiteInstance.  This will create a new
   // BrowsingInstance, so it should only be used when creating a new tab from
   // scratch (or similar circumstances).
diff --git a/content/public/browser/site_instance_process_assignment.h b/content/public/browser/site_instance_process_assignment.h
deleted file mode 100644
index 04cfd1f..0000000
--- a/content/public/browser/site_instance_process_assignment.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 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 CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_PROCESS_ASSIGNMENT_H_
-#define CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_PROCESS_ASSIGNMENT_H_
-
-namespace content {
-
-// This enum describes how a renderer process is assigned to a SiteInstance.
-enum class SiteInstanceProcessAssignment {
-  // No renderer process has been assigned to the SiteInstance yet.
-  UNKNOWN,
-
-  // Reused some pre-existing process.
-  REUSED_EXISTING_PROCESS,
-
-  // Used an existing spare process.
-  USED_SPARE_PROCESS,
-
-  // No renderer could be reused, so a new one was created for the SiteInstance.
-  CREATED_NEW_PROCESS,
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_PROCESS_ASSIGNMENT_H_
diff --git a/content/test/gpu/gpu_tests/skia_gold/gpu_skia_gold_session_manager.py b/content/test/gpu/gpu_tests/skia_gold/gpu_skia_gold_session_manager.py
index 6fe4207..d1b7e23 100644
--- a/content/test/gpu/gpu_tests/skia_gold/gpu_skia_gold_session_manager.py
+++ b/content/test/gpu/gpu_tests/skia_gold/gpu_skia_gold_session_manager.py
@@ -13,7 +13,7 @@
 class GpuSkiaGoldSessionManager(sgsm.SkiaGoldSessionManager):
   @staticmethod
   def _GetDefaultInstance():
-    return 'chrome-gpu'
+    return 'chrome'
 
   @staticmethod
   def _GetSessionClass():
diff --git a/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py b/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py
index 8233720..b720910 100644
--- a/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py
+++ b/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py
@@ -29,8 +29,7 @@
     os.path.join(path_util.GetChromiumSrcDir(), 'media/test/data'),
 ]
 
-SKIA_GOLD_INSTANCE = 'chrome-gpu'
-SKIA_GOLD_CORPUS = SKIA_GOLD_INSTANCE
+SKIA_GOLD_CORPUS = 'chrome-gpu'
 
 
 class _ImageParameters(object):
@@ -344,25 +343,13 @@
 
     gpu_keys = self.GetGoldJsonKeys(page)
     gold_session = self.GetSkiaGoldSessionManager().GetSkiaGoldSession(
-        gpu_keys, corpus=SKIA_GOLD_CORPUS, instance='chrome')
+        gpu_keys, corpus=SKIA_GOLD_CORPUS)
     gold_properties = self.GetSkiaGoldProperties()
     use_luci = not (gold_properties.local_pixel_tests
                     or gold_properties.no_luci_auth)
 
     inexact_matching_args = page.matching_algorithm.GetCmdline()
 
-    # TODO(crbug.com/1113308): Switch the FYI session to the only session once
-    # all the data is migrated to the Chrome Gold instance.
-    status, error = gold_session.RunComparison(
-        name=image_name,
-        png_file=png_temp_file,
-        inexact_matching_args=inexact_matching_args,
-        use_luci=use_luci)
-    if status:
-      logging.warning('FYI Gold comparison failed with status %s and error %s',
-                      status, error)
-
-    gold_session = self.GetSkiaGoldSessionManager().GetSkiaGoldSession(gpu_keys)
     status, error = gold_session.RunComparison(
         name=image_name,
         png_file=png_temp_file,
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc
index d8d31f4..bacd6d5 100644
--- a/gpu/command_buffer/service/webgpu_decoder_impl.cc
+++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -652,6 +652,10 @@
     device_descriptor.requiredExtensions.push_back("shader_float16");
   }
 
+  if (request_device_properties.timestampQuery) {
+    device_descriptor.requiredExtensions.push_back("timestamp_query");
+  }
+
   WGPUDevice wgpu_device =
       dawn_adapters_[requested_adapter_index].CreateDevice(&device_descriptor);
   if (wgpu_device == nullptr) {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_app_interface.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_app_interface.h
index 429cc58..ffdae458 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_app_interface.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_app_interface.h
@@ -46,8 +46,11 @@
 + (void)resetWhatsNewPromo;
 
 // Returns the width the search field is supposed to have when the collection
-// has |collectionWidth|.
-+ (CGFloat)searchFieldWidthForCollectionWidth:(CGFloat)collectionWidth;
+// has |collectionWidth|. |traitCollection| is the trait collection of the view
+// displaying the omnibox, its Size Class is used in the computation.
++ (CGFloat)searchFieldWidthForCollectionWidth:(CGFloat)collectionWidth
+                              traitCollection:
+                                  (UITraitCollection*)traitCollection;
 
 // Returns the collection view.
 + (UICollectionView*)collectionView;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_app_interface.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_app_interface.mm
index 75a50f8..480e11e 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_app_interface.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_app_interface.mm
@@ -178,8 +178,11 @@
   ios::NotificationPromo::MigrateUserPrefs(local_state);
 }
 
-+ (CGFloat)searchFieldWidthForCollectionWidth:(CGFloat)collectionWidth {
-  return content_suggestions::searchFieldWidth(collectionWidth);
++ (CGFloat)searchFieldWidthForCollectionWidth:(CGFloat)collectionWidth
+                              traitCollection:
+                                  (UITraitCollection*)traitCollection {
+  return content_suggestions::searchFieldWidth(collectionWidth,
+                                               traitCollection);
 }
 
 + (UICollectionView*)collectionView {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h
index 243871850..3b5e48c 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h
@@ -14,26 +14,35 @@
 extern const CGFloat kHintTextScale;
 
 // Returns the proper height for the doodle. |logoIsShowing| refers to the
-// Google logo or the doodle.
-CGFloat doodleHeight(BOOL logoIsShowing);
+// Google logo or the doodle. The SizeClass of the |traitCollection| of the view
+// displaying the doodle is used in the computation.
+CGFloat doodleHeight(BOOL logoIsShowing, UITraitCollection* traitCollection);
 // Returns the proper margin to the top of the header for the doodle.
 // If |toolbarPresent| is true, the top margin include a space to display the
-// toolbar.  Adds |topInset| to non-RxR displays.
-CGFloat doodleTopMargin(BOOL toolbarPresent, CGFloat topInset);
+// toolbar.  Adds |topInset| to non-RxR displays. The SizeClass of the
+// |traitCollection| of the view displaying the doodle is used.
+CGFloat doodleTopMargin(BOOL toolbarPresent,
+                        CGFloat topInset,
+                        UITraitCollection* traitCollection);
 // Returns the proper margin to the bottom of the doodle for the search field.
 CGFloat searchFieldTopMargin();
 // Returns the proper width for the search field inside a view with a |width|.
-CGFloat searchFieldWidth(CGFloat superviewWidth);
+// The SizeClass of the |traitCollection| of the view displaying the search
+// field is used in the computation.
+CGFloat searchFieldWidth(CGFloat superviewWidth,
+                         UITraitCollection* traitCollection);
 // TODO(crbug.com/761817): Remove |toolbarPresent| once the transition to the
 // new architecture is completed.
 // Returns the expected height of the header. |logoIsShowing| refers to the
 // Google logo or the doodle. |promoCanShow| represents whether a what's new
 // promo can be displayed.  |toolbarPresent| represent whether the height should
-// take into account a space to show the toolbar.
+// take into account a space to show the toolbar. The SizeClass of the
+// |traitCollection| of the view displaying the logo is used in the computation.
 CGFloat heightForLogoHeader(BOOL logoIsShowing,
                             BOOL promoCanShow,
                             BOOL toolbarPresent,
-                            CGFloat topInset);
+                            CGFloat topInset,
+                            UITraitCollection* traitCollection);
 // Configure the |searchHintLabel| for the fake omnibox.  |hintLabelContainer|
 // is added to the |searchTapTarget| with autolayout and |searchHintLabel| is
 // added to |hintLabelContainer| with autoresizing.  This is done due to the
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
index e899216..3b3a982f 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
@@ -58,17 +58,19 @@
 const int kSearchFieldBackgroundColor = 0xF1F3F4;
 const CGFloat kHintTextScale = 0.15;
 
-CGFloat doodleHeight(BOOL logoIsShowing) {
-  if (!IsRegularXRegularSizeClass() && !logoIsShowing)
+CGFloat doodleHeight(BOOL logoIsShowing, UITraitCollection* traitCollection) {
+  if (!IsRegularXRegularSizeClass(traitCollection) && !logoIsShowing)
     return kNonGoogleSearchDoodleHeight;
 
   return kGoogleSearchDoodleHeight;
 }
 
-CGFloat doodleTopMargin(BOOL toolbarPresent, CGFloat topInset) {
-  if (!IsCompactWidth() && !IsCompactHeight())
+CGFloat doodleTopMargin(BOOL toolbarPresent,
+                        CGFloat topInset,
+                        UITraitCollection* traitCollection) {
+  if (IsRegularXRegularSizeClass(traitCollection))
     return kDoodleTopMarginRegularXRegular;
-  if (IsCompactHeight())
+  if (IsCompactHeight(traitCollection))
     return topInset;
   return topInset + kDoodleTopMarginOther +
          AlignValueToPixel(kDoodleScaledTopMarginOther *
@@ -79,8 +81,9 @@
   return kSearchFieldTopMargin;
 }
 
-CGFloat searchFieldWidth(CGFloat superviewWidth) {
-  if (!IsCompactWidth() && !IsCompactHeight())
+CGFloat searchFieldWidth(CGFloat superviewWidth,
+                         UITraitCollection* traitCollection) {
+  if (!IsCompactWidth(traitCollection) && !IsCompactHeight(traitCollection))
     return kSearchFieldLarge;
 
   // Special case for narrow sizes.
@@ -90,14 +93,15 @@
 CGFloat heightForLogoHeader(BOOL logoIsShowing,
                             BOOL promoCanShow,
                             BOOL toolbarPresent,
-                            CGFloat topInset) {
+                            CGFloat topInset,
+                            UITraitCollection* traitCollection) {
   CGFloat headerHeight =
-      doodleTopMargin(toolbarPresent, topInset) + doodleHeight(logoIsShowing) +
-      searchFieldTopMargin() +
+      doodleTopMargin(toolbarPresent, topInset, traitCollection) +
+      doodleHeight(logoIsShowing, traitCollection) + searchFieldTopMargin() +
       ToolbarExpandedHeight(
           [UIApplication sharedApplication].preferredContentSizeCategory) +
       kNTPSearchFieldBottomPadding;
-  if (!IsRegularXRegularSizeClass()) {
+  if (!IsRegularXRegularSizeClass(traitCollection)) {
     return headerHeight;
   }
   if (!logoIsShowing) {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm
index 4dd94ebb..e5aad302 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm
@@ -21,86 +21,41 @@
 
 class ContentSuggestionsCollectionUtilsTest : public PlatformTest {
  public:
-  void SetAsIPad() {
+  UITraitCollection* IPadTraitCollection() {
     UITraitCollection* horizontalRegular = [UITraitCollection
         traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
     UITraitCollection* verticalRegular = [UITraitCollection
         traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassRegular];
-    UITraitCollection* custom_trait_collection =
-        [UITraitCollection traitCollectionWithTraitsFromCollections:@[
-          verticalRegular, horizontalRegular
-        ]];
-
-    SetSwizzlersUp(custom_trait_collection, UIUserInterfaceIdiomPad,
-                   UIInterfaceOrientationPortrait);
+    return [UITraitCollection traitCollectionWithTraitsFromCollections:@[
+      verticalRegular, horizontalRegular
+    ]];
   }
 
-  void SetAsIPhoneLandscape() {
+  UITraitCollection* IPhoneLandscapeTraitCollection() {
     UITraitCollection* horizontalCompact = [UITraitCollection
         traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
     UITraitCollection* verticalCompact = [UITraitCollection
         traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact];
-    UITraitCollection* custom_trait_collection =
-        [UITraitCollection traitCollectionWithTraitsFromCollections:@[
-          verticalCompact, horizontalCompact
-        ]];
-
-    SetSwizzlersUp(custom_trait_collection, UIUserInterfaceIdiomPhone,
-                   UIInterfaceOrientationLandscapeLeft);
+    return [UITraitCollection traitCollectionWithTraitsFromCollections:@[
+      verticalCompact, horizontalCompact
+    ]];
   }
 
-  void SetAsIPhonePortrait() {
+  UITraitCollection* IPhonePortraitTraitCollection() {
     UITraitCollection* horizontalCompact = [UITraitCollection
         traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
     UITraitCollection* verticalRegular = [UITraitCollection
         traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassRegular];
-    UITraitCollection* custom_trait_collection =
-        [UITraitCollection traitCollectionWithTraitsFromCollections:@[
-          verticalRegular, horizontalCompact
-        ]];
-
-    SetSwizzlersUp(custom_trait_collection, UIUserInterfaceIdiomPhone,
-                   UIInterfaceOrientationPortrait);
+    return [UITraitCollection traitCollectionWithTraitsFromCollections:@[
+      verticalRegular, horizontalCompact
+    ]];
   }
-
- private:
-  // Sets up the swizzler for the different parameters passed.
-  void SetSwizzlersUp(UITraitCollection* custom_trait_collection,
-                      UIUserInterfaceIdiom custom_interface,
-                      UIInterfaceOrientation custom_orientation) {
-    customTraitCollection_ = custom_trait_collection;
-    trait_swizzler_ = std::make_unique<ScopedBlockSwizzler>(
-        [UIWindow class], @selector(traitCollection),
-        ^UITraitCollection*(id self) {
-          return customTraitCollection_;
-        });
-
-    device_type_swizzler_ = std::make_unique<ScopedBlockSwizzler>(
-        [UIDevice class], @selector(userInterfaceIdiom),
-        ^UIUserInterfaceIdiom(id self) {
-          return custom_interface;
-        });
-
-    orientation_swizzler_ = std::make_unique<ScopedBlockSwizzler>(
-        [UIApplication class], @selector(statusBarOrientation),
-        ^UIInterfaceOrientation(id self) {
-          return custom_orientation;
-        });
-  }
-
-  UITraitCollection* customTraitCollection_;
-  std::unique_ptr<ScopedBlockSwizzler> trait_swizzler_;
-  std::unique_ptr<ScopedBlockSwizzler> device_type_swizzler_;
-  std::unique_ptr<ScopedBlockSwizzler> orientation_swizzler_;
 };
 
 TEST_F(ContentSuggestionsCollectionUtilsTest, doodleFrameIPad) {
-  // Setup.
-  SetAsIPad();
-
   // Action.
-  CGFloat height = doodleHeight(YES);
-  CGFloat topMargin = doodleTopMargin(YES, kTopInset);
+  CGFloat height = doodleHeight(YES, IPadTraitCollection());
+  CGFloat topMargin = doodleTopMargin(YES, kTopInset, IPadTraitCollection());
 
   // Test.
   EXPECT_EQ(120, height);
@@ -108,13 +63,11 @@
 }
 
 TEST_F(ContentSuggestionsCollectionUtilsTest, doodleFrameIPhonePortrait) {
-  // Setup.
-  SetAsIPhonePortrait();
-
   // Action.
-  CGFloat heightLogo = doodleHeight(YES);
-  CGFloat heightNoLogo = doodleHeight(NO);
-  CGFloat topMargin = doodleTopMargin(YES, kTopInset);
+  CGFloat heightLogo = doodleHeight(YES, IPhonePortraitTraitCollection());
+  CGFloat heightNoLogo = doodleHeight(NO, IPhonePortraitTraitCollection());
+  CGFloat topMargin =
+      doodleTopMargin(YES, kTopInset, IPhonePortraitTraitCollection());
 
   // Test.
   EXPECT_EQ(120, heightLogo);
@@ -123,13 +76,11 @@
 }
 
 TEST_F(ContentSuggestionsCollectionUtilsTest, doodleFrameIPhoneLandscape) {
-  // Setup.
-  SetAsIPhoneLandscape();
-
   // Action.
-  CGFloat heightLogo = doodleHeight(YES);
-  CGFloat heightNoLogo = doodleHeight(NO);
-  CGFloat topMargin = doodleTopMargin(YES, kTopInset);
+  CGFloat heightLogo = doodleHeight(YES, IPhoneLandscapeTraitCollection());
+  CGFloat heightNoLogo = doodleHeight(NO, IPhoneLandscapeTraitCollection());
+  CGFloat topMargin =
+      doodleTopMargin(YES, kTopInset, IPhoneLandscapeTraitCollection());
 
   // Test.
   EXPECT_EQ(120, heightLogo);
@@ -139,13 +90,13 @@
 
 TEST_F(ContentSuggestionsCollectionUtilsTest, searchFieldFrameIPad) {
   // Setup.
-  SetAsIPad();
   CGFloat width = 500;
   CGFloat largeIPadWidth = 1366;
 
   // Action.
-  CGFloat resultWidth = searchFieldWidth(width);
-  CGFloat resultWidthLargeIPad = searchFieldWidth(largeIPadWidth);
+  CGFloat resultWidth = searchFieldWidth(width, IPadTraitCollection());
+  CGFloat resultWidthLargeIPad =
+      searchFieldWidth(largeIPadWidth, IPadTraitCollection());
   CGFloat topMargin = searchFieldTopMargin();
 
   // Test.
@@ -156,11 +107,11 @@
 
 TEST_F(ContentSuggestionsCollectionUtilsTest, searchFieldFrameIPhonePortrait) {
   // Setup.
-  SetAsIPhonePortrait();
   CGFloat width = 500;
 
   // Action.
-  CGFloat resultWidth = searchFieldWidth(width);
+  CGFloat resultWidth =
+      searchFieldWidth(width, IPhonePortraitTraitCollection());
   CGFloat topMargin = searchFieldTopMargin();
 
   // Test.
@@ -170,11 +121,11 @@
 
 TEST_F(ContentSuggestionsCollectionUtilsTest, searchFieldFrameIPhoneLandscape) {
   // Setup.
-  SetAsIPhoneLandscape();
   CGFloat width = 500;
 
   // Action.
-  CGFloat resultWidth = searchFieldWidth(width);
+  CGFloat resultWidth =
+      searchFieldWidth(width, IPhoneLandscapeTraitCollection());
   CGFloat topMargin = searchFieldTopMargin();
 
   // Test.
@@ -183,25 +134,23 @@
 }
 
 TEST_F(ContentSuggestionsCollectionUtilsTest, heightForLogoHeaderIPad) {
-  // Setup.
-  SetAsIPad();
-
   // Action, tests.
-  EXPECT_EQ(382, heightForLogoHeader(YES, YES, YES, 0));
-  EXPECT_EQ(406, heightForLogoHeader(YES, NO, YES, 0));
-  EXPECT_EQ(382, heightForLogoHeader(YES, YES, NO, 0));
-  EXPECT_EQ(406, heightForLogoHeader(YES, NO, NO, 0));
+  EXPECT_EQ(382, heightForLogoHeader(YES, YES, YES, 0, IPadTraitCollection()));
+  EXPECT_EQ(406, heightForLogoHeader(YES, NO, YES, 0, IPadTraitCollection()));
+  EXPECT_EQ(382, heightForLogoHeader(YES, YES, NO, 0, IPadTraitCollection()));
+  EXPECT_EQ(406, heightForLogoHeader(YES, NO, NO, 0, IPadTraitCollection()));
 }
 
 TEST_F(ContentSuggestionsCollectionUtilsTest, heightForLogoHeaderIPhone) {
-  // Setup.
-  SetAsIPhonePortrait();
-
   // Action, tests.
-  EXPECT_EQ(278, heightForLogoHeader(YES, YES, YES, 0));
-  EXPECT_EQ(278, heightForLogoHeader(YES, NO, YES, 0));
-  EXPECT_EQ(278, heightForLogoHeader(YES, YES, NO, 0));
-  EXPECT_EQ(278, heightForLogoHeader(YES, NO, NO, 0));
+  EXPECT_EQ(278, heightForLogoHeader(YES, YES, YES, 0,
+                                     IPhonePortraitTraitCollection()));
+  EXPECT_EQ(278, heightForLogoHeader(YES, NO, YES, 0,
+                                     IPhonePortraitTraitCollection()));
+  EXPECT_EQ(278, heightForLogoHeader(YES, YES, NO, 0,
+                                     IPhonePortraitTraitCollection()));
+  EXPECT_EQ(278, heightForLogoHeader(YES, NO, NO, 0,
+                                     IPhonePortraitTraitCollection()));
 }
 
 TEST_F(ContentSuggestionsCollectionUtilsTest, NearestAncestor) {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm
index 05fba0f..e328821 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm
@@ -313,7 +313,7 @@
     return;
 
   CGFloat searchFieldNormalWidth =
-      content_suggestions::searchFieldWidth(contentWidth);
+      content_suggestions::searchFieldWidth(contentWidth, self.traitCollection);
 
   CGFloat percent =
       [self searchFieldProgressForOffset:offset safeAreaInsets:safeAreaInsets];
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
index 5511a4c..bdada462 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
@@ -133,7 +133,7 @@
   void (^transition)(id<UIViewControllerTransitionCoordinatorContext>) =
       ^(id<UIViewControllerTransitionCoordinatorContext> context) {
         // Ensure omnibox is reset when not a regular tablet.
-        if (IsSplitToolbarMode()) {
+        if (IsSplitToolbarMode(newCollection)) {
           [self.toolbarDelegate setScrollProgressForTabletOmnibox:1];
         }
         // Fake Tap button only needs to work in portrait. Disable the button
@@ -161,7 +161,7 @@
                                              safeAreaInsets:safeAreaInsets]
             // RxR with no logo hides the fakebox, so always show the omnibox.
             : 1;
-    if (!IsSplitToolbarMode()) {
+    if (!IsSplitToolbarMode(self)) {
       [self.toolbarDelegate setScrollProgressForTabletOmnibox:progress];
     } else {
       // Ensure omnibox is reset when not a regular tablet.
@@ -182,7 +182,7 @@
 
 - (void)updateFakeOmniboxForWidth:(CGFloat)width {
   self.fakeOmniboxWidthConstraint.constant =
-      content_suggestions::searchFieldWidth(width);
+      content_suggestions::searchFieldWidth(width, self.traitCollection);
 }
 
 - (void)unfocusOmnibox {
@@ -200,13 +200,15 @@
 // Update the doodle top margin to the new -doodleTopMargin value.
 - (void)updateConstraints {
   self.doodleTopMarginConstraint.constant =
-      content_suggestions::doodleTopMargin(YES, [self topInset]);
+      content_suggestions::doodleTopMargin(YES, [self topInset],
+                                           self.traitCollection);
   [self.headerView updateForTopSafeAreaInset:[self topInset]];
 }
 
 - (CGFloat)pinnedOffsetY {
   CGFloat headerHeight = content_suggestions::heightForLogoHeader(
-      self.logoIsShowing, self.promoCanShow, YES, [self topInset]);
+      self.logoIsShowing, self.promoCanShow, YES, [self topInset],
+      self.traitCollection);
 
   CGFloat offsetY =
       headerHeight - ntp_header::kScrolledToTopOmniboxBottomMargin;
@@ -231,7 +233,8 @@
 
 - (CGFloat)headerHeight {
   return content_suggestions::heightForLogoHeader(
-      self.logoIsShowing, self.promoCanShow, YES, [self topInset]);
+      self.logoIsShowing, self.promoCanShow, YES, [self topInset],
+      self.traitCollection);
 }
 
 #pragma mark - ContentSuggestionsHeaderProvider
@@ -271,7 +274,8 @@
         0, width - safeAreaInsets.left - safeAreaInsets.right);
 
     self.fakeOmniboxWidthConstraint = [self.fakeOmnibox.widthAnchor
-        constraintEqualToConstant:content_suggestions::searchFieldWidth(width)];
+        constraintEqualToConstant:content_suggestions::searchFieldWidth(
+                                      width, self.traitCollection)];
     [self addConstraintsForLogoView:self.logoVendor.view
                         fakeOmnibox:self.fakeOmnibox
                       andHeaderView:self.headerView];
@@ -461,7 +465,8 @@
 // shows fakebox if the logo is visible and hides otherwise
 - (void)updateFakeboxDisplay {
   [self.doodleHeightConstraint
-      setConstant:content_suggestions::doodleHeight(self.logoIsShowing)];
+      setConstant:content_suggestions::doodleHeight(self.logoIsShowing,
+                                                    self.traitCollection)];
   self.fakeOmnibox.hidden =
       IsRegularXRegularSizeClass(self) && !self.logoIsShowing;
   [self.collectionSynchronizer invalidateLayout];
@@ -493,10 +498,10 @@
   self.doodleTopMarginConstraint = [logoView.topAnchor
       constraintEqualToAnchor:headerView.topAnchor
                      constant:content_suggestions::doodleTopMargin(
-                                  YES, [self topInset])];
+                                  YES, [self topInset], self.traitCollection)];
   self.doodleHeightConstraint = [logoView.heightAnchor
       constraintEqualToConstant:content_suggestions::doodleHeight(
-                                    self.logoIsShowing)];
+                                    self.logoIsShowing, self.traitCollection)];
   self.fakeOmniboxHeightConstraint = [fakeOmnibox.heightAnchor
       constraintEqualToConstant:ToolbarExpandedHeight(
                                     self.traitCollection
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
index 4808b73..a63b2cc 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -591,8 +591,8 @@
     parentInset.right = margin;
   } else if (self.styler.cellStyle == MDCCollectionViewCellStyleCard) {
     CGFloat collectionWidth = collectionView.bounds.size.width;
-    CGFloat maxCardWidth =
-        content_suggestions::searchFieldWidth(collectionWidth);
+    CGFloat maxCardWidth = content_suggestions::searchFieldWidth(
+        collectionWidth, self.traitCollection);
     CGFloat margin =
         MAX(0, (collectionView.frame.size.width - maxCardWidth) / 2);
     parentInset.left = margin;
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
index 8fb54e7f..d28f50f6 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -237,13 +237,15 @@
     EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to device rotation bug.");
   }
   [ChromeEarlGreyUI waitForAppToIdle];
-  UIEdgeInsets safeArea =
-      [ContentSuggestionsAppInterface collectionView].safeAreaInsets;
-  CGFloat collectionWidth = CGRectGetWidth(UIEdgeInsetsInsetRect(
-      [ContentSuggestionsAppInterface collectionView].bounds, safeArea));
+  UICollectionView* collectionView =
+      [ContentSuggestionsAppInterface collectionView];
+  UIEdgeInsets safeArea = collectionView.safeAreaInsets;
+  CGFloat collectionWidth =
+      CGRectGetWidth(UIEdgeInsetsInsetRect(collectionView.bounds, safeArea));
   GREYAssertTrue(collectionWidth > 0, @"The collection width is nil.");
   CGFloat fakeOmniboxWidth = [ContentSuggestionsAppInterface
-      searchFieldWidthForCollectionWidth:collectionWidth];
+      searchFieldWidthForCollectionWidth:collectionWidth
+                         traitCollection:collectionView.traitCollection];
 
   [[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
       assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)];
@@ -257,13 +259,15 @@
 
   [ChromeEarlGreyUI waitForAppToIdle];
 
-  safeArea = [ContentSuggestionsAppInterface collectionView].safeAreaInsets;
-  CGFloat collectionWidthAfterRotation = CGRectGetWidth(UIEdgeInsetsInsetRect(
-      [ContentSuggestionsAppInterface collectionView].bounds, safeArea));
+  collectionView = [ContentSuggestionsAppInterface collectionView];
+  safeArea = collectionView.safeAreaInsets;
+  CGFloat collectionWidthAfterRotation =
+      CGRectGetWidth(UIEdgeInsetsInsetRect(collectionView.bounds, safeArea));
   GREYAssertNotEqual(collectionWidth, collectionWidthAfterRotation,
                      @"The collection width has not changed.");
   fakeOmniboxWidth = [ContentSuggestionsAppInterface
-      searchFieldWidthForCollectionWidth:collectionWidthAfterRotation];
+      searchFieldWidthForCollectionWidth:collectionWidthAfterRotation
+                         traitCollection:collectionView.traitCollection];
 
   [[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
       assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)];
@@ -278,13 +282,15 @@
     EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to device rotation bug.");
   }
   [ChromeEarlGreyUI waitForAppToIdle];
-  UIEdgeInsets safeArea =
-      [ContentSuggestionsAppInterface collectionView].safeAreaInsets;
-  CGFloat collectionWidth = CGRectGetWidth(UIEdgeInsetsInsetRect(
-      [ContentSuggestionsAppInterface collectionView].bounds, safeArea));
+  UICollectionView* collectionView =
+      [ContentSuggestionsAppInterface collectionView];
+  UIEdgeInsets safeArea = collectionView.safeAreaInsets;
+  CGFloat collectionWidth =
+      CGRectGetWidth(UIEdgeInsetsInsetRect(collectionView.bounds, safeArea));
   GREYAssertTrue(collectionWidth > 0, @"The collection width is nil.");
   CGFloat fakeOmniboxWidth = [ContentSuggestionsAppInterface
-      searchFieldWidthForCollectionWidth:collectionWidth];
+      searchFieldWidthForCollectionWidth:collectionWidth
+                         traitCollection:collectionView.traitCollection];
 
   [[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
       assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)];
@@ -303,13 +309,15 @@
   [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsDoneButton()]
       performAction:grey_tap()];
 
-  safeArea = [ContentSuggestionsAppInterface collectionView].safeAreaInsets;
-  CGFloat collectionWidthAfterRotation = CGRectGetWidth(UIEdgeInsetsInsetRect(
-      [ContentSuggestionsAppInterface collectionView].bounds, safeArea));
+  collectionView = [ContentSuggestionsAppInterface collectionView];
+  safeArea = collectionView.safeAreaInsets;
+  CGFloat collectionWidthAfterRotation =
+      CGRectGetWidth(UIEdgeInsetsInsetRect(collectionView.bounds, safeArea));
   GREYAssertNotEqual(collectionWidth, collectionWidthAfterRotation,
                      @"The collection width has not changed.");
   fakeOmniboxWidth = [ContentSuggestionsAppInterface
-      searchFieldWidthForCollectionWidth:collectionWidthAfterRotation];
+      searchFieldWidthForCollectionWidth:collectionWidthAfterRotation
+                         traitCollection:collectionView.traitCollection];
 
   [[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
       assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)];
diff --git a/ios/chrome/browser/ui/util/uikit_ui_util.h b/ios/chrome/browser/ui/util/uikit_ui_util.h
index c7b000d..1be6b7c 100644
--- a/ios/chrome/browser/ui/util/uikit_ui_util.h
+++ b/ios/chrome/browser/ui/util/uikit_ui_util.h
@@ -202,6 +202,9 @@
 // Whether the |environment| has a compact horizontal size class.
 bool IsCompactWidth(id<UITraitEnvironment> environment);
 
+// Whether the |traitCollection| has a compact horizontal size class.
+bool IsCompactWidth(UITraitCollection* traitCollection);
+
 // Whether the main application window's rootViewController has a compact
 // horizontal size class.
 bool IsCompactWidth();
@@ -220,6 +223,9 @@
 // Whether the |environment| has a compact vertical size class.
 bool IsCompactHeight(id<UITraitEnvironment> environment);
 
+// Whether the |traitCollection| has a compact vertical size class.
+bool IsCompactHeight(UITraitCollection* traitCollection);
+
 // Whether toolbar should be shown in compact mode.
 bool ShouldShowCompactToolbar();
 // Whether toolbar should be shown in compact mode in |traitCollection|.
@@ -243,6 +249,10 @@
 // toolbar or if it is displayed as only one toolbar.
 bool IsSplitToolbarMode(id<UITraitEnvironment> environment);
 
+// Returns whether the |traitCollection|'s toolbar is split between top and
+// bottom toolbar or if it is displayed as only one toolbar.
+bool IsSplitToolbarMode(UITraitCollection* traitCollection);
+
 // Returns the current first responder for keyWindow.
 UIResponder* GetFirstResponder();
 
diff --git a/ios/chrome/browser/ui/util/uikit_ui_util.mm b/ios/chrome/browser/ui/util/uikit_ui_util.mm
index dd375ae2..57215a4b 100644
--- a/ios/chrome/browser/ui/util/uikit_ui_util.mm
+++ b/ios/chrome/browser/ui/util/uikit_ui_util.mm
@@ -572,8 +572,11 @@
 }
 
 bool IsCompactWidth(id<UITraitEnvironment> environment) {
-  return environment.traitCollection.horizontalSizeClass ==
-         UIUserInterfaceSizeClassCompact;
+  return IsCompactWidth(environment.traitCollection);
+}
+
+bool IsCompactWidth(UITraitCollection* traitCollection) {
+  return traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact;
 }
 
 bool IsCompactWidth() {
@@ -594,8 +597,11 @@
 }
 
 bool IsCompactHeight(id<UITraitEnvironment> environment) {
-  return environment.traitCollection.verticalSizeClass ==
-         UIUserInterfaceSizeClassCompact;
+  return IsCompactHeight(environment.traitCollection);
+}
+
+bool IsCompactHeight(UITraitCollection* traitCollection) {
+  return traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact;
 }
 
 bool IsRegularXRegularSizeClass() {
@@ -621,11 +627,16 @@
 }
 
 bool IsSplitToolbarMode() {
-  return IsCompactWidth() && !IsCompactHeight();
+  return IsSplitToolbarMode(
+      [UIApplication sharedApplication].keyWindow.traitCollection);
 }
 
 bool IsSplitToolbarMode(id<UITraitEnvironment> environment) {
-  return IsCompactWidth(environment) && !IsCompactHeight(environment);
+  return IsSplitToolbarMode(environment.traitCollection);
+}
+
+bool IsSplitToolbarMode(UITraitCollection* traitCollection) {
+  return IsCompactWidth(traitCollection) && !IsCompactHeight(traitCollection);
 }
 
 UIView* GetFirstResponderSubview(UIView* view) {
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 86deb48e..b3cc57d07 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -664,6 +664,11 @@
 const base::Feature MEDIA_EXPORT kAVFoundationCaptureV2{
     "AVFoundationCaptureV2", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Controls whether or not the V2 capturer exports IOSurfaces for zero-copy.
+// This feature only has any effect if kAVFoundationCaptureV2 is also enabled.
+const base::Feature MEDIA_EXPORT kAVFoundationCaptureV2ZeroCopy{
+    "AVFoundationCaptureV2ZeroCopy", base::FEATURE_ENABLED_BY_DEFAULT};
+
 const base::Feature MEDIA_EXPORT kVideoToolboxVp9Decoding{
     "VideoToolboxVp9Decoding", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif  // defined(OS_MAC)
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index 63c36c1..06cf7223 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -226,6 +226,7 @@
 
 #if defined(OS_MAC)
 MEDIA_EXPORT extern const base::Feature kAVFoundationCaptureV2;
+MEDIA_EXPORT extern const base::Feature kAVFoundationCaptureV2ZeroCopy;
 MEDIA_EXPORT extern const base::Feature kVideoToolboxVp9Decoding;
 #endif
 
diff --git a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
index 526b3658..5ebc7073 100644
--- a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
+++ b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
@@ -17,6 +17,7 @@
 #include "base/sequenced_task_runner.h"
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
+#include "media/base/media_switches.h"
 #include "media/base/timestamp_constants.h"
 #include "media/base/video_types.h"
 #import "media/capture/video/mac/video_capture_device_avfoundation_utils_mac.h"
@@ -654,9 +655,8 @@
     DCHECK_EQ(pixelBufferPixelFormat, sampleBufferPixelFormat);
 
     // First preference is to use an NV12 IOSurface as a GpuMemoryBuffer.
-    // TODO(https://crbug.com/1125879): This path cannot be used in software
-    // mode yet, and so it cannot be enabled yet.
-    constexpr bool kEnableGpuMemoryBuffers = false;
+    static const bool kEnableGpuMemoryBuffers =
+        base::FeatureList::IsEnabled(media::kAVFoundationCaptureV2ZeroCopy);
     if (kEnableGpuMemoryBuffers) {
       IOSurfaceRef ioSurface = CVPixelBufferGetIOSurface(pixelBuffer);
       if (ioSurface && videoPixelFormat == media::PIXEL_FORMAT_NV12) {
diff --git a/media/capture/video/mac/video_capture_device_avfoundation_mac_unittest.mm b/media/capture/video/mac/video_capture_device_avfoundation_mac_unittest.mm
index 63e3cf8..f6e0e1a1 100644
--- a/media/capture/video/mac/video_capture_device_avfoundation_mac_unittest.mm
+++ b/media/capture/video/mac/video_capture_device_avfoundation_mac_unittest.mm
@@ -19,7 +19,7 @@
 
 namespace media {
 
-TEST(VideoCaptureDeviceAVFoundationMacTest, TakePhoto) {
+TEST(VideoCaptureDeviceAVFoundationMacTest, DISABLED_TakePhoto) {
   RunTestCase(base::BindOnce([] {
     NSString* deviceId = GetFirstDeviceId();
     if (!deviceId) {
@@ -46,7 +46,8 @@
   }));
 }
 
-TEST(VideoCaptureDeviceAVFoundationMacTest, StopCaptureWhileTakingPhoto) {
+TEST(VideoCaptureDeviceAVFoundationMacTest,
+     DISABLED_StopCaptureWhileTakingPhoto) {
   RunTestCase(base::BindOnce([] {
     NSString* deviceId = GetFirstDeviceId();
     if (!deviceId) {
@@ -77,7 +78,8 @@
   }));
 }
 
-TEST(VideoCaptureDeviceAVFoundationMacTest, MultiplePendingTakePhotos) {
+TEST(VideoCaptureDeviceAVFoundationMacTest,
+     DISABLED_MultiplePendingTakePhotos) {
   RunTestCase(base::BindOnce([] {
     NSString* deviceId = GetFirstDeviceId();
     if (!deviceId) {
@@ -113,7 +115,7 @@
 }
 
 TEST(VideoCaptureDeviceAVFoundationMacTest,
-     StopCaptureWhileMultiplePendingTakePhotos) {
+     DISABLED_StopCaptureWhileMultiplePendingTakePhotos) {
   RunTestCase(base::BindOnce([] {
     NSString* deviceId = GetFirstDeviceId();
     if (!deviceId) {
@@ -153,7 +155,7 @@
 }
 
 TEST(VideoCaptureDeviceAVFoundationMacTest,
-     StopStillImageOutputWhenNoLongerTakingPhotos) {
+     DISABLED_StopStillImageOutputWhenNoLongerTakingPhotos) {
   RunTestCase(base::BindOnce([] {
     NSString* deviceId = GetFirstDeviceId();
     if (!deviceId) {
@@ -190,7 +192,7 @@
 
 // This test ensures we don't crash even if we leave operations pending.
 TEST(VideoCaptureDeviceAVFoundationMacTest,
-     TakePhotoAndShutDownWithoutWaiting) {
+     DISABLED_TakePhotoAndShutDownWithoutWaiting) {
   RunTestCase(base::BindOnce([] {
     NSString* deviceId = GetFirstDeviceId();
     if (!deviceId) {
diff --git a/media/capture/video/mac/video_capture_device_factory_mac.mm b/media/capture/video/mac/video_capture_device_factory_mac.mm
index 9f5b3a98..da4edcb6 100644
--- a/media/capture/video/mac/video_capture_device_factory_mac.mm
+++ b/media/capture/video/mac/video_capture_device_factory_mac.mm
@@ -120,10 +120,11 @@
             : VideoCaptureTransportType::OTHER_TRANSPORT;
     const std::string model_id = VideoCaptureDeviceMac::GetDeviceModelId(
         device_id, capture_api, device_transport_type);
+    bool pan_tilt_zoom_supported =
+        VideoCaptureDeviceMac::IsPanTiltZoomSupported(model_id);
     VideoCaptureDeviceDescriptor descriptor(
         [[[capture_devices valueForKey:key] deviceName] UTF8String], device_id,
-        model_id, capture_api,
-        /*pan_tilt_zoom_supported=*/false, device_transport_type);
+        model_id, capture_api, pan_tilt_zoom_supported, device_transport_type);
     if (IsDeviceBlocked(descriptor))
       continue;
     devices_info.emplace_back(descriptor);
diff --git a/media/capture/video/mac/video_capture_device_factory_mac_unittest.mm b/media/capture/video/mac/video_capture_device_factory_mac_unittest.mm
index be079c39..4b6f6ac 100644
--- a/media/capture/video/mac/video_capture_device_factory_mac_unittest.mm
+++ b/media/capture/video/mac/video_capture_device_factory_mac_unittest.mm
@@ -47,21 +47,6 @@
   }));
 }
 
-TEST_P(VideoCaptureDeviceFactoryMacTest, ListDevicesWithNoPanTiltZoomSupport) {
-  RunTestCase(base::BindOnce([]() {
-    VideoCaptureDeviceFactoryMac video_capture_device_factory;
-
-    std::vector<VideoCaptureDeviceInfo> devices_info =
-        GetDevicesInfo(&video_capture_device_factory);
-    if (devices_info.empty()) {
-      DVLOG(1) << "No camera available. Exiting test.";
-      return;
-    }
-    for (const auto& device : devices_info)
-      EXPECT_FALSE(device.descriptor.pan_tilt_zoom_supported());
-  }));
-}
-
 INSTANTIATE_TEST_SUITE_P(,
                          VideoCaptureDeviceFactoryMacTest,
                          ::testing::Values(AVFoundationCaptureV2::kEnabled,
diff --git a/media/capture/video/mac/video_capture_device_mac.h b/media/capture/video/mac/video_capture_device_mac.h
index d23a545..e1af2ca6 100644
--- a/media/capture/video/mac/video_capture_device_mac.h
+++ b/media/capture/video/mac/video_capture_device_mac.h
@@ -103,6 +103,8 @@
                                       VideoCaptureApi capture_api,
                                       VideoCaptureTransportType transport_type);
 
+  static bool IsPanTiltZoomSupported(const std::string& device_model);
+
  private:
   void SetErrorState(VideoCaptureError error,
                      const base::Location& from_here,
diff --git a/media/capture/video/mac/video_capture_device_mac.mm b/media/capture/video/mac/video_capture_device_mac.mm
index 56f56b2..be33fc1 100644
--- a/media/capture/video/mac/video_capture_device_mac.mm
+++ b/media/capture/video/mac/video_capture_device_mac.mm
@@ -32,6 +32,9 @@
 #include "media/capture/video/mac/video_capture_device_avfoundation_utils_mac.h"
 #include "ui/gfx/geometry/size.h"
 
+using ScopedIOUSBInterfaceInterface =
+    base::mac::ScopedIOPluginInterface<IOUSBInterfaceInterface220>;
+
 @implementation DeviceNameAndTransportType
 
 - (id)initWithName:(NSString*)deviceName transportType:(int32_t)transportType {
@@ -64,27 +67,59 @@
 // The following constants are extracted from the specification "Universal
 // Serial Bus Device Class Definition for Video Devices", Rev. 1.1 June 1, 2005.
 // http://www.usb.org/developers/devclass_docs/USB_Video_Class_1_1.zip
-// CS_INTERFACE: Sec. A.4 "Video Class-Specific Descriptor Types".
-const int kVcCsInterface = 0x24;
-// VC_PROCESSING_UNIT: Sec. A.5 "Video Class-Specific VC Interface Descriptor
-// Subtypes".
-const int kVcProcessingUnit = 0x5;
-// SET_CUR: Sec. A.8 "Video Class-Specific Request Codes".
-const int kVcRequestCodeSetCur = 0x1;
-// PU_POWER_LINE_FREQUENCY_CONTROL: Sec. A.9.5 "Processing Unit Control
-// Selectors".
-const int kPuPowerLineFrequencyControl = 0x5;
-// Sec. 4.2.2.3.5 Power Line Frequency Control.
+// Sec. A.4 "Video Class-Specific Descriptor Types".
+const int kVcCsInterface = 0x24;  // CS_INTERFACE
+// Sec. A.5 "Video Class-Specific VC Interface Descriptor Subtypes".
+const int kVcInputTerminal = 0x2;   // VC_INPUT_TERMINAL
+const int kVcProcessingUnit = 0x5;  // VC_PROCESSING_UNIT
+// Sec. A.8 "Video Class-Specific Request Codes".
+const int kVcRequestCodeSetCur = 0x1;   // SET_CUR
+const int kVcRequestCodeGetCur = 0x81;  // GET_CUR
+const int kVcRequestCodeGetMin = 0x82;  // GET_MIN
+const int kVcRequestCodeGetMax = 0x83;  // GET_MAX
+const int kVcRequestCodeGetRes = 0x84;  // GET_RES
+// Sec. A.9.4. "Camera Terminal Control Selectors".
+const int kCtZoomAbsoluteControl = 0x0b;     // CT_ZOOM_ABSOLUTE_CONTROL
+const int kCtPanTiltAbsoluteControl = 0x0d;  // CT_PANTILT_ABSOLUTE_CONTROL
+// Sec. A.9.5 "Processing Unit Control Selectors".
+const int kPuPowerLineFrequencyControl =
+    0x5;  // PU_POWER_LINE_FREQUENCY_CONTROL
+// Sec. 4.2.2.3.5 "Power Line Frequency Control".
 const int k50Hz = 1;
 const int k60Hz = 2;
 const int kPuPowerLineFrequencyControlCommandSize = 1;
+// Sec. 4.2.2.1.11 "Zoom (Absolute) Control".
+const int kCtZoomAbsoluteControlCommandSize = 2;
+// Sec. 4.2.2.1.13 "PanTilt (Absolute) Control".
+const int kCtPanTiltAbsoluteControlCommandSize = 8;
 
 // Addition to the IOUSB family of structures, with subtype and unit ID.
-typedef struct IOUSBInterfaceDescriptor {
+// Sec. 3.7.2 "Class-Specific VC Interface Descriptor"
+typedef struct VcCsInterfaceDescriptor {
   IOUSBDescriptorHeader header;
   UInt8 bDescriptorSubType;
   UInt8 bUnitID;
-} IOUSBInterfaceDescriptor;
+} VcCsInterfaceDescriptor;
+
+static bool FindDeviceWithVendorAndProductIds(int vendor_id,
+                                              int product_id,
+                                              io_iterator_t* usb_iterator) {
+  // Compose a search dictionary with vendor and product ID.
+  base::ScopedCFTypeRef<CFMutableDictionaryRef> query_dictionary(
+      IOServiceMatching(kIOUSBDeviceClassName));
+  CFDictionarySetValue(query_dictionary, CFSTR(kUSBVendorName),
+                       base::mac::NSToCFCast(@(vendor_id)));
+  CFDictionarySetValue(query_dictionary, CFSTR(kUSBProductName),
+                       base::mac::NSToCFCast(@(product_id)));
+
+  kern_return_t kr = IOServiceGetMatchingServices(
+      kIOMasterPortDefault, query_dictionary.release(), usb_iterator);
+  if (kr != kIOReturnSuccess) {
+    DLOG(ERROR) << "No devices found with specified Vendor and Product ID.";
+    return false;
+  }
+  return true;
+}
 
 // Tries to create a user-side device interface for a given USB device. Returns
 // true if interface was found and passes it back in |device_interface|. The
@@ -169,33 +204,29 @@
     const PowerLineFrequency frequency) {
   // Create, the control interface for the found plugin, and release
   // the intermediate plugin.
-  IOUSBInterfaceInterface** control_interface = NULL;
+  ScopedIOUSBInterfaceInterface control_interface;
   HRESULT res =
       (*plugin_interface)
-          ->QueryInterface(plugin_interface,
-                           CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
-                           reinterpret_cast<LPVOID*>(&control_interface));
+          ->QueryInterface(
+              plugin_interface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
+              reinterpret_cast<LPVOID*>(control_interface.InitializeInto()));
   if (!SUCCEEDED(res) || !control_interface) {
     DLOG(ERROR) << "Couldn’t create control interface";
     return;
   }
-  base::mac::ScopedIOPluginInterface<IOUSBInterfaceInterface>
-      control_interface_ref(control_interface);
 
   // Find the device's unit ID presenting type 0x24 (kVcCsInterface) and
   // subtype 0x5 (kVcProcessingUnit). Inside this unit is where we find the
   // power line frequency removal setting, and this id is device dependent.
   int real_unit_id = -1;
   IOUSBDescriptorHeader* descriptor = NULL;
-  IOUSBInterfaceDescriptor* cs_descriptor = NULL;
-  IOUSBInterfaceInterface220** interface =
-      reinterpret_cast<IOUSBInterfaceInterface220**>(control_interface);
-  while ((descriptor = (*interface)
-                           ->FindNextAssociatedDescriptor(interface, descriptor,
-                                                          kUSBAnyDesc))) {
-    cs_descriptor = reinterpret_cast<IOUSBInterfaceDescriptor*>(descriptor);
-    if ((descriptor->bDescriptorType == kVcCsInterface) &&
-        (cs_descriptor->bDescriptorSubType == kVcProcessingUnit)) {
+  while ((descriptor =
+              (*control_interface)
+                  ->FindNextAssociatedDescriptor(control_interface.get(),
+                                                 descriptor, kVcCsInterface))) {
+    auto* cs_descriptor =
+        reinterpret_cast<VcCsInterfaceDescriptor*>(descriptor);
+    if (cs_descriptor->bDescriptorSubType == kVcProcessingUnit) {
       real_unit_id = cs_descriptor->bUnitID;
       break;
     }
@@ -254,22 +285,11 @@
   DVLOG(1) << "Setting Power Line Frequency to " << static_cast<int>(frequency)
            << " Hz, device " << std::hex << vendor_id << "-" << product_id;
 
-  // Compose a search dictionary with vendor and product ID.
-  base::ScopedCFTypeRef<CFMutableDictionaryRef> query_dictionary(
-      IOServiceMatching(kIOUSBDeviceClassName));
-  CFDictionarySetValue(query_dictionary, CFSTR(kUSBVendorName),
-                       base::mac::NSToCFCast(@(vendor_id)));
-  CFDictionarySetValue(query_dictionary, CFSTR(kUSBProductName),
-                       base::mac::NSToCFCast(@(product_id)));
-
-  io_iterator_t usb_iterator;
-  kern_return_t kr = IOServiceGetMatchingServices(
-      kIOMasterPortDefault, query_dictionary.release(), &usb_iterator);
-  if (kr != kIOReturnSuccess) {
-    DLOG(ERROR) << "No devices found with specified Vendor and Product ID.";
+  base::mac::ScopedIOObject<io_iterator_t> usb_iterator;
+  if (!FindDeviceWithVendorAndProductIds(vendor_id, product_id,
+                                         usb_iterator.InitializeInto())) {
     return;
   }
-  base::mac::ScopedIOObject<io_iterator_t> usb_iterator_ref(usb_iterator);
 
   while (io_service_t usb_device = IOIteratorNext(usb_iterator)) {
     base::mac::ScopedIOObject<io_service_t> usb_device_ref(usb_device);
@@ -294,6 +314,287 @@
   }
 }
 
+// Create an empty IOUSBDevRequest for a USB device to either control or get
+// information from pan, tilt, and zoom controls.
+static IOUSBDevRequest CreateEmptyPanTiltZoomRequest(
+    IOUSBInterfaceInterface220** control_interface,
+    int unit_id,
+    int request_code,
+    int endpoint_direction,
+    int control_selector,
+    int control_command_size) {
+  DCHECK((endpoint_direction == kUSBIn) || (endpoint_direction == kUSBOut));
+  UInt8 interface_number;
+  (*control_interface)
+      ->GetInterfaceNumber(control_interface, &interface_number);
+  IOUSBDevRequest command;
+  command.bmRequestType =
+      USBmakebmRequestType(endpoint_direction, kUSBClass, kUSBInterface);
+  command.bRequest = request_code;
+  command.wIndex = (unit_id << 8) | interface_number;
+  command.wValue = (control_selector << 8);
+  command.wLength = control_command_size;
+  command.wLenDone = 0;
+  return command;
+}
+
+// Send USB request to get information about pan and tilt controls.
+// Returns true if the request is successful. To send the request, the interface
+// must be opened already.
+static bool SendPanTiltControlRequest(
+    IOUSBInterfaceInterface220** control_interface,
+    int unit_id,
+    int request_code,
+    int* pan_result,
+    int* tilt_result) {
+  IOUSBDevRequest command = CreateEmptyPanTiltZoomRequest(
+      control_interface, unit_id, request_code, kUSBIn,
+      kCtPanTiltAbsoluteControl, kCtPanTiltAbsoluteControlCommandSize);
+  int32_t data[2];
+  command.pData = &data;
+
+  IOReturn ret =
+      (*control_interface)->ControlRequest(control_interface, 0, &command);
+  DLOG_IF(ERROR, ret != kIOReturnSuccess)
+      << "Control pan tilt request"
+      << " failed (0x" << std::hex << ret << "), unit id: " << unit_id;
+  if (ret != kIOReturnSuccess)
+    return false;
+
+  *pan_result = USBToHostLong(data[0]);
+  *tilt_result = USBToHostLong(data[1]);
+  return true;
+}
+
+// Send USB request to get information about zoom control.
+// Returns true if the request is successful. To send the request, the interface
+// must be opened already.
+static bool SendZoomControlRequest(
+    IOUSBInterfaceInterface220** control_interface,
+    int unit_id,
+    int request_code,
+    int* result) {
+  IOUSBDevRequest command = CreateEmptyPanTiltZoomRequest(
+      control_interface, unit_id, request_code, kUSBIn, kCtZoomAbsoluteControl,
+      kCtZoomAbsoluteControlCommandSize);
+  uint16_t data;
+  command.pData = &data;
+
+  IOReturn ret =
+      (*control_interface)->ControlRequest(control_interface, 0, &command);
+  DLOG_IF(ERROR, ret != kIOReturnSuccess)
+      << "Control zoom request"
+      << " failed (0x" << std::hex << ret << "), unit id: " << unit_id;
+  if (ret != kIOReturnSuccess)
+    return false;
+
+  *result = USBToHostLong(data);
+  return true;
+}
+
+// Retrieves the control range and current value of pan and tilt controls.
+// The interface must be opened already.
+static void GetPanTiltControlRangeAndCurrent(
+    IOUSBInterfaceInterface220** control_interface,
+    int unit_id,
+    mojom::Range* pan_range,
+    mojom::Range* tilt_range) {
+  int pan_max, pan_min, pan_step, pan_current;
+  int tilt_max, tilt_min, tilt_step, tilt_current;
+  if (!SendPanTiltControlRequest(control_interface, unit_id,
+                                 kVcRequestCodeGetMax, &pan_max, &tilt_max) ||
+      !SendPanTiltControlRequest(control_interface, unit_id,
+                                 kVcRequestCodeGetMin, &pan_min, &tilt_min) ||
+      !SendPanTiltControlRequest(control_interface, unit_id,
+                                 kVcRequestCodeGetRes, &pan_step, &tilt_step) ||
+      !SendPanTiltControlRequest(control_interface, unit_id,
+                                 kVcRequestCodeGetCur, &pan_current,
+                                 &tilt_current)) {
+    return;
+  }
+  pan_range->max = pan_max;
+  pan_range->min = pan_min;
+  pan_range->step = pan_step;
+  pan_range->current = pan_current;
+  tilt_range->max = tilt_max;
+  tilt_range->min = tilt_min;
+  tilt_range->step = tilt_step;
+  tilt_range->current = tilt_current;
+}
+
+// Retrieves the control range and current value of a zoom control. The
+// interface must be opened already.
+static void GetZoomControlRangeAndCurrent(
+    IOUSBInterfaceInterface220** control_interface,
+    int unit_id,
+    mojom::Range* zoom_range) {
+  int max, min, step, current;
+  if (!SendZoomControlRequest(control_interface, unit_id, kVcRequestCodeGetMax,
+                              &max) ||
+      !SendZoomControlRequest(control_interface, unit_id, kVcRequestCodeGetMin,
+                              &min) ||
+      !SendZoomControlRequest(control_interface, unit_id, kVcRequestCodeGetRes,
+                              &step) ||
+      !SendZoomControlRequest(control_interface, unit_id, kVcRequestCodeGetCur,
+                              &current)) {
+    return;
+  }
+  zoom_range->max = max;
+  zoom_range->min = min;
+  zoom_range->step = step;
+  zoom_range->current = current;
+}
+
+// Set pan and tilt values for a USB camera device. The interface must be opened
+// already.
+static void SetPanTiltInUsbDevice(
+    IOUSBInterfaceInterface220** control_interface,
+    int unit_id,
+    base::Optional<int> pan,
+    base::Optional<int> tilt) {
+  if (!pan.has_value() && !tilt.has_value())
+    return;
+
+  int pan_current, tilt_current;
+  if ((!pan.has_value() || !tilt.has_value()) &&
+      !SendPanTiltControlRequest(control_interface, unit_id,
+                                 kVcRequestCodeGetCur, &pan_current,
+                                 &tilt_current)) {
+    return;
+  }
+
+  uint32_t pan_tilt_data[2];
+  pan_tilt_data[0] =
+      CFSwapInt32HostToLittle((uint32_t)pan.value_or(pan_current));
+  pan_tilt_data[1] =
+      CFSwapInt32HostToLittle((uint32_t)tilt.value_or(tilt_current));
+
+  IOUSBDevRequest command = CreateEmptyPanTiltZoomRequest(
+      control_interface, unit_id, kVcRequestCodeSetCur, kUSBOut,
+      kCtPanTiltAbsoluteControl, kCtPanTiltAbsoluteControlCommandSize);
+  command.pData = pan_tilt_data;
+
+  IOReturn ret =
+      (*control_interface)->ControlRequest(control_interface, 0, &command);
+  DLOG_IF(ERROR, ret != kIOReturnSuccess)
+      << "Control request"
+      << " failed (0x" << std::hex << ret << "), unit id: " << unit_id
+      << " pan value: " << pan.value_or(pan_current)
+      << " tilt value: " << tilt.value_or(tilt_current);
+  DVLOG_IF(1, ret == kIOReturnSuccess)
+      << "Setting pan value to " << pan.value_or(pan_current)
+      << " and tilt value to " << tilt.value_or(tilt_current);
+}
+
+// Set zoom value for a USB camera device. The interface must be opened already.
+static void SetZoomInUsbDevice(IOUSBInterfaceInterface220** control_interface,
+                               int unit_id,
+                               int zoom) {
+  IOUSBDevRequest command = CreateEmptyPanTiltZoomRequest(
+      control_interface, unit_id, kVcRequestCodeSetCur, kUSBOut,
+      kCtZoomAbsoluteControl, kCtZoomAbsoluteControlCommandSize);
+  command.pData = &zoom;
+
+  IOReturn ret =
+      (*control_interface)->ControlRequest(control_interface, 0, &command);
+  DLOG_IF(ERROR, ret != kIOReturnSuccess)
+      << "Control request"
+      << " failed (0x" << std::hex << ret << "), unit id: " << unit_id
+      << " zoom value: " << zoom;
+  DVLOG_IF(1, ret == kIOReturnSuccess) << "Setting zoom value to " << zoom;
+}
+
+// Open the pan, tilt, zoom interface in a USB webcam identified by
+// |device_model|. Returns interface when it is succcessfully opened. You have
+// to close the interface manually when you're done.
+static ScopedIOUSBInterfaceInterface OpenPanTiltZoomControlInterface(
+    std::string device_model,
+    int* unit_id) {
+  if (device_model.length() <= 2 * kVidPidSize) {
+    return ScopedIOUSBInterfaceInterface();
+  }
+  std::string vendor_id = device_model.substr(0, kVidPidSize);
+  std::string product_id = device_model.substr(kVidPidSize + 1);
+  int vendor_id_as_int, product_id_as_int;
+  if (!base::HexStringToInt(vendor_id, &vendor_id_as_int) ||
+      !base::HexStringToInt(product_id, &product_id_as_int)) {
+    return ScopedIOUSBInterfaceInterface();
+  }
+
+  base::mac::ScopedIOObject<io_iterator_t> usb_iterator;
+  if (!FindDeviceWithVendorAndProductIds(vendor_id_as_int, product_id_as_int,
+                                         usb_iterator.InitializeInto())) {
+    return ScopedIOUSBInterfaceInterface();
+  }
+
+  base::mac::ScopedIOPluginInterface<IOCFPlugInInterface>
+      video_control_interface;
+
+  while (io_service_t usb_device = IOIteratorNext(usb_iterator)) {
+    base::mac::ScopedIOObject<io_service_t> usb_device_ref(usb_device);
+    base::mac::ScopedIOPluginInterface<IOUSBDeviceInterface> device_interface;
+
+    if (!FindDeviceInterfaceInUsbDevice(vendor_id_as_int, product_id_as_int,
+                                        usb_device,
+                                        device_interface.InitializeInto())) {
+      continue;
+    }
+
+    if (FindVideoControlInterfaceInDeviceInterface(
+            device_interface, video_control_interface.InitializeInto())) {
+      break;
+    }
+  }
+
+  if (video_control_interface == nullptr) {
+    return ScopedIOUSBInterfaceInterface();
+  }
+
+  // Create the control interface for the found plugin, and release
+  // the intermediate plugin.
+  ScopedIOUSBInterfaceInterface control_interface;
+  HRESULT res =
+      (*video_control_interface)
+          ->QueryInterface(
+              video_control_interface,
+              CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID220),
+              reinterpret_cast<LPVOID*>(control_interface.InitializeInto()));
+  if (!SUCCEEDED(res) || !control_interface) {
+    DLOG(ERROR) << "Couldn’t get control interface";
+    return ScopedIOUSBInterfaceInterface();
+  }
+
+  // Find the device's unit ID presenting type 0x24 (kVcCsInterface) and
+  // subtype 0x2 (kVcInputTerminal). Inside this unit is where we find the
+  // settings for pan, tilt, and zoom, and this id is device dependent.
+  IOUSBDescriptorHeader* descriptor = nullptr;
+  while ((descriptor =
+              (*control_interface)
+                  ->FindNextAssociatedDescriptor(control_interface.get(),
+                                                 descriptor, kVcCsInterface))) {
+    auto* cs_descriptor =
+        reinterpret_cast<VcCsInterfaceDescriptor*>(descriptor);
+    if (cs_descriptor->bDescriptorSubType == kVcInputTerminal) {
+      *unit_id = cs_descriptor->bUnitID;
+      break;
+    }
+  }
+
+  DVLOG_IF(1, *unit_id == -1)
+      << "This USB device doesn't seem to have a "
+      << " VC_INPUT_TERMINAL. Pan, tilt, zoom are not available.";
+  if (*unit_id == -1)
+    return ScopedIOUSBInterfaceInterface();
+
+  if ((*control_interface)->USBInterfaceOpen(control_interface) !=
+      kIOReturnSuccess) {
+    DLOG(ERROR) << "Unable to open control interface";
+    return ScopedIOUSBInterfaceInterface();
+  }
+
+  return control_interface;
+}
+
 VideoCaptureDeviceMac::VideoCaptureDeviceMac(
     const VideoCaptureDeviceDescriptor& device_descriptor)
     : device_descriptor_(device_descriptor),
@@ -350,11 +651,11 @@
       device_descriptor_.transport_type);
   if (device_model.length() > 2 * kVidPidSize) {
     std::string vendor_id = device_model.substr(0, kVidPidSize);
-    std::string model_id = device_model.substr(kVidPidSize + 1);
-    int vendor_id_as_int, model_id_as_int;
-    if (base::HexStringToInt(base::StringPiece(vendor_id), &vendor_id_as_int) &&
-        base::HexStringToInt(base::StringPiece(model_id), &model_id_as_int)) {
-      SetAntiFlickerInUsbDevice(vendor_id_as_int, model_id_as_int,
+    std::string product_id = device_model.substr(kVidPidSize + 1);
+    int vendor_id_as_int, product_id_as_int;
+    if (base::HexStringToInt(vendor_id, &vendor_id_as_int) &&
+        base::HexStringToInt(product_id, &product_id_as_int)) {
+      SetAntiFlickerInUsbDevice(vendor_id_as_int, product_id_as_int,
                                 GetPowerLineFrequency(params));
     }
   }
@@ -405,6 +706,21 @@
       capture_format_.frame_size.width(), capture_format_.frame_size.width(),
       capture_format_.frame_size.width(), 0 /* step */);
 
+  const std::string device_model = GetDeviceModelId(
+      device_descriptor_.device_id, device_descriptor_.capture_api,
+      device_descriptor_.transport_type);
+  int unit_id = -1;
+  ScopedIOUSBInterfaceInterface control_interface(
+      OpenPanTiltZoomControlInterface(device_model, &unit_id));
+  if (control_interface) {
+    GetPanTiltControlRangeAndCurrent(control_interface, unit_id,
+                                     photo_state->pan.get(),
+                                     photo_state->tilt.get());
+    GetZoomControlRangeAndCurrent(control_interface, unit_id,
+                                  photo_state->zoom.get());
+    (*control_interface)->USBInterfaceClose(control_interface);
+  }
+
   std::move(callback).Run(std::move(photo_state));
 }
 
@@ -420,6 +736,31 @@
       settings->has_fill_light_mode || settings->has_red_eye_reduction) {
     return;
   }
+
+  if (settings->has_pan || settings->has_tilt || settings->has_zoom) {
+    const std::string device_model = GetDeviceModelId(
+        device_descriptor_.device_id, device_descriptor_.capture_api,
+        device_descriptor_.transport_type);
+    int unit_id = -1;
+    ScopedIOUSBInterfaceInterface control_interface(
+        OpenPanTiltZoomControlInterface(device_model, &unit_id));
+    if (!control_interface)
+      return;
+
+    if (settings->has_pan || settings->has_tilt) {
+      SetPanTiltInUsbDevice(
+          control_interface, unit_id,
+          settings->has_pan ? base::make_optional(settings->pan)
+                            : base::nullopt,
+          settings->has_tilt ? base::make_optional(settings->tilt)
+                             : base::nullopt);
+    }
+    if (settings->has_zoom) {
+      SetZoomInUsbDevice(control_interface, unit_id, settings->zoom);
+    }
+    (*control_interface)->USBInterfaceClose(control_interface);
+  }
+
   std::move(callback).Run(true);
 }
 
@@ -539,6 +880,41 @@
   return id_vendor + ":" + id_product;
 }
 
+// Check if the video capture device supports at least one of pan, tilt and zoom
+// controls.
+// static
+bool VideoCaptureDeviceMac::IsPanTiltZoomSupported(
+    const std::string& device_model) {
+  int unit_id = -1;
+  ScopedIOUSBInterfaceInterface control_interface(
+      OpenPanTiltZoomControlInterface(device_model, &unit_id));
+  if (!control_interface)
+    return false;
+
+  bool result = false;
+  int zoom_max, zoom_min = 0;
+  if (SendZoomControlRequest(control_interface, unit_id, kVcRequestCodeGetMax,
+                             &zoom_max) &&
+      SendZoomControlRequest(control_interface, unit_id, kVcRequestCodeGetMin,
+                             &zoom_min) &&
+      zoom_min < zoom_max) {
+    result = true;
+  }
+  int pan_max, pan_min = 0;
+  int tilt_max, tilt_min = 0;
+  if (!result &&
+      SendPanTiltControlRequest(control_interface, unit_id,
+                                kVcRequestCodeGetMax, &pan_max, &tilt_max) &&
+      SendPanTiltControlRequest(control_interface, unit_id,
+                                kVcRequestCodeGetMin, &pan_min, &tilt_min) &&
+      ((pan_min < pan_max || tilt_min < tilt_max))) {
+    result = true;
+  }
+
+  (*control_interface)->USBInterfaceClose(control_interface);
+  return result;
+}
+
 void VideoCaptureDeviceMac::SetErrorState(VideoCaptureError error,
                                           const base::Location& from_here,
                                           const std::string& reason) {
diff --git a/media/fuchsia/audio/fuchsia_audio_renderer.cc b/media/fuchsia/audio/fuchsia_audio_renderer.cc
index 62a1ef1..3049d4b 100644
--- a/media/fuchsia/audio/fuchsia_audio_renderer.cc
+++ b/media/fuchsia/audio/fuchsia_audio_renderer.cc
@@ -485,6 +485,12 @@
 
   is_demuxer_read_pending_ = false;
 
+  if (drop_next_demuxer_read_result_) {
+    drop_next_demuxer_read_result_ = false;
+    ScheduleReadDemuxerStream();
+    return;
+  }
+
   if (read_status != DemuxerStream::kOk) {
     if (read_status == DemuxerStream::kError) {
       OnError(PIPELINE_ERROR_READ);
@@ -586,6 +592,10 @@
   SetBufferState(BUFFERING_HAVE_NOTHING);
   last_packet_timestamp_ = base::TimeDelta::Min();
   read_timer_.Stop();
+
+  if (is_demuxer_read_pending_) {
+    drop_next_demuxer_read_result_ = true;
+  }
 }
 
 void FuchsiaAudioRenderer::OnEndOfStream() {
diff --git a/media/fuchsia/audio/fuchsia_audio_renderer.h b/media/fuchsia/audio/fuchsia_audio_renderer.h
index 95ead1af..1a873caa 100644
--- a/media/fuchsia/audio/fuchsia_audio_renderer.h
+++ b/media/fuchsia/audio/fuchsia_audio_renderer.h
@@ -131,6 +131,7 @@
 
   DemuxerStream* demuxer_stream_ = nullptr;
   bool is_demuxer_read_pending_ = false;
+  bool drop_next_demuxer_read_result_ = false;
 
   RendererClient* client_ = nullptr;
 
diff --git a/media/gpu/vaapi/vaapi_utils.cc b/media/gpu/vaapi/vaapi_utils.cc
index 72e7ab68..450f0c8 100644
--- a/media/gpu/vaapi/vaapi_utils.cc
+++ b/media/gpu/vaapi/vaapi_utils.cc
@@ -190,20 +190,20 @@
          va_rt_format_ != kInvalidVaRtFormat;
 }
 
-bool FillVP8DataStructures(VaapiWrapper* vaapi_wrapper,
-                           VASurfaceID va_surface_id,
-                           const Vp8FrameHeader& frame_header,
-                           const Vp8ReferenceFrameVector& reference_frames) {
-  DCHECK_NE(va_surface_id, VA_INVALID_SURFACE);
-  DCHECK(vaapi_wrapper);
-
+void FillVP8DataStructures(const Vp8FrameHeader& frame_header,
+                           const Vp8ReferenceFrameVector& reference_frames,
+                           VAIQMatrixBufferVP8* iq_matrix_buf,
+                           VAProbabilityDataBufferVP8* prob_buf,
+                           VAPictureParameterBufferVP8* pic_param,
+                           VASliceParameterBufferVP8* slice_param) {
   const Vp8SegmentationHeader& sgmnt_hdr = frame_header.segmentation_hdr;
   const Vp8QuantizationHeader& quant_hdr = frame_header.quantization_hdr;
-  VAIQMatrixBufferVP8 iq_matrix_buf{};
-  static_assert(base::size(iq_matrix_buf.quantization_index) == kMaxMBSegments,
+  static_assert(base::size(decltype(iq_matrix_buf->quantization_index){}) ==
+                    kMaxMBSegments,
                 "incorrect quantization matrix segment size");
-  static_assert(base::size(iq_matrix_buf.quantization_index[0]) == 6,
-                "incorrect quantization matrix Q index size");
+  static_assert(
+      base::size(decltype(iq_matrix_buf->quantization_index){}[0]) == 6,
+      "incorrect quantization matrix Q index size");
   for (size_t i = 0; i < kMaxMBSegments; ++i) {
     int q = quant_hdr.y_ac_qi;
 
@@ -217,52 +217,54 @@
     }
 
 #define CLAMP_Q(q) base::ClampToRange(q, 0, 127)
-    iq_matrix_buf.quantization_index[i][0] = CLAMP_Q(q);
-    iq_matrix_buf.quantization_index[i][1] = CLAMP_Q(q + quant_hdr.y_dc_delta);
-    iq_matrix_buf.quantization_index[i][2] = CLAMP_Q(q + quant_hdr.y2_dc_delta);
-    iq_matrix_buf.quantization_index[i][3] = CLAMP_Q(q + quant_hdr.y2_ac_delta);
-    iq_matrix_buf.quantization_index[i][4] = CLAMP_Q(q + quant_hdr.uv_dc_delta);
-    iq_matrix_buf.quantization_index[i][5] = CLAMP_Q(q + quant_hdr.uv_ac_delta);
+    iq_matrix_buf->quantization_index[i][0] = CLAMP_Q(q);
+    iq_matrix_buf->quantization_index[i][1] = CLAMP_Q(q + quant_hdr.y_dc_delta);
+    iq_matrix_buf->quantization_index[i][2] =
+        CLAMP_Q(q + quant_hdr.y2_dc_delta);
+    iq_matrix_buf->quantization_index[i][3] =
+        CLAMP_Q(q + quant_hdr.y2_ac_delta);
+    iq_matrix_buf->quantization_index[i][4] =
+        CLAMP_Q(q + quant_hdr.uv_dc_delta);
+    iq_matrix_buf->quantization_index[i][5] =
+        CLAMP_Q(q + quant_hdr.uv_ac_delta);
 #undef CLAMP_Q
   }
 
   const Vp8EntropyHeader& entr_hdr = frame_header.entropy_hdr;
-  VAProbabilityDataBufferVP8 prob_buf{};
-  CheckedMemcpy(prob_buf.dct_coeff_probs, entr_hdr.coeff_probs);
+  CheckedMemcpy(prob_buf->dct_coeff_probs, entr_hdr.coeff_probs);
 
-  VAPictureParameterBufferVP8 pic_param{};
-  pic_param.frame_width = frame_header.width;
-  pic_param.frame_height = frame_header.height;
+  pic_param->frame_width = frame_header.width;
+  pic_param->frame_height = frame_header.height;
 
   const auto last_frame = reference_frames.GetFrame(Vp8RefType::VP8_FRAME_LAST);
   if (last_frame) {
-    pic_param.last_ref_frame =
+    pic_param->last_ref_frame =
         last_frame->AsVaapiVP8Picture()->GetVASurfaceID();
   } else {
-    pic_param.last_ref_frame = VA_INVALID_SURFACE;
+    pic_param->last_ref_frame = VA_INVALID_SURFACE;
   }
 
   const auto golden_frame =
       reference_frames.GetFrame(Vp8RefType::VP8_FRAME_GOLDEN);
   if (golden_frame) {
-    pic_param.golden_ref_frame =
+    pic_param->golden_ref_frame =
         golden_frame->AsVaapiVP8Picture()->GetVASurfaceID();
   } else {
-    pic_param.golden_ref_frame = VA_INVALID_SURFACE;
+    pic_param->golden_ref_frame = VA_INVALID_SURFACE;
   }
 
   const auto alt_frame =
       reference_frames.GetFrame(Vp8RefType::VP8_FRAME_ALTREF);
   if (alt_frame)
-    pic_param.alt_ref_frame = alt_frame->AsVaapiVP8Picture()->GetVASurfaceID();
+    pic_param->alt_ref_frame = alt_frame->AsVaapiVP8Picture()->GetVASurfaceID();
   else
-    pic_param.alt_ref_frame = VA_INVALID_SURFACE;
+    pic_param->alt_ref_frame = VA_INVALID_SURFACE;
 
-  pic_param.out_of_loop_frame = VA_INVALID_SURFACE;
+  pic_param->out_of_loop_frame = VA_INVALID_SURFACE;
 
   const Vp8LoopFilterHeader& lf_hdr = frame_header.loopfilter_hdr;
 
-#define FHDR_TO_PP_PF(a, b) pic_param.pic_fields.bits.a = (b)
+#define FHDR_TO_PP_PF(a, b) pic_param->pic_fields.bits.a = (b)
   FHDR_TO_PP_PF(key_frame, frame_header.IsKeyframe() ? 0 : 1);
   FHDR_TO_PP_PF(version, frame_header.version);
   FHDR_TO_PP_PF(segmentation_enabled, sgmnt_hdr.segmentation_enabled);
@@ -280,10 +282,10 @@
   FHDR_TO_PP_PF(loop_filter_disable, lf_hdr.level == 0);
 #undef FHDR_TO_PP_PF
 
-  CheckedMemcpy(pic_param.mb_segment_tree_probs, sgmnt_hdr.segment_prob);
+  CheckedMemcpy(pic_param->mb_segment_tree_probs, sgmnt_hdr.segment_prob);
 
   static_assert(std::extent<decltype(sgmnt_hdr.lf_update_value)>() ==
-                    std::extent<decltype(pic_param.loop_filter_level)>(),
+                    std::extent<decltype(pic_param->loop_filter_level)>(),
                 "loop filter level arrays mismatch");
   for (size_t i = 0; i < base::size(sgmnt_hdr.lf_update_value); ++i) {
     int lf_level = lf_hdr.level;
@@ -296,61 +298,53 @@
       }
     }
 
-    pic_param.loop_filter_level[i] = base::ClampToRange(lf_level, 0, 63);
+    pic_param->loop_filter_level[i] = base::ClampToRange(lf_level, 0, 63);
   }
 
   static_assert(
       std::extent<decltype(lf_hdr.ref_frame_delta)>() ==
-          std::extent<decltype(pic_param.loop_filter_deltas_ref_frame)>(),
+          std::extent<decltype(pic_param->loop_filter_deltas_ref_frame)>(),
       "loop filter deltas arrays size mismatch");
   static_assert(std::extent<decltype(lf_hdr.mb_mode_delta)>() ==
-                    std::extent<decltype(pic_param.loop_filter_deltas_mode)>(),
+                    std::extent<decltype(pic_param->loop_filter_deltas_mode)>(),
                 "loop filter deltas arrays size mismatch");
   static_assert(std::extent<decltype(lf_hdr.ref_frame_delta)>() ==
                     std::extent<decltype(lf_hdr.mb_mode_delta)>(),
                 "loop filter deltas arrays size mismatch");
   for (size_t i = 0; i < base::size(lf_hdr.ref_frame_delta); ++i) {
-    pic_param.loop_filter_deltas_ref_frame[i] = lf_hdr.ref_frame_delta[i];
-    pic_param.loop_filter_deltas_mode[i] = lf_hdr.mb_mode_delta[i];
+    pic_param->loop_filter_deltas_ref_frame[i] = lf_hdr.ref_frame_delta[i];
+    pic_param->loop_filter_deltas_mode[i] = lf_hdr.mb_mode_delta[i];
   }
 
-#define FHDR_TO_PP(a) pic_param.a = frame_header.a
+#define FHDR_TO_PP(a) pic_param->a = frame_header.a
   FHDR_TO_PP(prob_skip_false);
   FHDR_TO_PP(prob_intra);
   FHDR_TO_PP(prob_last);
   FHDR_TO_PP(prob_gf);
 #undef FHDR_TO_PP
 
-  CheckedMemcpy(pic_param.y_mode_probs, entr_hdr.y_mode_probs);
-  CheckedMemcpy(pic_param.uv_mode_probs, entr_hdr.uv_mode_probs);
-  CheckedMemcpy(pic_param.mv_probs, entr_hdr.mv_probs);
+  CheckedMemcpy(pic_param->y_mode_probs, entr_hdr.y_mode_probs);
+  CheckedMemcpy(pic_param->uv_mode_probs, entr_hdr.uv_mode_probs);
+  CheckedMemcpy(pic_param->mv_probs, entr_hdr.mv_probs);
 
-  pic_param.bool_coder_ctx.range = frame_header.bool_dec_range;
-  pic_param.bool_coder_ctx.value = frame_header.bool_dec_value;
-  pic_param.bool_coder_ctx.count = frame_header.bool_dec_count;
+  pic_param->bool_coder_ctx.range = frame_header.bool_dec_range;
+  pic_param->bool_coder_ctx.value = frame_header.bool_dec_value;
+  pic_param->bool_coder_ctx.count = frame_header.bool_dec_count;
 
-  VASliceParameterBufferVP8 slice_param{};
-  slice_param.slice_data_size = frame_header.frame_size;
-  slice_param.slice_data_offset = frame_header.first_part_offset;
-  slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
-  slice_param.macroblock_offset = frame_header.macroblock_bit_offset;
+  slice_param->slice_data_size = frame_header.frame_size;
+  slice_param->slice_data_offset = frame_header.first_part_offset;
+  slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
+  slice_param->macroblock_offset = frame_header.macroblock_bit_offset;
   // Number of DCT partitions plus control partition.
-  slice_param.num_of_partitions = frame_header.num_of_dct_partitions + 1;
+  slice_param->num_of_partitions = frame_header.num_of_dct_partitions + 1;
 
   // Per VAAPI, this size only includes the size of the macroblock data in
   // the first partition (in bytes), so we have to subtract the header size.
-  slice_param.partition_size[0] =
+  slice_param->partition_size[0] =
       frame_header.first_part_size -
       ((frame_header.macroblock_bit_offset + 7) / 8);
 
   for (size_t i = 0; i < frame_header.num_of_dct_partitions; ++i)
-    slice_param.partition_size[i + 1] = frame_header.dct_partition_sizes[i];
-
-  return vaapi_wrapper->SubmitBuffers(
-      {{VAIQMatrixBufferType, sizeof(iq_matrix_buf), &iq_matrix_buf},
-       {VAProbabilityBufferType, sizeof(prob_buf), &prob_buf},
-       {VAPictureParameterBufferType, sizeof(pic_param), &pic_param},
-       {VASliceParameterBufferType, sizeof(slice_param), &slice_param},
-       {VASliceDataBufferType, frame_header.frame_size, frame_header.data}});
+    slice_param->partition_size[i + 1] = frame_header.dct_partition_sizes[i];
 }
 }  // namespace media
diff --git a/media/gpu/vaapi/vaapi_utils.h b/media/gpu/vaapi/vaapi_utils.h
index ac4bb78f..0db323e 100644
--- a/media/gpu/vaapi/vaapi_utils.h
+++ b/media/gpu/vaapi/vaapi_utils.h
@@ -174,12 +174,13 @@
   ReleaseCB release_cb_;
 };
 
-// Adapts |frame_header| to the Vaapi data types, prepping it for consumption by
-// |vaapi_wrapper|
-bool FillVP8DataStructures(VaapiWrapper* vaapi_wrapper,
-                           VASurfaceID va_surface_id,
-                           const Vp8FrameHeader& frame_header,
-                           const Vp8ReferenceFrameVector& reference_frames);
+// Adapts |frame_header| to the Vaapi data types.
+void FillVP8DataStructures(const Vp8FrameHeader& frame_header,
+                           const Vp8ReferenceFrameVector& reference_frames,
+                           VAIQMatrixBufferVP8* iq_matrix_buf,
+                           VAProbabilityDataBufferVP8* prob_buf,
+                           VAPictureParameterBufferVP8* pic_param,
+                           VASliceParameterBufferVP8* slice_param);
 }  // namespace media
 
 #endif  // MEDIA_GPU_VAAPI_VAAPI_UTILS_H_
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
index dbbd453d..3772ad5 100644
--- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -1066,7 +1066,8 @@
 
   // Notify |decoder_delegate_| of an imminent VAContextID destruction, so it
   // can destroy any internal structures making use of it. At this point
-  // |decoder_thread_| is stopped so we can access these from |task_runner_|.
+  // |decoder_thread_| is stopped so we can access |decoder_delegate_| from
+  // |task_runner_|.
   decoder_delegate_->OnVAContextDestructionSoon();
   vaapi_wrapper_->DestroyContext();
 
diff --git a/media/gpu/vaapi/vaapi_webp_decoder.cc b/media/gpu/vaapi/vaapi_webp_decoder.cc
index 866965d..ef395f914 100644
--- a/media/gpu/vaapi/vaapi_webp_decoder.cc
+++ b/media/gpu/vaapi/vaapi_webp_decoder.cc
@@ -120,14 +120,24 @@
     }
     DCHECK(scoped_va_context_and_surface_->IsValid());
   }
+  DCHECK_NE(scoped_va_context_and_surface_->id(), VA_INVALID_SURFACE);
 
-  if (!FillVP8DataStructures(vaapi_wrapper_.get(),
-                             scoped_va_context_and_surface_->id(),
-                             *parse_result, Vp8ReferenceFrameVector())) {
-    return VaapiImageDecodeStatus::kSubmitVABuffersFailed;
-  }
+  VAIQMatrixBufferVP8 iq_matrix_buf{};
+  VAProbabilityDataBufferVP8 prob_buf{};
+  VAPictureParameterBufferVP8 pic_param{};
+  VASliceParameterBufferVP8 slice_param{};
+  FillVP8DataStructures(*parse_result, Vp8ReferenceFrameVector(),
+                        &iq_matrix_buf, &prob_buf, &pic_param, &slice_param);
 
-  return VaapiImageDecodeStatus::kSuccess;
+  const bool success = vaapi_wrapper_->SubmitBuffers(
+      {{VAIQMatrixBufferType, sizeof(iq_matrix_buf), &iq_matrix_buf},
+       {VAProbabilityBufferType, sizeof(prob_buf), &prob_buf},
+       {VAPictureParameterBufferType, sizeof(pic_param), &pic_param},
+       {VASliceParameterBufferType, sizeof(slice_param), &slice_param},
+       {VASliceDataBufferType, parse_result->frame_size, parse_result->data}});
+
+  return success ? VaapiImageDecodeStatus::kSuccess
+                 : VaapiImageDecodeStatus::kSubmitVABuffersFailed;
 }
 
 }  // namespace media
diff --git a/media/gpu/vaapi/vp8_vaapi_video_decoder_delegate.cc b/media/gpu/vaapi/vp8_vaapi_video_decoder_delegate.cc
index c68ca3b..e9e2150 100644
--- a/media/gpu/vaapi/vp8_vaapi_video_decoder_delegate.cc
+++ b/media/gpu/vaapi/vp8_vaapi_video_decoder_delegate.cc
@@ -18,7 +18,12 @@
     scoped_refptr<VaapiWrapper> vaapi_wrapper)
     : VaapiVideoDecoderDelegate(vaapi_dec, std::move(vaapi_wrapper)) {}
 
-VP8VaapiVideoDecoderDelegate::~VP8VaapiVideoDecoderDelegate() = default;
+VP8VaapiVideoDecoderDelegate::~VP8VaapiVideoDecoderDelegate() {
+  DCHECK(!iq_matrix_);
+  DCHECK(!prob_buffer_);
+  DCHECK(!picture_params_);
+  DCHECK(!slice_params_);
+}
 
 scoped_refptr<VP8Picture> VP8VaapiVideoDecoderDelegate::CreateVP8Picture() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -35,14 +40,63 @@
   TRACE_EVENT0("media,gpu", "VP8VaapiVideoDecoderDelegate::SubmitDecode");
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  auto va_surface_id = pic->AsVaapiVP8Picture()->va_surface()->id();
+  const auto va_surface_id = pic->AsVaapiVP8Picture()->va_surface()->id();
+  DCHECK_NE(va_surface_id, VA_INVALID_SURFACE);
 
-  if (!FillVP8DataStructures(vaapi_wrapper_.get(), va_surface_id,
-                             *pic->frame_hdr, reference_frames)) {
-    return false;
+  VAIQMatrixBufferVP8 iq_matrix_buf{};
+  VAProbabilityDataBufferVP8 prob_buf{};
+  VAPictureParameterBufferVP8 pic_param{};
+  VASliceParameterBufferVP8 slice_param{};
+
+  const Vp8FrameHeader* const header = pic->frame_hdr.get();
+  DCHECK(header);
+
+  FillVP8DataStructures(*header, reference_frames, &iq_matrix_buf, &prob_buf,
+                        &pic_param, &slice_param);
+
+  if (!iq_matrix_) {
+    iq_matrix_ = vaapi_wrapper_->CreateVABuffer(VAIQMatrixBufferType,
+                                                sizeof(iq_matrix_buf));
+    if (!iq_matrix_)
+      return false;
   }
+  if (!prob_buffer_) {
+    prob_buffer_ = vaapi_wrapper_->CreateVABuffer(VAProbabilityBufferType,
+                                                  sizeof(prob_buf));
+    if (!prob_buffer_)
+      return false;
+  }
+  if (!picture_params_) {
+    picture_params_ = vaapi_wrapper_->CreateVABuffer(
+        VAPictureParameterBufferType, sizeof(pic_param));
+    if (!picture_params_)
+      return false;
+  }
+  if (!slice_params_) {
+    slice_params_ = vaapi_wrapper_->CreateVABuffer(VASliceParameterBufferType,
+                                                   sizeof(slice_param));
+    if (!slice_params_)
+      return false;
+  }
+  // |encoded_data| cannot be reused even when it's of the appropriate size, due
+  // to strange stutterings in e.g. Gen 9.5.
+  std::unique_ptr<ScopedVABuffer> encoded_data =
+      vaapi_wrapper_->CreateVABuffer(VASliceDataBufferType, header->frame_size);
+  if (!encoded_data)
+    return false;
 
-  return vaapi_wrapper_->ExecuteAndDestroyPendingBuffers(va_surface_id);
+  return vaapi_wrapper_->MapAndCopyAndExecute(
+      va_surface_id,
+      {{iq_matrix_->id(),
+        {iq_matrix_->type(), iq_matrix_->size(), &iq_matrix_buf}},
+       {prob_buffer_->id(),
+        {prob_buffer_->type(), prob_buffer_->size(), &prob_buf}},
+       {picture_params_->id(),
+        {picture_params_->type(), picture_params_->size(), &pic_param}},
+       {slice_params_->id(),
+        {slice_params_->type(), slice_params_->size(), &slice_param}},
+       {encoded_data->id(),
+        {encoded_data->type(), header->frame_size, header->data}}});
 }
 
 bool VP8VaapiVideoDecoderDelegate::OutputPicture(
@@ -56,4 +110,12 @@
   return true;
 }
 
+void VP8VaapiVideoDecoderDelegate::OnVAContextDestructionSoon() {
+  // Destroy the member ScopedVABuffers below since they refer to a VAContextID
+  // that will be destroyed soon. iq_matrix_.reset();
+  prob_buffer_.reset();
+  picture_params_.reset();
+  slice_params_.reset();
+}
+
 }  // namespace media
diff --git a/media/gpu/vaapi/vp8_vaapi_video_decoder_delegate.h b/media/gpu/vaapi/vp8_vaapi_video_decoder_delegate.h
index 01a3013..9a299d8 100644
--- a/media/gpu/vaapi/vp8_vaapi_video_decoder_delegate.h
+++ b/media/gpu/vaapi/vp8_vaapi_video_decoder_delegate.h
@@ -13,6 +13,7 @@
 
 namespace media {
 
+class ScopedVABuffer;
 class VP8Picture;
 
 class VP8VaapiVideoDecoderDelegate : public VP8Decoder::VP8Accelerator,
@@ -29,6 +30,15 @@
                     const Vp8ReferenceFrameVector& reference_frames) override;
   bool OutputPicture(scoped_refptr<VP8Picture> pic) override;
 
+  // VaapiVideoDecoderDelegate impl.
+  void OnVAContextDestructionSoon() override;
+
+ private:
+  std::unique_ptr<ScopedVABuffer> iq_matrix_;
+  std::unique_ptr<ScopedVABuffer> prob_buffer_;
+  std::unique_ptr<ScopedVABuffer> picture_params_;
+  std::unique_ptr<ScopedVABuffer> slice_params_;
+
   DISALLOW_COPY_AND_ASSIGN(VP8VaapiVideoDecoderDelegate);
 };
 
diff --git a/mojo/public/tools/bindings/README.md b/mojo/public/tools/bindings/README.md
index 1a3d5c5..228a2d3 100644
--- a/mojo/public/tools/bindings/README.md
+++ b/mojo/public/tools/bindings/README.md
@@ -555,13 +555,14 @@
 };
 ```
 
-and you would like to add a birthday field. You can do:
+and you would like to add birthday and nickname fields. You can do:
 
 ``` cpp
 struct Employee {
   uint64 employee_id;
   string name;
   [MinVersion=1] Date? birthday;
+  [MinVersion=1] string? nickname;
 };
 ```
 
@@ -570,10 +571,14 @@
 with the `MinVersion` attribute set to a number greater than any previous
 existing versions.
 
+The value of `MinVersion` is unrelated to ordinals. The choice of a particular
+version number is arbitrary. All its usage means is that a field isn't present
+before the numbered version.
+
 *** note
 **NOTE:** do not change existing fields in versioned structs, as this is
 not backwards-compatible. Instead, rename the old field to make its
-deprecation clear and add a new field with the new version number.
+deprecation clear and add a new field with a new `MinVersion` number.
 ***
 
 **Ordinal value** refers to the relative positional layout of a struct's fields
@@ -602,6 +607,7 @@
   uint64 employee_id@0;
   [MinVersion=1] Date? birthday@2;
   string name@1;
+  [MinVersion=1] string? nickname@3;
 };
 ```
 
diff --git a/mojo/public/tools/mojom/check_stable_mojom_compatibility.py b/mojo/public/tools/mojom/check_stable_mojom_compatibility.py
index 7e74611..08bd672f 100755
--- a/mojo/public/tools/mojom/check_stable_mojom_compatibility.py
+++ b/mojo/public/tools/mojom/check_stable_mojom_compatibility.py
@@ -131,7 +131,8 @@
           'renamed, please add a [RenamedFrom] attribute to the new type. This '
           'can be deleted by a subsequent change.' % qualified_name)
 
-    if not new_types[new_name].IsBackwardCompatible(kind):
+    checker = module.BackwardCompatibilityChecker()
+    if not checker.IsBackwardCompatible(new_types[new_name], kind):
       raise Exception('Stable type %s appears to have changed in a way which '
                       'breaks backward-compatibility. Please fix!\n\nIf you '
                       'believe this assessment to be incorrect, please file a '
diff --git a/mojo/public/tools/mojom/mojom/generate/module.py b/mojo/public/tools/mojom/mojom/generate/module.py
index a8083bd..ebbc9b3 100644
--- a/mojo/public/tools/mojom/mojom/generate/module.py
+++ b/mojo/public/tools/mojom/mojom/generate/module.py
@@ -14,6 +14,27 @@
 
 import pickle
 
+
+class BackwardCompatibilityChecker(object):
+  """Used for memoization while recursively checking two type definitions for
+  backward-compatibility."""
+
+  def __init__(self):
+    self._cache = {}
+
+  def IsBackwardCompatible(self, new_kind, old_kind):
+    key = (new_kind, old_kind)
+    result = self._cache.get(key)
+    if result is None:
+      # Assume they're compatible at first to effectively ignore recursive
+      # checks between these types, e.g. if both kinds are a struct or union
+      # that references itself in a field.
+      self._cache[key] = True
+      result = new_kind.IsBackwardCompatible(old_kind, self)
+      self._cache[key] = result
+    return result
+
+
 # We use our own version of __repr__ when displaying the AST, as the
 # AST currently doesn't capture which nodes are reference (e.g. to
 # types) and which nodes are definitions. This allows us to e.g. print
@@ -114,7 +135,8 @@
     # during a subsequent run of the parser.
     return hash((self.spec, self.parent_kind))
 
-  def IsBackwardCompatible(self, rhs):
+  # pylint: disable=unused-argument
+  def IsBackwardCompatible(self, rhs, checker):
     return self == rhs
 
 
@@ -198,8 +220,8 @@
   def __hash__(self):
     return hash((super(ReferenceKind, self).__hash__(), self.is_nullable))
 
-  def IsBackwardCompatible(self, rhs):
-    return (super(ReferenceKind, self).IsBackwardCompatible(rhs)
+  def IsBackwardCompatible(self, rhs, checker):
+    return (super(ReferenceKind, self).IsBackwardCompatible(rhs, checker)
             and self.is_nullable == rhs.is_nullable)
 
 
@@ -383,11 +405,11 @@
   pass
 
 
-def _IsFieldBackwardCompatible(new_field, old_field):
+def _IsFieldBackwardCompatible(new_field, old_field, checker):
   if (new_field.min_version or 0) != (old_field.min_version or 0):
     return False
 
-  return new_field.kind.IsBackwardCompatible(old_field.kind)
+  return checker.IsBackwardCompatible(new_field.kind, old_field.kind)
 
 
 class Struct(ReferenceKind):
@@ -462,7 +484,7 @@
     for constant in self.constants:
       constant.Stylize(stylizer)
 
-  def IsBackwardCompatible(self, older_struct):
+  def IsBackwardCompatible(self, older_struct, checker):
     """This struct is backward-compatible with older_struct if and only if all
     of the following conditions hold:
       - Any newly added field is tagged with a [MinVersion] attribute specifying
@@ -501,7 +523,7 @@
       old_field = old_fields[ordinal]
       if (old_field.min_version or 0) > max_old_min_version:
         max_old_min_version = old_field.min_version
-      if not _IsFieldBackwardCompatible(new_field, old_field):
+      if not _IsFieldBackwardCompatible(new_field, old_field, checker):
         # Type or min-version mismatch between old and new versions of the same
         # ordinal field.
         return False
@@ -595,7 +617,7 @@
     for field in self.fields:
       field.Stylize(stylizer)
 
-  def IsBackwardCompatible(self, older_union):
+  def IsBackwardCompatible(self, older_union, checker):
     """This union is backward-compatible with older_union if and only if all
     of the following conditions hold:
       - Any newly added field is tagged with a [MinVersion] attribute specifying
@@ -628,7 +650,7 @@
       if not new_field:
         # A field was removed, which is not OK.
         return False
-      if not _IsFieldBackwardCompatible(new_field, old_field):
+      if not _IsFieldBackwardCompatible(new_field, old_field, checker):
         # An field changed its type or MinVersion, which is not OK.
         return False
       old_min_version = old_field.min_version or 0
@@ -708,9 +730,9 @@
   def __hash__(self):
     return id(self)
 
-  def IsBackwardCompatible(self, rhs):
+  def IsBackwardCompatible(self, rhs, checker):
     return (isinstance(rhs, Array) and self.length == rhs.length
-            and self.kind.IsBackwardCompatible(rhs.kind))
+            and checker.IsBackwardCompatible(self.kind, rhs.kind))
 
 
 class Map(ReferenceKind):
@@ -756,10 +778,10 @@
   def __hash__(self):
     return id(self)
 
-  def IsBackwardCompatible(self, rhs):
+  def IsBackwardCompatible(self, rhs, checker):
     return (isinstance(rhs, Map)
-            and self.key_kind.IsBackwardCompatible(rhs.key_kind)
-            and self.value_kind.IsBackwardCompatible(rhs.value_kind))
+            and checker.IsBackwardCompatible(self.key_kind, rhs.key_kind)
+            and checker.IsBackwardCompatible(self.value_kind, rhs.value_kind))
 
 
 class PendingRemote(ReferenceKind):
@@ -782,9 +804,9 @@
   def __hash__(self):
     return id(self)
 
-  def IsBackwardCompatible(self, rhs):
+  def IsBackwardCompatible(self, rhs, checker):
     return (isinstance(rhs, PendingRemote)
-            and self.kind.IsBackwardCompatible(rhs.kind))
+            and checker.IsBackwardCompatible(self.kind, rhs.kind))
 
 
 class PendingReceiver(ReferenceKind):
@@ -807,9 +829,9 @@
   def __hash__(self):
     return id(self)
 
-  def IsBackwardCompatible(self, rhs):
-    return isinstance(rhs, PendingReceiver) and self.kind.IsBackwardCompatible(
-        rhs.kind)
+  def IsBackwardCompatible(self, rhs, checker):
+    return isinstance(rhs, PendingReceiver) and checker.IsBackwardCompatible(
+        self.kind, rhs.kind)
 
 
 class PendingAssociatedRemote(ReferenceKind):
@@ -832,10 +854,10 @@
   def __hash__(self):
     return id(self)
 
-  def IsBackwardCompatible(self, rhs):
-    return isinstance(
-        rhs, PendingAssociatedRemote) and self.kind.IsBackwardCompatible(
-            rhs.kind)
+  def IsBackwardCompatible(self, rhs, checker):
+    return isinstance(rhs,
+                      PendingAssociatedRemote) and checker.IsBackwardCompatible(
+                          self.kind, rhs.kind)
 
 
 class PendingAssociatedReceiver(ReferenceKind):
@@ -858,10 +880,10 @@
   def __hash__(self):
     return id(self)
 
-  def IsBackwardCompatible(self, rhs):
+  def IsBackwardCompatible(self, rhs, checker):
     return isinstance(
-        rhs, PendingAssociatedReceiver) and self.kind.IsBackwardCompatible(
-            rhs.kind)
+        rhs, PendingAssociatedReceiver) and checker.IsBackwardCompatible(
+            self.kind, rhs.kind)
 
 
 class InterfaceRequest(ReferenceKind):
@@ -883,9 +905,9 @@
   def __hash__(self):
     return id(self)
 
-  def IsBackwardCompatible(self, rhs):
-    return isinstance(rhs, InterfaceRequest) and self.kind.IsBackwardCompatible(
-        rhs.kind)
+  def IsBackwardCompatible(self, rhs, checker):
+    return isinstance(rhs, InterfaceRequest) and checker.IsBackwardCompatible(
+        self.kind, rhs.kind)
 
 
 class AssociatedInterfaceRequest(ReferenceKind):
@@ -909,10 +931,10 @@
   def __hash__(self):
     return id(self)
 
-  def IsBackwardCompatible(self, rhs):
+  def IsBackwardCompatible(self, rhs, checker):
     return isinstance(
-        rhs, AssociatedInterfaceRequest) and self.kind.IsBackwardCompatible(
-            rhs.kind)
+        rhs, AssociatedInterfaceRequest) and checker.IsBackwardCompatible(
+            self.kind, rhs.kind)
 
 
 class Parameter(object):
@@ -1075,7 +1097,7 @@
     for constant in self.constants:
       constant.Stylize(stylizer)
 
-  def IsBackwardCompatible(self, older_interface):
+  def IsBackwardCompatible(self, older_interface, checker):
     """This interface is backward-compatible with older_interface if and only
     if all of the following conditions hold:
       - All defined methods in older_interface (when identified by ordinal) have
@@ -1113,8 +1135,8 @@
         # A method was removed, which is not OK.
         return False
 
-      if not new_method.param_struct.IsBackwardCompatible(
-          old_method.param_struct):
+      if not checker.IsBackwardCompatible(new_method.param_struct,
+                                          old_method.param_struct):
         # The parameter list is not backward-compatible, which is not OK.
         return False
 
@@ -1127,8 +1149,8 @@
         if new_method.response_param_struct is None:
           # A reply was removed from a message, which is not OK.
           return False
-        if not new_method.response_param_struct.IsBackwardCompatible(
-            old_method.response_param_struct):
+        if not checker.IsBackwardCompatible(new_method.response_param_struct,
+                                            old_method.response_param_struct):
           # The new message's reply is not backward-compatible with the old
           # message's reply, which is not OK.
           return False
@@ -1190,9 +1212,10 @@
   def __hash__(self):
     return id(self)
 
-  def IsBackwardCompatible(self, rhs):
-    return isinstance(
-        rhs, AssociatedInterface) and self.kind.IsBackwardCompatible(rhs.kind)
+  def IsBackwardCompatible(self, rhs, checker):
+    return isinstance(rhs,
+                      AssociatedInterface) and checker.IsBackwardCompatible(
+                          self.kind, rhs.kind)
 
 
 class EnumField(object):
@@ -1266,7 +1289,8 @@
       prefix = self.module.GetNamespacePrefix()
     return '%s%s' % (prefix, self.mojom_name)
 
-  def IsBackwardCompatible(self, older_enum):
+  # pylint: disable=unused-argument
+  def IsBackwardCompatible(self, older_enum, checker):
     """This enum is backward-compatible with older_enum if and only if one of
     the following conditions holds:
         - Neither enum is [Extensible] and both have the exact same set of valid
diff --git a/mojo/public/tools/mojom/version_compatibility_unittest.py b/mojo/public/tools/mojom/version_compatibility_unittest.py
index b70cf8f0..65db4dc 100644
--- a/mojo/public/tools/mojom/version_compatibility_unittest.py
+++ b/mojo/public/tools/mojom/version_compatibility_unittest.py
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from mojom.generate import module
 from mojom_parser_test_case import MojomParserTestCase
 
 
@@ -20,9 +21,11 @@
     self.assertEqual(set(old.keys()), set(new.keys()),
                      'Old and new test mojoms should use the same type names.')
 
+    checker = module.BackwardCompatibilityChecker()
     compatibility_map = {}
     for name in old.keys():
-      compatibility_map[name] = new[name].IsBackwardCompatible(old[name])
+      compatibility_map[name] = checker.IsBackwardCompatible(
+          new[name], old[name])
     return compatibility_map
 
   def assertBackwardCompatible(self, old_mojom, new_mojom):
@@ -261,6 +264,20 @@
         struct S { pending_receiver<F> r; };
         """)
 
+  def testRecursiveTypeChange(self):
+    """Recursive types do not break the compatibility checker."""
+    self.assertBackwardCompatible(
+        """\
+        struct S {
+          string a;
+          array<S> others;
+        };""", """\
+        struct S {
+          string a;
+          array<S> others;
+          [MinVersion=1] string? b;
+        };""")
+
   def testUnionFieldBecomingNonOptional(self):
     """Changing a field from optional to non-optional breaks
     backward-compatibility."""
diff --git a/pdf/document_layout.cc b/pdf/document_layout.cc
index 0809cc75..9f5b12c 100644
--- a/pdf/document_layout.cc
+++ b/pdf/document_layout.cc
@@ -8,8 +8,6 @@
 
 #include "base/check_op.h"
 #include "base/values.h"
-#include "ppapi/cpp/var.h"
-#include "ppapi/cpp/var_dictionary.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
@@ -59,11 +57,11 @@
   return dictionary;
 }
 
-void DocumentLayout::Options::FromVar(const pp::Var& var) {
-  pp::VarDictionary dictionary(var);
+void DocumentLayout::Options::FromValue(const base::Value& value) {
+  DCHECK(value.is_dict());
 
   int32_t default_page_orientation =
-      dictionary.Get(kDefaultPageOrientation).AsInt();
+      value.FindKey(kDefaultPageOrientation)->GetInt();
   DCHECK_GE(default_page_orientation,
             static_cast<int32_t>(PageOrientation::kOriginal));
   DCHECK_LE(default_page_orientation,
@@ -71,7 +69,7 @@
   default_page_orientation_ =
       static_cast<PageOrientation>(default_page_orientation);
 
-  two_up_view_enabled_ = dictionary.Get(kTwoUpViewEnabled).AsBool();
+  two_up_view_enabled_ = value.FindKey(kTwoUpViewEnabled)->GetBool();
 }
 
 void DocumentLayout::Options::RotatePagesClockwise() {
diff --git a/pdf/document_layout.h b/pdf/document_layout.h
index e998c74f..fb028424 100644
--- a/pdf/document_layout.h
+++ b/pdf/document_layout.h
@@ -18,10 +18,6 @@
 class Value;
 }
 
-namespace pp {
-class Var;
-}  // namespace pp
-
 namespace chrome_pdf {
 
 // Layout of pages within a PDF document. Pages are placed as rectangles
@@ -55,8 +51,8 @@
     // Serializes layout options to a base::Value.
     base::Value ToValue() const;
 
-    // Deserializes layout options from a pp::Var.
-    void FromVar(const pp::Var& var);
+    // Deserializes layout options from a base::Value.
+    void FromValue(const base::Value& value);
 
     PageOrientation default_page_orientation() const {
       return default_page_orientation_;
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc
index e15a66b..f683127 100644
--- a/pdf/out_of_process_instance.cc
+++ b/pdf/out_of_process_instance.cc
@@ -1833,7 +1833,7 @@
   pp::Var layout_options_var = dict.Get(kJSLayoutOptions);
   if (!layout_options_var.is_undefined()) {
     DocumentLayout::Options layout_options;
-    layout_options.FromVar(layout_options_var);
+    layout_options.FromValue(ValueFromVar(layout_options_var));
     // TODO(crbug.com/1013800): Eliminate need to get document size from here.
     document_size_ =
         PPSizeFromSize(engine()->ApplyDocumentLayout(layout_options));
diff --git a/pdf/ppapi_migration/value_conversions.cc b/pdf/ppapi_migration/value_conversions.cc
index 1890d89..c0b894ea 100644
--- a/pdf/ppapi_migration/value_conversions.cc
+++ b/pdf/ppapi_migration/value_conversions.cc
@@ -6,6 +6,8 @@
 
 #include <algorithm>
 
+#include "base/containers/span.h"
+#include "base/notreached.h"
 #include "base/values.h"
 #include "ppapi/cpp/var.h"
 #include "ppapi/cpp/var_array.h"
@@ -55,4 +57,57 @@
   }
 }
 
-}  // namespace chrome_pdf
\ No newline at end of file
+base::Value ValueFromVar(const pp::Var& var) {
+  switch (var.pp_var().type) {
+    case PP_VARTYPE_UNDEFINED:
+      return base::Value();
+    case PP_VARTYPE_NULL:
+      return base::Value();
+    case PP_VARTYPE_BOOL:
+      return base::Value(var.AsBool());
+    case PP_VARTYPE_INT32:
+      return base::Value(var.AsInt());
+    case PP_VARTYPE_DOUBLE:
+      return base::Value(var.AsDouble());
+    case PP_VARTYPE_STRING:
+      return base::Value(var.AsString());
+    case PP_VARTYPE_OBJECT:
+      // There is no valid conversion from PP_VARTYPE_OBJECT to a base::Value
+      // type. This should not be called to convert this type.
+      NOTREACHED();
+      return base::Value();
+    case PP_VARTYPE_ARRAY: {
+      pp::VarArray var_array(var);
+      base::Value::ListStorage list_storage(var_array.GetLength());
+      for (uint32_t i = 0; i < var_array.GetLength(); ++i) {
+        list_storage[i] = ValueFromVar(var_array.Get(i));
+      }
+      return base::Value(std::move(list_storage));
+    }
+    case PP_VARTYPE_DICTIONARY: {
+      base::Value val_dictionary(base::Value::Type::DICTIONARY);
+      pp::VarDictionary var_dict(var);
+      pp::VarArray dict_keys = var_dict.GetKeys();
+      for (uint32_t i = 0; i < dict_keys.GetLength(); ++i) {
+        pp::Var key = dict_keys.Get(i);
+        val_dictionary.SetKey(key.AsString(), ValueFromVar(var_dict.Get(key)));
+      }
+      return val_dictionary;
+    }
+    case PP_VARTYPE_ARRAY_BUFFER: {
+      pp::VarArrayBuffer var_array_buffer(var);
+      base::Value value(
+          base::make_span(static_cast<uint8_t*>(var_array_buffer.Map()),
+                          var_array_buffer.ByteLength()));
+      var_array_buffer.Unmap();
+      return value;
+    }
+    case PP_VARTYPE_RESOURCE:
+      // There is no valid conversion from PP_VARTYPE_RESOURCE to a base::Value
+      // type. This should not be called to convert this type.
+      NOTREACHED();
+      return base::Value();
+  }
+}
+
+}  // namespace chrome_pdf
diff --git a/pdf/ppapi_migration/value_conversions.h b/pdf/ppapi_migration/value_conversions.h
index 3b93df5..edfea99 100644
--- a/pdf/ppapi_migration/value_conversions.h
+++ b/pdf/ppapi_migration/value_conversions.h
@@ -16,7 +16,8 @@
 namespace chrome_pdf {
 
 pp::Var VarFromValue(const base::Value& value);
+base::Value ValueFromVar(const pp::Var& var);
 
 }  // namespace chrome_pdf
 
-#endif  // PDF_PPAPI_MIGRATION_VALUE_CONVERSIONS_H_
\ No newline at end of file
+#endif  // PDF_PPAPI_MIGRATION_VALUE_CONVERSIONS_H_
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 8959d30..4912fd5 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -29652,7 +29652,8 @@
         "args": [
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
-          "--avd-config=../../tools/android/avd/proto/generic_android23.textpb"
+          "--avd-config=../../tools/android/avd/proto/generic_android23.textpb",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_m.unit_tests.filter"
         ],
         "merge": {
           "args": [
diff --git a/testing/buildbot/chromium.ci.json b/testing/buildbot/chromium.ci.json
index 464d7e7..0ef037cd 100644
--- a/testing/buildbot/chromium.ci.json
+++ b/testing/buildbot/chromium.ci.json
@@ -185476,7 +185476,8 @@
         "args": [
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices",
-          "--avd-config=../../tools/android/avd/proto/generic_android23.textpb"
+          "--avd-config=../../tools/android/avd/proto/generic_android23.textpb",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_m.unit_tests.filter"
         ],
         "merge": {
           "args": [
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn
index fb3518ad..1db0905 100644
--- a/testing/buildbot/filters/BUILD.gn
+++ b/testing/buildbot/filters/BUILD.gn
@@ -192,6 +192,7 @@
 
   data = [
     "//testing/buildbot/filters/android.asan.unit_tests.filter",
+    "//testing/buildbot/filters/android.emulator_m.unit_tests.filter",
     "//testing/buildbot/filters/bfcache.unit_tests.filter",
     "//testing/buildbot/filters/lacros.unit_tests.filter",
   ]
diff --git a/testing/buildbot/filters/android.emulator_m.unit_tests.filter b/testing/buildbot/filters/android.emulator_m.unit_tests.filter
new file mode 100644
index 0000000..f3770296
--- /dev/null
+++ b/testing/buildbot/filters/android.emulator_m.unit_tests.filter
@@ -0,0 +1,5 @@
+# crbug.com/1131181
+-MediaRouterAndroidTest.DetachRoute
+-MediaRouterAndroidTest.OnRouteClosed
+-MediaRouterAndroidTest.OnRouteClosedWithError
+-MediaRouterAndroidTest.OnRouteTerminated
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 0ff2730..62e6ac5 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -2671,6 +2671,11 @@
           'shards': 8,
         },
       },
+      'android-marshmallow-x86-rel': {
+        'args': [
+          '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_m.unit_tests.filter',
+        ],
+      },
       'linux-chromeos-chrome': {
         'args': [
           '--test-launcher-filter-file=../../testing/buildbot/filters/chromeos.unit_tests.filter',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 7c981d46..621abd4 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1504,9 +1504,9 @@
             ],
             "experiments": [
                 {
-                    "name": "UseMap1_20200903",
+                    "name": "UseMap2_20200922",
                     "params": {
-                        "map": "1"
+                        "map": "2"
                     },
                     "enable_features": [
                         "EmojiSuggestAddition"
@@ -1734,7 +1734,7 @@
             ]
         }
     ],
-    "ContentCapture": [
+    "ContentCaptureExperiment": [
         {
             "platforms": [
                 "android",
@@ -1743,14 +1743,9 @@
             ],
             "experiments": [
                 {
-                    "name": "ContentCaptureUseTextHolder",
-                    "params": {
-                        "task_long_delay_in_milliseconds": "5000",
-                        "task_short_delay_in_milliseconds": "500",
-                        "use_node_id": "false"
-                    },
+                    "name": "EnableExperiment",
                     "enable_features": [
-                        "ContentCapture"
+                        "ContentCaptureTriggeringForExperiment"
                     ]
                 }
             ]
diff --git a/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc b/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc
index b33fe56..147afbb 100644
--- a/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc
@@ -4,6 +4,8 @@
 
 #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
 
+#include <algorithm>
+
 #include "base/single_thread_task_runner.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/platform.h"
@@ -19,39 +21,6 @@
 namespace blink {
 namespace {
 
-Vector<scoped_refptr<DOMWrapperWorld>> CreateIsolatedWorlds(
-    v8::Isolate* isolate) {
-  Vector<scoped_refptr<DOMWrapperWorld>> worlds;
-  worlds.push_back(DOMWrapperWorld::EnsureIsolatedWorld(
-      isolate, DOMWrapperWorld::kMainWorldId + 1));
-  worlds.push_back(DOMWrapperWorld::EnsureIsolatedWorld(
-      isolate, DOMWrapperWorld::kDOMWrapperWorldEmbedderWorldIdLimit - 1));
-  EXPECT_TRUE(worlds[0]->IsIsolatedWorld());
-  EXPECT_TRUE(worlds[1]->IsIsolatedWorld());
-  return worlds;
-}
-
-Vector<scoped_refptr<DOMWrapperWorld>> CreateWorlds(v8::Isolate* isolate) {
-  Vector<scoped_refptr<DOMWrapperWorld>> worlds;
-  worlds.push_back(
-      DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker));
-  worlds.push_back(
-      DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker));
-  worlds.push_back(
-      DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker));
-  EXPECT_TRUE(worlds[0]->IsWorkerWorld());
-  EXPECT_TRUE(worlds[1]->IsWorkerWorld());
-  EXPECT_TRUE(worlds[2]->IsWorkerWorld());
-
-  // World ids should be unique.
-  HashSet<int32_t> world_ids;
-  EXPECT_TRUE(world_ids.insert(worlds[0]->GetWorldId()).is_new_entry);
-  EXPECT_TRUE(world_ids.insert(worlds[1]->GetWorldId()).is_new_entry);
-  EXPECT_TRUE(world_ids.insert(worlds[2]->GetWorldId()).is_new_entry);
-
-  return worlds;
-}
-
 void WorkerThreadFunc(
     WorkerBackingThread* thread,
     scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) {
@@ -59,23 +28,26 @@
       WorkerBackingThreadStartupData::CreateDefault());
 
   // Worlds on the main thread should not be visible from the worker thread.
-  Vector<scoped_refptr<DOMWrapperWorld>> retrieved_worlds;
-  DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds);
-  EXPECT_TRUE(retrieved_worlds.IsEmpty());
+  Vector<scoped_refptr<DOMWrapperWorld>> initial_worlds;
+  DOMWrapperWorld::AllWorldsInCurrentThread(initial_worlds);
+  EXPECT_TRUE(initial_worlds.IsEmpty());
 
   // Create worlds on the worker thread and verify them.
-  Vector<scoped_refptr<DOMWrapperWorld>> worlds =
-      CreateWorlds(thread->GetIsolate());
-  DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds);
-  EXPECT_EQ(worlds.size(), retrieved_worlds.size());
-  retrieved_worlds.clear();
+  v8::Isolate* isolate = thread->GetIsolate();
+  auto worker_world1 =
+      DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker);
+  auto worker_world2 =
+      DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker);
+  Vector<scoped_refptr<DOMWrapperWorld>> worlds;
+  DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
+  EXPECT_EQ(worlds.size(), initial_worlds.size() + 2);
+  worlds.clear();
 
   // Dispose of remaining worlds.
-  for (scoped_refptr<DOMWrapperWorld>& world : worlds) {
-    if (world->IsWorkerWorld())
-      world->Dispose();
-  }
-  worlds.clear();
+  worker_world1->Dispose();
+  worker_world2->Dispose();
+  worker_world1.reset();
+  worker_world2.reset();
 
   thread->ShutdownOnBackingThread();
   PostCrossThreadTask(*main_thread_task_runner, FROM_HERE,
@@ -83,33 +55,70 @@
 }
 
 TEST(DOMWrapperWorldTest, Basic) {
-  // Create the main world and verify it.
+  // Initial setup
   DOMWrapperWorld& main_world = DOMWrapperWorld::MainWorld();
   EXPECT_TRUE(main_world.IsMainWorld());
-  EXPECT_FALSE(DOMWrapperWorld::NonMainWorldsExistInMainThread());
-  Vector<scoped_refptr<DOMWrapperWorld>> retrieved_worlds;
-  DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds);
-  EXPECT_EQ(1u, retrieved_worlds.size());
-  EXPECT_TRUE(retrieved_worlds[0]->IsMainWorld());
-  retrieved_worlds.clear();
-
-  // Create isolated worlds and verify them.
+  Vector<scoped_refptr<DOMWrapperWorld>> initial_worlds;
+  DOMWrapperWorld::AllWorldsInCurrentThread(initial_worlds);
+  int32_t used_isolated_world_id = DOMWrapperWorld::kMainWorldId;
+  for (const auto& world : initial_worlds) {
+    if (world->IsIsolatedWorld()) {
+      used_isolated_world_id =
+          std::max(used_isolated_world_id, world->GetWorldId());
+    }
+  }
+  ASSERT_TRUE(DOMWrapperWorld::IsIsolatedWorldId(used_isolated_world_id + 1));
   V8TestingScope scope;
-  Vector<scoped_refptr<DOMWrapperWorld>> isolated_worlds =
-      CreateIsolatedWorlds(scope.GetIsolate());
-  EXPECT_TRUE(DOMWrapperWorld::NonMainWorldsExistInMainThread());
-  DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds);
-  EXPECT_EQ(isolated_worlds.size() + 1, retrieved_worlds.size());
+  v8::Isolate* isolate = scope.GetIsolate();
 
-  // Create other worlds and verify them.
-  Vector<scoped_refptr<DOMWrapperWorld>> worlds =
-      CreateWorlds(scope.GetIsolate());
+  // Isolated worlds
+  auto isolated_world1 =
+      DOMWrapperWorld::EnsureIsolatedWorld(isolate, used_isolated_world_id + 1);
+  auto isolated_world2 =
+      DOMWrapperWorld::EnsureIsolatedWorld(isolate, used_isolated_world_id + 2);
+  EXPECT_TRUE(isolated_world1->IsIsolatedWorld());
+  EXPECT_TRUE(isolated_world2->IsIsolatedWorld());
+  Vector<scoped_refptr<DOMWrapperWorld>> worlds;
   EXPECT_TRUE(DOMWrapperWorld::NonMainWorldsExistInMainThread());
-  retrieved_worlds.clear();
-  DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds);
-  EXPECT_EQ(isolated_worlds.size() + worlds.size() + 1,
-            retrieved_worlds.size());
-  retrieved_worlds.clear();
+  DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
+  EXPECT_EQ(worlds.size(), initial_worlds.size() + 2);
+  worlds.clear();
+  isolated_world1.reset();
+  isolated_world2.reset();
+  DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
+  EXPECT_EQ(worlds.size(), initial_worlds.size());
+  worlds.clear();
+
+  // Worker worlds
+  auto worker_world1 =
+      DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker);
+  auto worker_world2 =
+      DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker);
+  auto worker_world3 =
+      DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker);
+  EXPECT_TRUE(worker_world1->IsWorkerWorld());
+  EXPECT_TRUE(worker_world2->IsWorkerWorld());
+  EXPECT_TRUE(worker_world3->IsWorkerWorld());
+  HashSet<int32_t> worker_world_ids;
+  EXPECT_TRUE(
+      worker_world_ids.insert(worker_world1->GetWorldId()).is_new_entry);
+  EXPECT_TRUE(
+      worker_world_ids.insert(worker_world2->GetWorldId()).is_new_entry);
+  EXPECT_TRUE(
+      worker_world_ids.insert(worker_world3->GetWorldId()).is_new_entry);
+  EXPECT_TRUE(DOMWrapperWorld::NonMainWorldsExistInMainThread());
+  DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
+  EXPECT_EQ(worlds.size(), initial_worlds.size() + 3);
+  worlds.clear();
+  worker_world1->Dispose();
+  worker_world2->Dispose();
+  worker_world3->Dispose();
+  worker_world1.reset();
+  worker_world2.reset();
+  worker_world3.reset();
+  DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
+  EXPECT_EQ(worlds.size(), initial_worlds.size());
+  worlds.clear();
 
   // Start a worker thread and create worlds on that.
   std::unique_ptr<WorkerBackingThread> thread =
@@ -125,28 +134,9 @@
   test::EnterRunLoop();
 
   // Worlds on the worker thread should not be visible from the main thread.
-  EXPECT_TRUE(DOMWrapperWorld::NonMainWorldsExistInMainThread());
-  DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds);
-  EXPECT_EQ(isolated_worlds.size() + worlds.size() + 1,
-            retrieved_worlds.size());
-  retrieved_worlds.clear();
-
-  // Dispose of the isolated worlds.
-  isolated_worlds.clear();
-  EXPECT_TRUE(DOMWrapperWorld::NonMainWorldsExistInMainThread());
-  DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds);
-  EXPECT_EQ(worlds.size() + 1, retrieved_worlds.size());
-  retrieved_worlds.clear();
-
-  // Dispose of the other worlds.
-  for (scoped_refptr<DOMWrapperWorld>& world : worlds) {
-    if (world->IsWorkerWorld())
-      world->Dispose();
-  }
+  DOMWrapperWorld::AllWorldsInCurrentThread(worlds);
+  EXPECT_EQ(worlds.size(), initial_worlds.size());
   worlds.clear();
-  EXPECT_FALSE(DOMWrapperWorld::NonMainWorldsExistInMainThread());
-  DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds);
-  EXPECT_EQ(1u, retrieved_worlds.size());
 }
 
 }  // namespace
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni
index 4cd5338..941430e 100644
--- a/third_party/blink/renderer/bindings/generated_in_core.gni
+++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -2,6 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# Generated sources for production
+
 generated_dictionary_sources_in_core = [
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_add_event_listener_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_add_event_listener_options.h",
@@ -1207,8 +1209,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_view_element.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_task_attribution_timing.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_task_attribution_timing.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_visibility_state_entry.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_visibility_state_entry.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_test_report_body.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_test_report_body.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text.cc",
@@ -1275,6 +1275,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_video_track.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_video_track_list.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_video_track_list.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_visibility_state_entry.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_visibility_state_entry.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_visual_viewport.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_visual_viewport.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_vtt_cue.cc",
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index 613efdd1..31ffaad6 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -4,6 +4,8 @@
 
 import("//third_party/blink/renderer/config.gni")
 
+# Generated sources for production
+
 generated_dictionary_sources_in_modules = [
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_address_errors.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_address_errors.h",
@@ -790,10 +792,10 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_lifecycle_state_query.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_type.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_color_gamut.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_color_gamut.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_codec_state.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_codec_state.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_color_gamut.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_color_gamut.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_connection_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_connection_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_contact_property.cc",
@@ -816,10 +818,10 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_end_of_stream_error.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_end_of_stream_error.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_fill_light_mode.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_fill_light_mode.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_permission_mode.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_permission_mode.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_fill_light_mode.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_fill_light_mode.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_haptic_actuator_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_haptic_actuator_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_haptic_effect_type.cc",
@@ -1431,6 +1433,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_out_of_memory_error.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_pipeline_layout.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_pipeline_layout.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_query_set.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_query_set.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_queue.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_queue.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_bundle.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_core.gni b/third_party/blink/renderer/bindings/idl_in_core.gni
index b15ac38..29c16bc9 100644
--- a/third_party/blink/renderer/bindings/idl_in_core.gni
+++ b/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -2,7 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# Statically-defined (not runtime-generated) IDL files in 'core' component.
+# Statically-defined (not runtime-generated) IDL files in 'core' component
+# for production.
 #
 # CAUTION: static_idl_files_in_core is used only by a new V8 bindings generator,
 # which is under development.  You have to update core/core_idl_files.gni in
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni
index 0ea2e92..b079d8d 100644
--- a/third_party/blink/renderer/bindings/idl_in_modules.gni
+++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -4,7 +4,8 @@
 
 import("//third_party/blink/renderer/config.gni")
 
-# Statically-defined (not runtime-generated) IDL files in 'modules' component.
+# Statically-defined (not runtime-generated) IDL files in 'modules' component
+# for production.
 #
 # CAUTION: static_idl_files_in_modules is used only by a new V8 bindings
 # generator, which is under development.  You have to update
@@ -171,6 +172,8 @@
           "//third_party/blink/renderer/modules/device_orientation/device_orientation_event_init.idl",
           "//third_party/blink/renderer/modules/device_orientation/window_device_motion.idl",
           "//third_party/blink/renderer/modules/device_orientation/window_device_orientation.idl",
+          "//third_party/blink/renderer/modules/direct_sockets/navigator_socket.idl",
+          "//third_party/blink/renderer/modules/direct_sockets/socket_options.idl",
           "//third_party/blink/renderer/modules/donottrack/navigator_do_not_track.idl",
           "//third_party/blink/renderer/modules/encoding/text_decode_options.idl",
           "//third_party/blink/renderer/modules/encoding/text_decoder.idl",
@@ -381,8 +384,8 @@
           "//third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl",
           "//third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.idl",
           "//third_party/blink/renderer/modules/native_file_system/open_file_picker_options.idl",
-          "//third_party/blink/renderer/modules/native_file_system/storage_manager_native_file_system.idl",
           "//third_party/blink/renderer/modules/native_file_system/save_file_picker_options.idl",
+          "//third_party/blink/renderer/modules/native_file_system/storage_manager_native_file_system.idl",
           "//third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl",
           "//third_party/blink/renderer/modules/native_file_system/write_params.idl",
           "//third_party/blink/renderer/modules/native_io/native_io_file.idl",
@@ -418,7 +421,6 @@
           "//third_party/blink/renderer/modules/payments/address_init.idl",
           "//third_party/blink/renderer/modules/payments/android_pay_method_data.idl",
           "//third_party/blink/renderer/modules/payments/basic_card_request.idl",
-          "//third_party/blink/renderer/modules/payments/secure_payment_confirmation_request.idl",
           "//third_party/blink/renderer/modules/payments/can_make_payment_event.idl",
           "//third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl",
           "//third_party/blink/renderer/modules/payments/can_make_payment_response.idl",
@@ -456,6 +458,7 @@
           "//third_party/blink/renderer/modules/payments/payment_response.idl",
           "//third_party/blink/renderer/modules/payments/payment_shipping_option.idl",
           "//third_party/blink/renderer/modules/payments/payment_validation_errors.idl",
+          "//third_party/blink/renderer/modules/payments/secure_payment_confirmation_request.idl",
           "//third_party/blink/renderer/modules/peerconnection/rtc_answer_options.idl",
           "//third_party/blink/renderer/modules/peerconnection/rtc_certificate.idl",
           "//third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl",
@@ -579,8 +582,6 @@
           "//third_party/blink/renderer/modules/quota/storage_usage_details.idl",
           "//third_party/blink/renderer/modules/quota/window_quota.idl",
           "//third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.idl",
-          "//third_party/blink/renderer/modules/direct_sockets/navigator_socket.idl",
-          "//third_party/blink/renderer/modules/direct_sockets/socket_options.idl",
           "//third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.idl",
           "//third_party/blink/renderer/modules/remoteplayback/remote_playback.idl",
           "//third_party/blink/renderer/modules/sanitizer_api/sanitizer.idl",
@@ -885,6 +886,8 @@
           "//third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout_descriptor.idl",
           "//third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.idl",
           "//third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl",
+          "//third_party/blink/renderer/modules/webgpu/gpu_query_set_descriptor.idl",
+          "//third_party/blink/renderer/modules/webgpu/gpu_query_set.idl",
           "//third_party/blink/renderer/modules/webgpu/gpu_queue.idl",
           "//third_party/blink/renderer/modules/webgpu/gpu_rasterization_state_descriptor.idl",
           "//third_party/blink/renderer/modules/webgpu/gpu_render_bundle.idl",
diff --git a/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc b/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
index 104e677..01ed8594 100644
--- a/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
@@ -192,7 +192,7 @@
 
 void WebSharedWorkerImpl::StartWorkerContext(
     const WebURL& script_request_url,
-    mojom::ScriptType script_type,
+    mojom::blink::ScriptType script_type,
     network::mojom::CredentialsMode credentials_mode,
     const WebString& name,
     WebSecurityOrigin constructor_origin,
@@ -300,14 +300,14 @@
       GetWorkerThread()->GetTaskRunner(TaskType::kDOMManipulation);
 
   switch (script_type) {
-    case mojom::ScriptType::kClassic:
+    case mojom::blink::ScriptType::kClassic:
       GetWorkerThread()->FetchAndRunClassicScript(
           script_request_url, std::move(worker_main_script_load_params),
           outside_settings_object->CopyData(),
           nullptr /* outside_resource_timing_notifier */,
           v8_inspector::V8StackTraceId());
       break;
-    case mojom::ScriptType::kModule:
+    case mojom::blink::ScriptType::kModule:
       GetWorkerThread()->FetchAndRunModuleScript(
           script_request_url, std::move(worker_main_script_load_params),
           outside_settings_object->CopyData(),
@@ -328,7 +328,7 @@
 std::unique_ptr<WebSharedWorker> WebSharedWorker::CreateAndStart(
     const blink::SharedWorkerToken& token,
     const WebURL& script_request_url,
-    mojom::ScriptType script_type,
+    mojom::blink::ScriptType script_type,
     network::mojom::CredentialsMode credentials_mode,
     const WebString& name,
     WebSecurityOrigin constructor_origin,
diff --git a/third_party/blink/renderer/core/exported/web_shared_worker_impl.h b/third_party/blink/renderer/core/exported/web_shared_worker_impl.h
index ebe4764..22e76ca 100644
--- a/third_party/blink/renderer/core/exported/web_shared_worker_impl.h
+++ b/third_party/blink/renderer/core/exported/web_shared_worker_impl.h
@@ -98,7 +98,7 @@
 
   void StartWorkerContext(
       const WebURL&,
-      mojom::ScriptType,
+      mojom::blink::ScriptType,
       network::mojom::CredentialsMode,
       const WebString& name,
       WebSecurityOrigin constructor_origin,
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
index bb208c3..193fd171 100644
--- a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
+++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
@@ -524,7 +524,9 @@
   gfx::Rect new_compositor_viewport_pixel_rect =
       visual_properties.compositor_viewport_pixel_rect;
   if (AutoResizeMode()) {
-    new_compositor_viewport_pixel_rect = gfx::Rect(size_);
+    new_compositor_viewport_pixel_rect = gfx::Rect(gfx::ScaleToCeiledSize(
+        widget_base_->BlinkSpaceToDIPs(size_),
+        visual_properties.screen_info.device_scale_factor));
   }
 
   widget_base_->UpdateSurfaceAndScreenInfo(
diff --git a/third_party/blink/renderer/core/html/html_view_source_document.cc b/third_party/blink/renderer/core/html/html_view_source_document.cc
index 2742eed..d8cb488 100644
--- a/third_party/blink/renderer/core/html/html_view_source_document.cc
+++ b/third_party/blink/renderer/core/html/html_view_source_document.cc
@@ -45,9 +45,7 @@
 HTMLViewSourceDocument::HTMLViewSourceDocument(const DocumentInit& initializer)
     : HTMLDocument(initializer), type_(initializer.GetMimeType()) {
   SetIsViewSource(true);
-
-  // FIXME: Why do view-source pages need to load in quirks mode?
-  SetCompatibilityMode(kQuirksMode);
+  SetCompatibilityMode(kNoQuirksMode);
   LockCompatibilityMode();
 }
 
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
index 2eb850c..163fd0d 100644
--- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
+++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -287,7 +287,7 @@
     if ((Match(tag_impl_, html_names::kScriptTag) &&
          type_attribute_value_ == "module") ||
         IsLinkRelModulePreload()) {
-      request->SetScriptType(mojom::ScriptType::kModule);
+      request->SetScriptType(mojom::blink::ScriptType::kModule);
     }
 
     request->SetCrossOrigin(cross_origin_);
@@ -665,7 +665,7 @@
     if (Match(tag_impl_, html_names::kInputTag) && !input_is_image_)
       return false;
     if (Match(tag_impl_, html_names::kScriptTag)) {
-      mojom::ScriptType script_type = mojom::ScriptType::kClassic;
+      mojom::blink::ScriptType script_type = mojom::blink::ScriptType::kClassic;
       bool is_import_map = false;
       if (!ScriptLoader::IsValidScriptTypeAndLanguage(
               type_attribute_value_, language_attribute_value_,
diff --git a/third_party/blink/renderer/core/html/parser/preload_request.cc b/third_party/blink/renderer/core/html/parser/preload_request.cc
index 5caac86a..8318f626 100644
--- a/third_party/blink/renderer/core/html/parser/preload_request.cc
+++ b/third_party/blink/renderer/core/html/parser/preload_request.cc
@@ -96,7 +96,7 @@
     params.SetCrossOriginAccessControl(origin, kCrossOriginAttributeAnonymous);
   }
 
-  if (script_type_ == mojom::ScriptType::kModule) {
+  if (script_type_ == mojom::blink::ScriptType::kModule) {
     DCHECK_EQ(resource_type_, ResourceType::kScript);
     params.SetCrossOriginAccessControl(
         origin, ScriptLoader::ModuleScriptCredentialsMode(cross_origin_));
@@ -114,7 +114,7 @@
   if (request_type_ == kRequestTypeLinkRelPreload)
     params.SetLinkPreload(true);
 
-  if (script_type_ == mojom::ScriptType::kModule) {
+  if (script_type_ == mojom::blink::ScriptType::kModule) {
     DCHECK_EQ(resource_type_, ResourceType::kScript);
     params.SetDecoderOptions(TextResourceDecoderOptions::CreateUTF8Decode());
   } else if (resource_type_ == ResourceType::kScript ||
diff --git a/third_party/blink/renderer/core/html/parser/preload_request.h b/third_party/blink/renderer/core/html/parser/preload_request.h
index b33b6e3..bb277995 100644
--- a/third_party/blink/renderer/core/html/parser/preload_request.h
+++ b/third_party/blink/renderer/core/html/parser/preload_request.h
@@ -91,7 +91,7 @@
     return referrer_policy_;
   }
 
-  void SetScriptType(mojom::ScriptType script_type) {
+  void SetScriptType(mojom::blink::ScriptType script_type) {
     script_type_ = script_type;
   }
 
@@ -130,7 +130,7 @@
         resource_url_(resource_url),
         base_url_(base_url),
         resource_type_(resource_type),
-        script_type_(mojom::ScriptType::kClassic),
+        script_type_(mojom::blink::ScriptType::kClassic),
         cross_origin_(kCrossOriginAttributeNotSet),
         importance_(mojom::FetchImportanceMode::kImportanceAuto),
         defer_(FetchParameters::kNoDefer),
@@ -151,7 +151,7 @@
   const KURL base_url_;
   String charset_;
   const ResourceType resource_type_;
-  mojom::ScriptType script_type_;
+  mojom::blink::ScriptType script_type_;
   CrossOriginAttributeValue cross_origin_;
   mojom::FetchImportanceMode importance_;
   String nonce_;
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc
index 422cc271..50ecaf1 100644
--- a/third_party/blink/renderer/core/layout/layout_block.cc
+++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -132,6 +132,7 @@
 }
 
 void LayoutBlock::RemoveFromGlobalMaps() {
+  CheckIsNotDestroyed();
   if (HasPositionedObjects()) {
     std::unique_ptr<TrackedLayoutBoxListHashSet> descendants =
         GetPositionedDescendantsMap().Take(this);
@@ -157,6 +158,7 @@
 }
 
 void LayoutBlock::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   if (!DocumentBeingDestroyed() && Parent())
     Parent()->DirtyLinesFromChangedChild(this);
 
@@ -173,6 +175,7 @@
 
 void LayoutBlock::StyleWillChange(StyleDifference diff,
                                   const ComputedStyle& new_style) {
+  CheckIsNotDestroyed();
   SetIsAtomicInlineLevel(new_style.IsDisplayInlineType());
   LayoutBox::StyleWillChange(diff, new_style);
 }
@@ -198,6 +201,7 @@
 
 void LayoutBlock::StyleDidChange(StyleDifference diff,
                                  const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutBox::StyleDidChange(diff, old_style);
 
   const ComputedStyle& new_style = StyleRef();
@@ -242,6 +246,7 @@
 }
 
 void LayoutBlock::UpdateFromStyle() {
+  CheckIsNotDestroyed();
   LayoutBox::UpdateFromStyle();
 
   bool should_clip_overflow = !StyleRef().IsOverflowVisibleAlongBothAxes() &&
@@ -259,12 +264,14 @@
 }
 
 bool LayoutBlock::AllowsNonVisibleOverflow() const {
+  CheckIsNotDestroyed();
   // If overflow has been propagated to the viewport, it has no effect here.
   return GetNode() != GetDocument().ViewportDefiningElement();
 }
 
 void LayoutBlock::AddChildBeforeDescendant(LayoutObject* new_child,
                                            LayoutObject* before_descendant) {
+  CheckIsNotDestroyed();
   DCHECK_NE(before_descendant->Parent(), this);
   LayoutObject* before_descendant_container = before_descendant->Parent();
   while (before_descendant_container->Parent() != this)
@@ -315,6 +322,7 @@
 
 void LayoutBlock::AddChild(LayoutObject* new_child,
                            LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   if (before_child && before_child->Parent() != this) {
     AddChildBeforeDescendant(new_child, before_child);
     return;
@@ -353,6 +361,7 @@
 }
 
 void LayoutBlock::RemoveLeftoverAnonymousBlock(LayoutBlock* child) {
+  CheckIsNotDestroyed();
   DCHECK(child->IsAnonymousBlock());
   DCHECK(!child->ChildrenInline());
   DCHECK_EQ(child->Parent(), this);
@@ -384,12 +393,14 @@
 }
 
 void LayoutBlock::UpdateAfterLayout() {
+  CheckIsNotDestroyed();
   InvalidateStickyConstraints();
 
   LayoutBox::UpdateAfterLayout();
 }
 
 void LayoutBlock::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(!GetScrollableArea() || GetScrollableArea()->GetScrollAnchor());
 
   LayoutAnalyzer::Scope analyzer(*this);
@@ -415,6 +426,7 @@
 }
 
 bool LayoutBlock::WidthAvailableToChildrenHasChanged() {
+  CheckIsNotDestroyed();
   // TODO(robhogan): Does m_widthAvailableToChildrenChanged always get reset
   // when it needs to?
   bool width_available_to_children_has_changed =
@@ -437,17 +449,20 @@
 
 DISABLE_CFI_PERF
 bool LayoutBlock::UpdateLogicalWidthAndColumnWidth() {
+  CheckIsNotDestroyed();
   LayoutUnit old_width = LogicalWidth();
   UpdateLogicalWidth();
   return old_width != LogicalWidth() || WidthAvailableToChildrenHasChanged();
 }
 
 void LayoutBlock::UpdateBlockLayout(bool) {
+  CheckIsNotDestroyed();
   NOTREACHED();
   ClearNeedsLayout();
 }
 
 void LayoutBlock::AddVisualOverflowFromChildren() {
+  CheckIsNotDestroyed();
   // It is an error to call this function on a LayoutBlock that it itself inside
   // a display-locked subtree.
   DCHECK(!DisplayLockUtilities::LockedAncestorPreventingPrePaint(*this));
@@ -463,6 +478,7 @@
 }
 
 void LayoutBlock::AddLayoutOverflowFromChildren() {
+  CheckIsNotDestroyed();
   if (ChildLayoutBlockedByDisplayLock())
     return;
 
@@ -473,6 +489,7 @@
 }
 
 void LayoutBlock::ComputeVisualOverflow(bool) {
+  CheckIsNotDestroyed();
   DCHECK(!SelfNeedsLayout());
 
   LayoutRect previous_visual_overflow_rect = VisualOverflowRect();
@@ -490,6 +507,7 @@
 DISABLE_CFI_PERF
 void LayoutBlock::ComputeLayoutOverflow(LayoutUnit old_client_after_edge,
                                         bool) {
+  CheckIsNotDestroyed();
   ClearSelfNeedsLayoutOverflowRecalc();
   ClearLayoutOverflow();
   AddLayoutOverflowFromChildren();
@@ -529,6 +547,7 @@
 }
 
 void LayoutBlock::AddVisualOverflowFromBlockChildren() {
+  CheckIsNotDestroyed();
   for (LayoutBox* child = FirstChildBox(); child;
        child = child->NextSiblingBox()) {
     if ((!IsLayoutNGContainingBlock(this) && child->IsFloating()) ||
@@ -549,6 +568,7 @@
 }
 
 void LayoutBlock::AddLayoutOverflowFromBlockChildren() {
+  CheckIsNotDestroyed();
   for (LayoutBox* child = FirstChildBox(); child;
        child = child->NextSiblingBox()) {
     if ((!IsLayoutNGContainingBlock(this) && child->IsFloating()) ||
@@ -570,6 +590,7 @@
 }
 
 void LayoutBlock::AddLayoutOverflowFromPositionedObjects() {
+  CheckIsNotDestroyed();
   if (IsLayoutNGBlockFlow())
     return;
 
@@ -603,6 +624,7 @@
 
 void LayoutBlock::UpdateBlockChildDirtyBitsBeforeLayout(bool relayout_children,
                                                         LayoutBox& child) {
+  CheckIsNotDestroyed();
   if (child.IsOutOfFlowPositioned()) {
     // It's rather useless to mark out-of-flow children at this point. We may
     // not be their containing block (and if we are, it's just pure luck), so
@@ -633,6 +655,7 @@
 }
 
 void LayoutBlock::SimplifiedNormalFlowLayout() {
+  CheckIsNotDestroyed();
   if (ChildrenInline()) {
     SECURITY_DCHECK(IsLayoutBlockFlow());
     auto* block_flow = To<LayoutBlockFlow>(this);
@@ -650,6 +673,7 @@
 }
 
 bool LayoutBlock::SimplifiedLayout() {
+  CheckIsNotDestroyed();
   // Check if we need to do a full layout.
   if (NormalChildNeedsLayout() || SelfNeedsLayout())
     return false;
@@ -735,6 +759,7 @@
 void LayoutBlock::MarkFixedPositionObjectForLayoutIfNeeded(
     LayoutObject* child,
     SubtreeLayoutScope& layout_scope) {
+  CheckIsNotDestroyed();
   if (child->StyleRef().GetPosition() != EPosition::kFixed)
     return;
 
@@ -775,6 +800,7 @@
 
 LayoutUnit LayoutBlock::MarginIntrinsicLogicalWidthForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   // A margin has three types: fixed, percentage, and auto (variable).
   // Auto and percentage margins become 0 when computing min/max width.
   // Fixed margins can be added in as is.
@@ -817,6 +843,7 @@
 
 void LayoutBlock::LayoutPositionedObjects(bool relayout_children,
                                           PositionedLayoutBehavior info) {
+  CheckIsNotDestroyed();
   if (ChildLayoutBlockedByDisplayLock())
     return;
 
@@ -832,6 +859,7 @@
 void LayoutBlock::LayoutPositionedObject(LayoutBox* positioned_object,
                                          bool relayout_children,
                                          PositionedLayoutBehavior info) {
+  CheckIsNotDestroyed();
   positioned_object->SetShouldCheckForPaintInvalidation();
 
   SubtreeLayoutScope layout_scope(*positioned_object);
@@ -940,6 +968,7 @@
 }
 
 void LayoutBlock::MarkPositionedObjectsForLayout() {
+  CheckIsNotDestroyed();
   if (TrackedLayoutBoxListHashSet* positioned_descendants =
           PositionedObjects()) {
     for (auto* descendant : *positioned_descendants)
@@ -948,24 +977,29 @@
 }
 
 void LayoutBlock::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   BlockPainter(*this).Paint(paint_info);
 }
 
 void LayoutBlock::PaintChildren(const PaintInfo& paint_info,
                                 const PhysicalOffset&) const {
+  CheckIsNotDestroyed();
   BlockPainter(*this).PaintChildren(paint_info);
 }
 
 void LayoutBlock::PaintObject(const PaintInfo& paint_info,
                               const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   BlockPainter(*this).PaintObject(paint_info, paint_offset);
 }
 
 TrackedLayoutBoxListHashSet* LayoutBlock::PositionedObjectsInternal() const {
+  CheckIsNotDestroyed();
   return GetPositionedDescendantsMap().at(this);
 }
 
 void LayoutBlock::InsertPositionedObject(LayoutBox* o) {
+  CheckIsNotDestroyed();
   DCHECK(!IsAnonymousBlock());
   DCHECK_EQ(o->ContainingBlock(), this);
 
@@ -1011,6 +1045,7 @@
 }
 
 bool LayoutBlock::IsAnonymousNGFieldsetContentWrapper() const {
+  CheckIsNotDestroyed();
   if (!RuntimeEnabledFeatures::LayoutNGFieldsetEnabled() || !Parent())
     return false;
   return Parent()->IsLayoutNGFieldset();
@@ -1018,11 +1053,13 @@
 
 void LayoutBlock::InvalidatePaint(
     const PaintInvalidatorContext& context) const {
+  CheckIsNotDestroyed();
   BlockPaintInvalidator(*this).InvalidatePaint(context);
 }
 
 void LayoutBlock::ImageChanged(WrappedImagePtr image,
                                CanDeferInvalidation defer) {
+  CheckIsNotDestroyed();
   LayoutBox::ImageChanged(image, defer);
 
   if (!StyleRef().HasPseudoElementStyle(kPseudoIdFirstLine))
@@ -1046,6 +1083,7 @@
 void LayoutBlock::RemovePositionedObjects(
     LayoutObject* o,
     ContainingBlockState containing_block_state) {
+  CheckIsNotDestroyed();
   TrackedLayoutBoxListHashSet* positioned_descendants = PositionedObjects();
   if (!positioned_descendants)
     return;
@@ -1100,6 +1138,7 @@
 }
 
 void LayoutBlock::AddPercentHeightDescendant(LayoutBox* descendant) {
+  CheckIsNotDestroyed();
   // A replaced object is incapable of properly acting as a containing block for
   // its children. This is an issue with VIDEO elements, for instance, which
   // insert some percentage height flexbox children. It is also very easily
@@ -1141,6 +1180,7 @@
 }
 
 void LayoutBlock::RemovePercentHeightDescendant(LayoutBox* descendant) {
+  CheckIsNotDestroyed();
   if (TrackedLayoutBoxListHashSet* descendants = PercentHeightDescendants()) {
     descendants->erase(descendant);
     descendant->SetPercentHeightContainer(nullptr);
@@ -1153,11 +1193,13 @@
 
 TrackedLayoutBoxListHashSet* LayoutBlock::PercentHeightDescendantsInternal()
     const {
+  CheckIsNotDestroyed();
   return GetPercentHeightDescendantsMap().at(this);
 }
 
 void LayoutBlock::DirtyForLayoutFromPercentageHeightDescendants(
     SubtreeLayoutScope& layout_scope) {
+  CheckIsNotDestroyed();
   TrackedLayoutBoxListHashSet* descendants = PercentHeightDescendants();
   if (!descendants)
     return;
@@ -1177,6 +1219,7 @@
 }
 
 LayoutUnit LayoutBlock::TextIndentOffset() const {
+  CheckIsNotDestroyed();
   LayoutUnit cw;
   if (StyleRef().TextIndent().IsPercentOrCalc())
     cw = ContentLogicalWidth();
@@ -1187,6 +1230,7 @@
     HitTestResult& result,
     const PhysicalOffset& hit_test_location,
     const PhysicalOffset& accumulated_offset) const {
+  CheckIsNotDestroyed();
   if (!ScrollsOverflow())
     return false;
 
@@ -1198,6 +1242,7 @@
     HitTestResult& result,
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& adjusted_location) const {
+  CheckIsNotDestroyed();
   if (VisibleToHitTestRequest(result.GetHitTestRequest()) &&
       IsPointInOverflowControl(result, hit_test_location.Point(),
                                adjusted_location)) {
@@ -1214,6 +1259,7 @@
                                   const HitTestLocation& hit_test_location,
                                   const PhysicalOffset& accumulated_offset,
                                   HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   // We may use legacy code to hit-test the anonymous fieldset content wrapper
   // child. The layout object for the rendered legend will be a child of that
   // one, and has to be skipped here, since its fragment is actually laid out on
@@ -1258,6 +1304,7 @@
 }
 
 Position LayoutBlock::PositionForBox(InlineBox* box, bool start) const {
+  CheckIsNotDestroyed();
   if (!box)
     return Position();
 
@@ -1294,6 +1341,7 @@
 PositionWithAffinity LayoutBlock::PositionForPointRespectingEditingBoundaries(
     LineLayoutBox child,
     const PhysicalOffset& point_in_parent_coordinates) const {
+  CheckIsNotDestroyed();
   PhysicalOffset child_location = child.PhysicalLocation();
   if (child.IsInFlowPositioned())
     child_location += child.OffsetForInFlowPosition();
@@ -1332,6 +1380,7 @@
 
 PositionWithAffinity LayoutBlock::PositionForPointIfOutsideAtomicInlineLevel(
     const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   DCHECK(IsAtomicInlineLevel());
   LogicalOffset logical_offset =
       point.ConvertToLogical(StyleRef().GetWritingMode(), ResolvedDirection(),
@@ -1355,6 +1404,7 @@
 
 PositionWithAffinity LayoutBlock::PositionForPoint(
     const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   if (IsTable())
     return LayoutBox::PositionForPoint(point);
 
@@ -1409,6 +1459,7 @@
 }
 
 void LayoutBlock::OffsetForContents(PhysicalOffset& offset) const {
+  CheckIsNotDestroyed();
   if (IsScrollContainer())
     offset += PhysicalOffset(PixelSnappedScrolledContentOffset());
 }
@@ -1416,11 +1467,13 @@
 void LayoutBlock::ScrollbarsChanged(bool horizontal_scrollbar_changed,
                                     bool vertical_scrollbar_changed,
                                     ScrollbarChangeContext context) {
+  CheckIsNotDestroyed();
   width_available_to_children_changed_ |= vertical_scrollbar_changed;
   height_available_to_children_changed_ |= horizontal_scrollbar_changed;
 }
 
 MinMaxSizes LayoutBlock::ComputeIntrinsicLogicalWidths() const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes;
   sizes +=
       BorderAndPaddingLogicalWidth() + ComputeLogicalScrollbars().InlineSum();
@@ -1480,6 +1533,7 @@
 
 DISABLE_CFI_PERF
 MinMaxSizes LayoutBlock::PreferredLogicalWidths() const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes;
 
   // FIXME: The isFixed() calls here should probably be checking for isSpecified
@@ -1520,6 +1574,7 @@
 void LayoutBlock::ComputeBlockPreferredLogicalWidths(
     LayoutUnit& min_logical_width,
     LayoutUnit& max_logical_width) const {
+  CheckIsNotDestroyed();
   const ComputedStyle& style_to_use = StyleRef();
   bool nowrap = style_to_use.WhiteSpace() == EWhiteSpace::kNowrap;
 
@@ -1644,6 +1699,7 @@
     LayoutObject& child,
     LayoutUnit& min_preferred_logical_width,
     LayoutUnit& max_preferred_logical_width) const {
+  CheckIsNotDestroyed();
   if (child.IsBox() &&
       child.IsHorizontalWritingMode() != IsHorizontalWritingMode()) {
     // If the child is an orthogonal flow, child's height determines the width,
@@ -1677,6 +1733,7 @@
 }
 
 bool LayoutBlock::HasLineIfEmpty() const {
+  CheckIsNotDestroyed();
   if (GetNode()) {
     if (IsRootEditableElement(*GetNode()))
       return true;
@@ -1686,6 +1743,7 @@
 
 LayoutUnit LayoutBlock::EmptyLineBaseline(
     LineDirectionMode line_direction) const {
+  CheckIsNotDestroyed();
   if (!HasLineIfEmpty())
     return LayoutUnit(-1);
   const auto baseline_offset = BaselineForEmptyLine(line_direction);
@@ -1694,6 +1752,7 @@
 
 base::Optional<LayoutUnit> LayoutBlock::BaselineForEmptyLine(
     LineDirectionMode line_direction) const {
+  CheckIsNotDestroyed();
   const SimpleFontData* font_data = FirstLineStyle()->GetFont().PrimaryFont();
   if (!font_data)
     return base::nullopt;
@@ -1711,6 +1770,7 @@
 LayoutUnit LayoutBlock::LineHeight(bool first_line,
                                    LineDirectionMode direction,
                                    LinePositionMode line_position_mode) const {
+  CheckIsNotDestroyed();
   // Inline blocks are replaced elements. Otherwise, just pass off to
   // the base class.  If we're being queried as though we're the root line
   // box, then the fact that we're an inline-block is irrelevant, and we behave
@@ -1725,6 +1785,7 @@
 
 LayoutUnit LayoutBlock::BeforeMarginInLineDirection(
     LineDirectionMode direction) const {
+  CheckIsNotDestroyed();
   // InlineFlowBox::placeBoxesInBlockDirection will flip lines in
   // case of verticalLR mode, so we can assume verticalRL for now.
   return direction == kHorizontalLine ? MarginTop() : MarginRight();
@@ -1735,6 +1796,7 @@
     bool first_line,
     LineDirectionMode direction,
     LinePositionMode line_position_mode) const {
+  CheckIsNotDestroyed();
   // Inline blocks are replaced elements. Otherwise, just pass off to
   // the base class.  If we're being queried as though we're the root line
   // box, then the fact that we're an inline-block is irrelevant, and we behave
@@ -1796,6 +1858,7 @@
 LayoutUnit LayoutBlock::MinLineHeightForReplacedObject(
     bool is_first_line,
     LayoutUnit replaced_height) const {
+  CheckIsNotDestroyed();
   if (!GetDocument().InNoQuirksMode() && replaced_height)
     return replaced_height;
 
@@ -1813,6 +1876,7 @@
 // those two layout modes, though.
 
 LayoutUnit LayoutBlock::FirstLineBoxBaseline() const {
+  CheckIsNotDestroyed();
   DCHECK(!ChildrenInline());
   if (ShouldApplyLayoutContainment())
     return LayoutUnit(-1);
@@ -1833,6 +1897,7 @@
 }
 
 bool LayoutBlock::UseLogicalBottomMarginEdgeForInlineBlockBaseline() const {
+  CheckIsNotDestroyed();
   // CSS2.1 states that the baseline of an 'inline-block' is:
   // the baseline of the last line box in the normal flow, unless it has
   // either no in-flow line boxes or if its 'overflow' property has a computed
@@ -1848,6 +1913,7 @@
 
 LayoutUnit LayoutBlock::InlineBlockBaseline(
     LineDirectionMode line_direction) const {
+  CheckIsNotDestroyed();
   DCHECK(!ChildrenInline());
   if (UseLogicalBottomMarginEdgeForInlineBlockBaseline()) {
     // We are not calling LayoutBox::baselinePosition here because the caller
@@ -1877,6 +1943,7 @@
 }
 
 const LayoutBlock* LayoutBlock::EnclosingFirstLineStyleBlock() const {
+  CheckIsNotDestroyed();
   const LayoutBlock* first_line_block = this;
   bool has_pseudo = false;
   while (true) {
@@ -1902,6 +1969,7 @@
 }
 
 LayoutBlockFlow* LayoutBlock::NearestInnerBlockWithFirstLine() {
+  CheckIsNotDestroyed();
   if (ChildrenInline())
     return To<LayoutBlockFlow>(this);
   for (LayoutObject* child = FirstChild();
@@ -1917,15 +1985,18 @@
 // An inline-block uses its inlineBox as the inlineBoxWrapper,
 // so the firstChild() is nullptr if the only child is an empty inline-block.
 inline bool LayoutBlock::IsInlineBoxWrapperActuallyChild() const {
+  CheckIsNotDestroyed();
   return IsInlineBlockOrInlineTable() && !Size().IsEmpty() && GetNode() &&
          EditingIgnoresContent(*GetNode());
 }
 
 bool LayoutBlock::ShouldPaintCursorCaret() const {
+  CheckIsNotDestroyed();
   return GetFrame()->Selection().ShouldPaintCaret(*this);
 }
 
 bool LayoutBlock::ShouldPaintDragCaret() const {
+  CheckIsNotDestroyed();
   return GetFrame()->GetPage()->GetDragCaret().ShouldPaintCaret(*this);
 }
 
@@ -1933,6 +2004,7 @@
     const InlineBox* inline_box,
     int caret_offset,
     LayoutUnit* extra_width_to_end_of_line) const {
+  CheckIsNotDestroyed();
   // Do the normal calculation in most cases.
   if ((FirstChild() && !FirstChild()->IsPseudoElement()) ||
       IsInlineBoxWrapperActuallyChild())
@@ -1951,6 +2023,7 @@
 void LayoutBlock::AddOutlineRects(Vector<PhysicalRect>& rects,
                                   const PhysicalOffset& additional_offset,
                                   NGOutlineType include_block_overflows) const {
+  CheckIsNotDestroyed();
 #if DCHECK_IS_ON()
   // TODO(crbug.com/987836): enable this DCHECK universally.
   Page* page = GetDocument().GetPage();
@@ -1977,11 +2050,13 @@
 
 LayoutBox* LayoutBlock::CreateAnonymousBoxWithSameTypeAs(
     const LayoutObject* parent) const {
+  CheckIsNotDestroyed();
   return CreateAnonymousWithParentAndDisplay(parent, StyleRef().Display());
 }
 
 void LayoutBlock::PaginatedContentWasLaidOut(
     LayoutUnit logical_bottom_offset_after_pagination) {
+  CheckIsNotDestroyed();
   if (LayoutFlowThread* flow_thread = FlowThreadContainingBlock())
     flow_thread->ContentWasLaidOut(OffsetFromLogicalTopOfFirstPage() +
                                    logical_bottom_offset_after_pagination);
@@ -1989,6 +2064,7 @@
 
 LayoutUnit LayoutBlock::CollapsedMarginBeforeForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   // If the child has the same directionality as we do, then we can just return
   // its collapsed margin.
   if (!child.IsWritingModeRoot())
@@ -2008,6 +2084,7 @@
 
 LayoutUnit LayoutBlock::CollapsedMarginAfterForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   // If the child has the same directionality as we do, then we can just return
   // its collapsed margin.
   if (!child.IsWritingModeRoot())
@@ -2026,6 +2103,7 @@
 }
 
 bool LayoutBlock::HasMarginBeforeQuirk(const LayoutBox* child) const {
+  CheckIsNotDestroyed();
   // If the child has the same directionality as we do, then we can just return
   // its margin quirk.
   auto* child_layout_block = DynamicTo<LayoutBlock>(child);
@@ -2048,6 +2126,7 @@
 }
 
 bool LayoutBlock::HasMarginAfterQuirk(const LayoutBox* child) const {
+  CheckIsNotDestroyed();
   // If the child has the same directionality as we do, then we can just return
   // its margin quirk.
   auto* child_layout_block = DynamicTo<LayoutBlock>(child);
@@ -2070,6 +2149,7 @@
 }
 
 const char* LayoutBlock::GetName() const {
+  CheckIsNotDestroyed();
   NOTREACHED();
   return "LayoutBlock";
 }
@@ -2124,12 +2204,14 @@
 
 bool LayoutBlock::RecalcNormalFlowChildLayoutOverflowIfNeeded(
     LayoutObject* layout_object) {
+  CheckIsNotDestroyed();
   if (layout_object->IsOutOfFlowPositioned())
     return false;
   return layout_object->RecalcLayoutOverflow();
 }
 
 bool LayoutBlock::RecalcChildLayoutOverflow() {
+  CheckIsNotDestroyed();
   DCHECK(!IsTable());
   DCHECK(ChildNeedsLayoutOverflowRecalc());
   ClearChildNeedsLayoutOverflowRecalc();
@@ -2152,6 +2234,7 @@
 }
 
 void LayoutBlock::RecalcChildVisualOverflow() {
+  CheckIsNotDestroyed();
   DCHECK(!IsTable());
   // It is an error to call this function on a LayoutBlock that it itself inside
   // a display-locked subtree.
@@ -2172,6 +2255,7 @@
 }
 
 bool LayoutBlock::RecalcPositionedDescendantsLayoutOverflow() {
+  CheckIsNotDestroyed();
   bool children_layout_overflow_changed = false;
 
   TrackedLayoutBoxListHashSet* positioned_descendants = PositionedObjects();
@@ -2186,6 +2270,7 @@
 }
 
 void LayoutBlock::RecalcPositionedDescendantsVisualOverflow() {
+  CheckIsNotDestroyed();
   TrackedLayoutBoxListHashSet* positioned_descendants = PositionedObjects();
   if (!positioned_descendants)
     return;
@@ -2198,6 +2283,7 @@
 }
 
 bool LayoutBlock::RecalcLayoutOverflow() {
+  CheckIsNotDestroyed();
   bool children_layout_overflow_changed = false;
   if (ChildNeedsLayoutOverflowRecalc())
     children_layout_overflow_changed = RecalcChildLayoutOverflow();
@@ -2210,11 +2296,13 @@
 }
 
 void LayoutBlock::RecalcVisualOverflow() {
+  CheckIsNotDestroyed();
   RecalcChildVisualOverflow();
   RecalcSelfVisualOverflow();
 }
 
 bool LayoutBlock::RecalcSelfLayoutOverflow() {
+  CheckIsNotDestroyed();
   bool self_needs_layout_overflow_recalc = SelfNeedsLayoutOverflowRecalc();
   // If the current block needs layout, overflow will be recalculated during
   // layout time anyway. We can safely exit here.
@@ -2230,6 +2318,7 @@
 }
 
 void LayoutBlock::RecalcSelfVisualOverflow() {
+  CheckIsNotDestroyed();
   ComputeVisualOverflow(true);
 }
 
@@ -2237,6 +2326,7 @@
 // A simplified layout is attempted that just updates the object's position.
 // If the size does change, the object remains dirty.
 bool LayoutBlock::TryLayoutDoingPositionedMovementOnly() {
+  CheckIsNotDestroyed();
   LayoutUnit old_width = LogicalWidth();
   LogicalExtentComputedValues computed_values;
   LogicalExtentAfterUpdatingLogicalWidth(LogicalTop(), computed_values);
@@ -2272,6 +2362,7 @@
 
 #if DCHECK_IS_ON()
 void LayoutBlock::CheckPositionedObjectsNeedLayout() {
+  CheckIsNotDestroyed();
   if (ChildLayoutBlockedByDisplayLock())
     return;
 
@@ -2293,6 +2384,7 @@
 #endif
 
 LayoutUnit LayoutBlock::AvailableLogicalHeightForPercentageComputation() const {
+  CheckIsNotDestroyed();
   LayoutUnit available_height(-1);
 
   // For anonymous blocks that are skipped during percentage height calculation,
@@ -2371,10 +2463,12 @@
 }
 
 bool LayoutBlock::HasDefiniteLogicalHeight() const {
+  CheckIsNotDestroyed();
   return AvailableLogicalHeightForPercentageComputation() != LayoutUnit(-1);
 }
 
 bool LayoutBlock::NeedsPreferredWidthsRecalculation() const {
+  CheckIsNotDestroyed();
   return (HasRelativeLogicalHeight() && StyleRef().LogicalWidth().IsAuto()) ||
          LayoutBox::NeedsPreferredWidthsRecalculation();
 }
diff --git a/third_party/blink/renderer/core/layout/layout_block.h b/third_party/blink/renderer/core/layout/layout_block.h
index 02f7c69..1201e930 100644
--- a/third_party/blink/renderer/core/layout/layout_block.h
+++ b/third_party/blink/renderer/core/layout/layout_block.h
@@ -110,10 +110,12 @@
 
  public:
   LayoutObject* FirstChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->FirstChild();
   }
   LayoutObject* LastChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->LastChild();
   }
@@ -122,8 +124,14 @@
   void SlowFirstChild() const = delete;
   void SlowLastChild() const = delete;
 
-  const LayoutObjectChildList* Children() const { return &children_; }
-  LayoutObjectChildList* Children() { return &children_; }
+  const LayoutObjectChildList* Children() const {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
+  LayoutObjectChildList* Children() {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
 
   // These two functions are overridden for inline-block.
   LayoutUnit LineHeight(
@@ -143,6 +151,7 @@
   const char* GetName() const override;
 
   virtual const NGPhysicalBoxFragment* CurrentFragment() const {
+    CheckIsNotDestroyed();
     return nullptr;
   }
 
@@ -167,10 +176,12 @@
                                ContainingBlockState = kSameContainingBlock);
 
   TrackedLayoutBoxListHashSet* PositionedObjects() const {
+    CheckIsNotDestroyed();
     return UNLIKELY(HasPositionedObjects()) ? PositionedObjectsInternal()
                                             : nullptr;
   }
   bool HasPositionedObjects() const {
+    CheckIsNotDestroyed();
     DCHECK(has_positioned_objects_ ? (PositionedObjectsInternal() &&
                                       !PositionedObjectsInternal()->IsEmpty())
                                    : !PositionedObjectsInternal());
@@ -180,15 +191,18 @@
   void AddPercentHeightDescendant(LayoutBox*);
   void RemovePercentHeightDescendant(LayoutBox*);
   bool HasPercentHeightDescendant(LayoutBox* o) const {
+    CheckIsNotDestroyed();
     return HasPercentHeightDescendants() &&
            PercentHeightDescendantsInternal()->Contains(o);
   }
 
   TrackedLayoutBoxListHashSet* PercentHeightDescendants() const {
+    CheckIsNotDestroyed();
     return HasPercentHeightDescendants() ? PercentHeightDescendantsInternal()
                                          : nullptr;
   }
   bool HasPercentHeightDescendants() const {
+    CheckIsNotDestroyed();
     DCHECK(has_percent_height_descendants_
                ? (PercentHeightDescendantsInternal() &&
                   !PercentHeightDescendantsInternal()->IsEmpty())
@@ -197,6 +211,7 @@
   }
 
   void NotifyScrollbarThicknessChanged() {
+    CheckIsNotDestroyed();
     width_available_to_children_changed_ = true;
   }
 
@@ -206,14 +221,32 @@
   // itself for the legend is still a child of this object.
   bool IsAnonymousNGFieldsetContentWrapper() const;
 
-  void SetHasMarkupTruncation(bool b) { has_markup_truncation_ = b; }
-  bool HasMarkupTruncation() const { return has_markup_truncation_; }
+  void SetHasMarkupTruncation(bool b) {
+    CheckIsNotDestroyed();
+    has_markup_truncation_ = b;
+  }
+  bool HasMarkupTruncation() const {
+    CheckIsNotDestroyed();
+    return has_markup_truncation_;
+  }
 
-  void SetHasMarginBeforeQuirk(bool b) { has_margin_before_quirk_ = b; }
-  void SetHasMarginAfterQuirk(bool b) { has_margin_after_quirk_ = b; }
+  void SetHasMarginBeforeQuirk(bool b) {
+    CheckIsNotDestroyed();
+    has_margin_before_quirk_ = b;
+  }
+  void SetHasMarginAfterQuirk(bool b) {
+    CheckIsNotDestroyed();
+    has_margin_after_quirk_ = b;
+  }
 
-  bool HasMarginBeforeQuirk() const { return has_margin_before_quirk_; }
-  bool HasMarginAfterQuirk() const { return has_margin_after_quirk_; }
+  bool HasMarginBeforeQuirk() const {
+    CheckIsNotDestroyed();
+    return has_margin_before_quirk_;
+  }
+  bool HasMarginAfterQuirk() const {
+    CheckIsNotDestroyed();
+    return has_margin_after_quirk_;
+  }
 
   bool HasMarginBeforeQuirk(const LayoutBox* child) const;
   bool HasMarginAfterQuirk(const LayoutBox* child) const;
@@ -228,6 +261,7 @@
       const LayoutObject*,
       EDisplay = EDisplay::kBlock);
   LayoutBlock* CreateAnonymousBlock(EDisplay display = EDisplay::kBlock) const {
+    CheckIsNotDestroyed();
     return CreateAnonymousWithParentAndDisplay(this, display);
   }
 
@@ -237,48 +271,61 @@
   // Accessors for logical width/height and margins in the containing block's
   // block-flow direction.
   LayoutUnit LogicalWidthForChild(const LayoutBox& child) const {
+    CheckIsNotDestroyed();
     return LogicalWidthForChildSize(child.Size());
   }
   LayoutUnit LogicalWidthForChildSize(LayoutSize child_size) const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? child_size.Width() : child_size.Height();
   }
   LayoutUnit LogicalHeightForChild(const LayoutBox& child) const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? child.Size().Height()
                                      : child.Size().Width();
   }
   LayoutSize LogicalSizeForChild(const LayoutBox& child) const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? child.Size()
                                      : child.Size().TransposedSize();
   }
   LayoutUnit LogicalTopForChild(const LayoutBox& child) const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? child.Location().Y()
                                      : child.Location().X();
   }
   DISABLE_CFI_PERF LayoutUnit
   MarginBeforeForChild(const LayoutBoxModelObject& child) const {
+    CheckIsNotDestroyed();
     return child.MarginBefore(Style());
   }
   DISABLE_CFI_PERF LayoutUnit
   MarginAfterForChild(const LayoutBoxModelObject& child) const {
+    CheckIsNotDestroyed();
     return child.MarginAfter(Style());
   }
   DISABLE_CFI_PERF LayoutUnit
   MarginStartForChild(const LayoutBoxModelObject& child) const {
+    CheckIsNotDestroyed();
     return child.MarginStart(Style());
   }
   LayoutUnit MarginEndForChild(const LayoutBoxModelObject& child) const {
+    CheckIsNotDestroyed();
     return child.MarginEnd(Style());
   }
   void SetMarginStartForChild(LayoutBox& child, LayoutUnit value) const {
+    CheckIsNotDestroyed();
     child.SetMarginStart(value, Style());
   }
   void SetMarginEndForChild(LayoutBox& child, LayoutUnit value) const {
+    CheckIsNotDestroyed();
     child.SetMarginEnd(value, Style());
   }
   void SetMarginBeforeForChild(LayoutBox& child, LayoutUnit value) const {
+    CheckIsNotDestroyed();
     child.SetMarginBefore(value, Style());
   }
   void SetMarginAfterForChild(LayoutBox& child, LayoutUnit value) const {
+    CheckIsNotDestroyed();
     child.SetMarginAfter(value, Style());
   }
   LayoutUnit CollapsedMarginBeforeForChild(const LayoutBox& child) const;
@@ -290,21 +337,26 @@
                                  ScrollbarChangeContext = kLayout);
 
   LayoutUnit AvailableLogicalWidthForContent() const {
+    CheckIsNotDestroyed();
     return (LogicalRightOffsetForContent() - LogicalLeftOffsetForContent())
         .ClampNegativeToZero();
   }
   DISABLE_CFI_PERF LayoutUnit LogicalLeftOffsetForContent() const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? ContentLeft() : ContentTop();
   }
   LayoutUnit LogicalRightOffsetForContent() const {
+    CheckIsNotDestroyed();
     return LogicalLeftOffsetForContent() + AvailableLogicalWidth();
   }
   LayoutUnit StartOffsetForContent() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsLeftToRightDirection()
                ? LogicalLeftOffsetForContent()
                : LogicalWidth() - LogicalRightOffsetForContent();
   }
   LayoutUnit EndOffsetForContent() const {
+    CheckIsNotDestroyed();
     return !StyleRef().IsLeftToRightDirection()
                ? LogicalLeftOffsetForContent()
                : LogicalWidth() - LogicalRightOffsetForContent();
@@ -380,10 +432,12 @@
 
  public:
   bool IsLegacyInitiatedOutOfFlowLayout() const {
+    CheckIsNotDestroyed();
     return is_legacy_initiated_out_of_flow_layout_;
   }
 
   void SetIsLegacyInitiatedOutOfFlowLayout(bool b) {
+    CheckIsNotDestroyed();
     is_legacy_initiated_out_of_flow_layout_ = b;
   }
 
@@ -411,7 +465,9 @@
   virtual void AdjustInlineDirectionLineBounds(
       unsigned /* expansionOpportunityCount */,
       LayoutUnit& /* logicalLeft */,
-      LayoutUnit& /* logicalWidth */) const {}
+      LayoutUnit& /* logicalWidth */) const {
+    CheckIsNotDestroyed();
+  }
 
   MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
   void ComputeChildPreferredLogicalWidths(
@@ -470,12 +526,14 @@
   // Alternatively it should be removed as we clarify the meaning of
   // isAtomicInlineLevel to imply isInline.
   bool IsInlineBlockOrInlineTable() const final {
+    CheckIsNotDestroyed();
     return IsInline() && IsAtomicInlineLevel();
   }
 
   bool NeedsPreferredWidthsRecalculation() const override;
 
   bool IsInSelfHitTestingPhase(HitTestAction hit_test_action) const final {
+    CheckIsNotDestroyed();
     return hit_test_action == kHitTestBlockBackground ||
            hit_test_action == kHitTestChildBlockBackground;
   }
@@ -486,12 +544,19 @@
   LayoutUnit EmptyLineBaseline(LineDirectionMode line_direction) const;
 
  private:
-  LayoutObjectChildList* VirtualChildren() final { return Children(); }
+  LayoutObjectChildList* VirtualChildren() final {
+    CheckIsNotDestroyed();
+    return Children();
+  }
   const LayoutObjectChildList* VirtualChildren() const final {
+    CheckIsNotDestroyed();
     return Children();
   }
 
-  bool IsLayoutBlock() const final { return true; }
+  bool IsLayoutBlock() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   virtual void RemoveLeftoverAnonymousBlock(LayoutBlock* child);
 
@@ -512,6 +577,7 @@
   bool ShouldPaintCursorCaret() const;
   bool ShouldPaintDragCaret() const;
   bool ShouldPaintCarets() const {
+    CheckIsNotDestroyed();
     return ShouldPaintCursorCaret() || ShouldPaintDragCaret();
   }
 
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 30c1e9de..3109c6f7 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow.cc
+++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -296,6 +296,7 @@
 LayoutObject* LayoutBlockFlow::LayoutSpecialExcludedChild(
     bool relayout_children,
     SubtreeLayoutScope& layout_scope) {
+  CheckIsNotDestroyed();
   LayoutMultiColumnFlowThread* flow_thread = MultiColumnFlowThread();
   if (!flow_thread)
     return nullptr;
@@ -306,6 +307,7 @@
 }
 
 bool LayoutBlockFlow::UpdateLogicalWidthAndColumnWidth() {
+  CheckIsNotDestroyed();
   bool relayout_children = LayoutBlock::UpdateLogicalWidthAndColumnWidth();
   if (LayoutMultiColumnFlowThread* flow_thread = MultiColumnFlowThread()) {
     if (flow_thread->NeedsNewWidth())
@@ -315,6 +317,7 @@
 }
 
 void LayoutBlockFlow::SetBreakAtLineToAvoidWidow(int line_to_break) {
+  CheckIsNotDestroyed();
   DCHECK_GE(line_to_break, 0);
   EnsureRareData();
   DCHECK(!rare_data_->did_break_at_line_to_avoid_widow_);
@@ -322,6 +325,7 @@
 }
 
 void LayoutBlockFlow::SetDidBreakAtLineToAvoidWidow() {
+  CheckIsNotDestroyed();
   DCHECK(!ShouldBreakAtLineToAvoidWidow());
 
   // This function should be called only after a break was applied to avoid
@@ -332,6 +336,7 @@
 }
 
 void LayoutBlockFlow::ClearDidBreakAtLineToAvoidWidow() {
+  CheckIsNotDestroyed();
   if (!rare_data_)
     return;
 
@@ -339,6 +344,7 @@
 }
 
 void LayoutBlockFlow::ClearShouldBreakAtLineToAvoidWidow() const {
+  CheckIsNotDestroyed();
   DCHECK(ShouldBreakAtLineToAvoidWidow());
   if (!rare_data_)
     return;
@@ -347,6 +353,7 @@
 }
 
 bool LayoutBlockFlow::IsSelfCollapsingBlock() const {
+  CheckIsNotDestroyed();
   if (NeedsLayout()) {
     // Sometimes we don't lay out objects in DOM order (column spanners being
     // one such relevant type of object right here). As long as the object in
@@ -361,6 +368,7 @@
 }
 
 bool LayoutBlockFlow::CheckIfIsSelfCollapsingBlock() const {
+  CheckIsNotDestroyed();
   // We are not self-collapsing if we
   // (a) have a non-zero height according to layout (an optimization to avoid
   //     wasting time)
@@ -440,6 +448,7 @@
 
 DISABLE_CFI_PERF
 void LayoutBlockFlow::UpdateBlockLayout(bool relayout_children) {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   DCHECK(IsInlineBlockOrInlineTable() || !IsInline());
 
@@ -542,6 +551,7 @@
 
 DISABLE_CFI_PERF
 void LayoutBlockFlow::ResetLayout() {
+  CheckIsNotDestroyed();
   if (!FirstChild() && !IsAnonymousBlock())
     SetChildrenInline(true);
   SetContainsInlineWithOutlineAndContinuation(false);
@@ -599,6 +609,7 @@
 DISABLE_CFI_PERF
 void LayoutBlockFlow::LayoutChildren(bool relayout_children,
                                      SubtreeLayoutScope& layout_scope) {
+  CheckIsNotDestroyed();
   ResetLayout();
 
   if (ChildLayoutBlockedByDisplayLock())
@@ -629,6 +640,7 @@
 
 void LayoutBlockFlow::AddOverhangingFloatsFromChildren(
     LayoutUnit unconstrained_height) {
+  CheckIsNotDestroyed();
   LayoutBlockFlow* lowest_block = nullptr;
   bool added_overhanging_floats = false;
   // One of our children's floats may have become an overhanging float for us.
@@ -660,6 +672,7 @@
 }
 
 void LayoutBlockFlow::AddLowestFloatFromChildren(LayoutBlockFlow* block) {
+  CheckIsNotDestroyed();
   // TODO(robhogan): Make createsNewFormattingContext an ASSERT.
   if (!block || !block->ContainsFloats() ||
       block->CreatesNewFormattingContext())
@@ -683,6 +696,7 @@
 
 DISABLE_CFI_PERF
 void LayoutBlockFlow::DetermineLogicalLeftPositionForChild(LayoutBox& child) {
+  CheckIsNotDestroyed();
   LayoutUnit start_position = BorderStart() + PaddingStart();
   LayoutUnit initial_start_position = start_position;
   start_position -= LogicalLeftScrollbarWidth();
@@ -718,6 +732,7 @@
 
 void LayoutBlockFlow::SetLogicalLeftForChild(LayoutBox& child,
                                              LayoutUnit logical_left) {
+  CheckIsNotDestroyed();
   LayoutPoint new_location(child.Location());
   if (IsHorizontalWritingMode()) {
     new_location.SetX(logical_left);
@@ -729,6 +744,7 @@
 
 void LayoutBlockFlow::SetLogicalTopForChild(LayoutBox& child,
                                             LayoutUnit logical_top) {
+  CheckIsNotDestroyed();
   if (IsHorizontalWritingMode()) {
     child.SetY(logical_top);
   } else {
@@ -740,6 +756,7 @@
     LayoutBlockFlow& child,
     LayoutUnit new_logical_top,
     LayoutUnit previous_float_logical_bottom) {
+  CheckIsNotDestroyed();
   // TODO(mstensho): rework the code to return early when there is no need for
   // marking, instead of this |markDescendantsWithFloats| flag.
   bool mark_descendants_with_floats = false;
@@ -770,6 +787,7 @@
     LayoutBox& child,
     LayoutUnit new_logical_top,
     BlockChildrenLayoutInfo& layout_info) {
+  CheckIsNotDestroyed();
   if (LayoutFlowThread* flow_thread = FlowThreadContainingBlock())
     layout_info.RollBackToInitialMultiColumnLayoutState(*flow_thread);
 
@@ -834,6 +852,7 @@
 void LayoutBlockFlow::InsertForcedBreakBeforeChildIfNeeded(
     LayoutBox& child,
     BlockChildrenLayoutInfo& layout_info) {
+  CheckIsNotDestroyed();
   LayoutState* layout_state = View()->GetLayoutState();
 
   // If the child has a start/end page name, that's the current name. Otherwise
@@ -912,6 +931,7 @@
 
 void LayoutBlockFlow::LayoutBlockChild(LayoutBox& child,
                                        BlockChildrenLayoutInfo& layout_info) {
+  CheckIsNotDestroyed();
   MarginInfo& margin_info = layout_info.GetMarginInfo();
   auto* child_layout_block_flow = DynamicTo<LayoutBlockFlow>(&child);
   LayoutUnit old_pos_margin_before = MaxPositiveMarginBefore();
@@ -1067,6 +1087,7 @@
     LayoutBox& child,
     BlockChildrenLayoutInfo& layout_info,
     bool at_before_side_of_block) {
+  CheckIsNotDestroyed();
   auto* child_block_flow = DynamicTo<LayoutBlockFlow>(&child);
 
   // See if we need a soft (unforced) break in front of this child, and set the
@@ -1153,6 +1174,7 @@
 LayoutUnit LayoutBlockFlow::AdjustFloatLogicalTopForPagination(
     LayoutBox& child,
     LayoutUnit logical_top_margin_edge) {
+  CheckIsNotDestroyed();
   // The first piece of content inside the child may have set a strut during
   // layout.
   LayoutUnit strut;
@@ -1238,6 +1260,7 @@
 
 void LayoutBlockFlow::AdjustLinePositionForPagination(RootInlineBox& line_box,
                                                       LayoutUnit& delta) {
+  CheckIsNotDestroyed();
   // TODO(mstensho): Pay attention to line overflow. It should be painted in the
   // same column as the rest of the line, possibly overflowing the column. We
   // currently only allow overflow above the first column. We clip at all other
@@ -1359,6 +1382,7 @@
 LayoutUnit LayoutBlockFlow::AdjustForUnsplittableChild(
     LayoutBox& child,
     LayoutUnit logical_offset) const {
+  CheckIsNotDestroyed();
   if (child.GetLegacyPaginationBreakability() == kAllowAnyBreaks)
     return logical_offset;
   LayoutUnit child_logical_height = LogicalHeightForChild(child);
@@ -1397,6 +1421,7 @@
 
 DISABLE_CFI_PERF
 void LayoutBlockFlow::RebuildFloatsFromIntruding() {
+  CheckIsNotDestroyed();
   if (floating_objects_)
     floating_objects_->SetHorizontalWritingMode(IsHorizontalWritingMode());
 
@@ -1576,6 +1601,7 @@
                                           SubtreeLayoutScope& layout_scope,
                                           LayoutUnit before_edge,
                                           LayoutUnit after_edge) {
+  CheckIsNotDestroyed();
   DirtyForLayoutFromPercentageHeightDescendants(layout_scope);
 
   BlockChildrenLayoutInfo layout_info(this, before_edge, after_edge);
@@ -1691,6 +1717,7 @@
 
 LayoutBlockFlow::MarginValues LayoutBlockFlow::MarginValuesForChild(
     LayoutBox& child) const {
+  CheckIsNotDestroyed();
   LayoutUnit child_before_positive;
   LayoutUnit child_before_negative;
   LayoutUnit child_after_positive;
@@ -1760,6 +1787,7 @@
     LayoutUnit logical_top_margin_edge,
     LayoutUnit logical_top_border_edge,
     const BlockChildrenLayoutInfo& layout_info) const {
+  CheckIsNotDestroyed();
   LayoutUnit effective_margin =
       logical_top_border_edge - logical_top_margin_edge;
   DCHECK(IsPageLogicalHeightKnown());
@@ -1798,6 +1826,7 @@
     LayoutBox& child,
     BlockChildrenLayoutInfo& layout_info,
     bool child_is_self_collapsing) {
+  CheckIsNotDestroyed();
   MarginInfo& margin_info = layout_info.GetMarginInfo();
 
   // Get the four margin values for the child and cache them.
@@ -1969,6 +1998,7 @@
 void LayoutBlockFlow::AdjustPositionedBlock(
     LayoutBox& child,
     const BlockChildrenLayoutInfo& layout_info) {
+  CheckIsNotDestroyed();
   LayoutUnit logical_top = LogicalHeight();
 
   // Forced breaks are only specified on in-flow objects, but auto-positioned
@@ -2001,6 +2031,7 @@
                                                 LayoutUnit old_top_neg_margin,
                                                 LayoutUnit y_pos,
                                                 bool child_is_self_collapsing) {
+  CheckIsNotDestroyed();
   LayoutUnit height_increase = GetClearDelta(&child, y_pos);
   margin_info.SetLastChildIsSelfCollapsingBlockWithClearance(false);
 
@@ -2062,6 +2093,7 @@
 }
 
 void LayoutBlockFlow::SetCollapsedBottomMargin(const MarginInfo& margin_info) {
+  CheckIsNotDestroyed();
   if (margin_info.CanCollapseWithMarginAfter() &&
       !margin_info.CanCollapseWithMarginBefore()) {
     // Update our max pos/neg bottom margins, since we collapsed our bottom
@@ -2087,6 +2119,7 @@
     LayoutBox& child,
     LayoutUnit& positive_margin_before,
     LayoutUnit& negative_margin_before) const {
+  CheckIsNotDestroyed();
   // Give up if in quirks mode and we're a body/table cell and the top margin of
   // the child box is quirky.
   // FIXME: Use writing mode independent accessor for marginBeforeCollapse.
@@ -2156,6 +2189,7 @@
     LayoutBox& child,
     const BlockChildrenLayoutInfo& layout_info,
     LayoutUnit& estimate_without_pagination) {
+  CheckIsNotDestroyed();
   const MarginInfo& margin_info = layout_info.GetMarginInfo();
   // FIXME: We need to eliminate the estimation of vertical position, because
   // when it's wrong we sometimes trigger a pathological
@@ -2225,6 +2259,7 @@
 }
 
 void LayoutBlockFlow::AdjustFloatingBlock(const MarginInfo& margin_info) {
+  CheckIsNotDestroyed();
   // The float should be positioned taking into account the bottom margin
   // of the previous flow. We add that margin into the height, get the
   // float positioned properly, and then subtract the margin out of the
@@ -2248,6 +2283,7 @@
                                              LayoutUnit before_side,
                                              LayoutUnit after_side,
                                              MarginInfo& margin_info) {
+  CheckIsNotDestroyed();
   margin_info.SetAtAfterSideOfBlock(true);
 
   // If our last child was a self-collapsing block with clearance then our
@@ -2299,6 +2335,7 @@
 }
 
 void LayoutBlockFlow::SetMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg) {
+  CheckIsNotDestroyed();
   if (!rare_data_) {
     if (pos == LayoutBlockFlowRareData::PositiveMarginBeforeDefault(this) &&
         neg == LayoutBlockFlowRareData::NegativeMarginBeforeDefault(this))
@@ -2310,6 +2347,7 @@
 }
 
 void LayoutBlockFlow::SetMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg) {
+  CheckIsNotDestroyed();
   if (!rare_data_) {
     if (pos == LayoutBlockFlowRareData::PositiveMarginAfterDefault(this) &&
         neg == LayoutBlockFlowRareData::NegativeMarginAfterDefault(this))
@@ -2322,6 +2360,7 @@
 
 LayoutUnit LayoutBlockFlow::ApplyForcedBreak(LayoutUnit logical_offset,
                                              EBreakBetween break_value) {
+  CheckIsNotDestroyed();
   if (!IsForcedFragmentainerBreakValue(break_value))
     return logical_offset;
   // TODO(mstensho): honor breakValue. There are different types of forced
@@ -2351,6 +2390,7 @@
 }
 
 void LayoutBlockFlow::SetBreakBefore(EBreakBetween break_value) {
+  CheckIsNotDestroyed();
   if (break_value != EBreakBetween::kAuto &&
       !IsBreakBetweenControllable(break_value))
     break_value = EBreakBetween::kAuto;
@@ -2360,6 +2400,7 @@
 }
 
 void LayoutBlockFlow::SetBreakAfter(EBreakBetween break_value) {
+  CheckIsNotDestroyed();
   if (break_value != EBreakBetween::kAuto &&
       !IsBreakBetweenControllable(break_value))
     break_value = EBreakBetween::kAuto;
@@ -2369,16 +2410,19 @@
 }
 
 EBreakBetween LayoutBlockFlow::BreakBefore() const {
+  CheckIsNotDestroyed();
   return rare_data_ ? static_cast<EBreakBetween>(rare_data_->break_before_)
                     : EBreakBetween::kAuto;
 }
 
 EBreakBetween LayoutBlockFlow::BreakAfter() const {
+  CheckIsNotDestroyed();
   return rare_data_ ? static_cast<EBreakBetween>(rare_data_->break_after_)
                     : EBreakBetween::kAuto;
 }
 
 void LayoutBlockFlow::AddVisualOverflowFromFloats() {
+  CheckIsNotDestroyed();
   if (ChildPrePaintBlockedByDisplayLock() || !floating_objects_)
     return;
 
@@ -2396,6 +2440,7 @@
 
 void LayoutBlockFlow::AddVisualOverflowFromFloats(
     const NGPhysicalContainerFragment& fragment) {
+  CheckIsNotDestroyed();
   DCHECK(!NeedsLayout());
   DCHECK(!ChildPrePaintBlockedByDisplayLock());
   DCHECK(fragment.HasFloatingDescendantsForPaint());
@@ -2419,6 +2464,7 @@
 }
 
 void LayoutBlockFlow::AddLayoutOverflowFromFloats() {
+  CheckIsNotDestroyed();
   if (ChildLayoutBlockedByDisplayLock() || !floating_objects_)
     return;
 
@@ -2434,16 +2480,19 @@
 
 void LayoutBlockFlow::SetPaintFragment(
     const NGBlockBreakToken*,
-    scoped_refptr<const NGPhysicalFragment>) {}
+    scoped_refptr<const NGPhysicalFragment>) {
+  CheckIsNotDestroyed();
+}
 
 const NGFragmentItems* LayoutBlockFlow::FragmentItems() const {
+  CheckIsNotDestroyed();
   if (const NGPhysicalBoxFragment* box_fragment = CurrentFragment())
     return box_fragment->Items();
   return nullptr;
 }
 
-void LayoutBlockFlow::ComputeVisualOverflow(
-    bool recompute_floats) {
+void LayoutBlockFlow::ComputeVisualOverflow(bool recompute_floats) {
+  CheckIsNotDestroyed();
   DCHECK(!SelfNeedsLayout());
 
   LayoutRect previous_visual_overflow_rect = VisualOverflowRect();
@@ -2465,6 +2514,7 @@
 
 void LayoutBlockFlow::ComputeLayoutOverflow(LayoutUnit old_client_after_edge,
                                             bool recompute_floats) {
+  CheckIsNotDestroyed();
   LayoutBlock::ComputeLayoutOverflow(old_client_after_edge, recompute_floats);
   // TODO(chrishtr): why does it check for a self-painting layer? That should
   // only apply to visual overflow.
@@ -2476,6 +2526,7 @@
 
 void LayoutBlockFlow::AbsoluteQuads(Vector<FloatQuad>& quads,
                                     MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   if (!IsAnonymousBlockContinuation()) {
     LayoutBlock::AbsoluteQuads(quads, mode);
     return;
@@ -2485,6 +2536,7 @@
 
 void LayoutBlockFlow::AbsoluteQuadsForSelf(Vector<FloatQuad>& quads,
                                            MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   // For blocks inside inlines, we go ahead and include margins so that we run
   // right up to the inline boxes above and below us (thus getting merged with
   // them to form a single irregular shape).
@@ -2496,11 +2548,13 @@
 }
 
 LayoutObject* LayoutBlockFlow::HoverAncestor() const {
+  CheckIsNotDestroyed();
   return IsAnonymousBlockContinuation() ? Continuation()
                                         : LayoutBlock::HoverAncestor();
 }
 
 RootInlineBox* LayoutBlockFlow::CreateAndAppendRootInlineBox() {
+  CheckIsNotDestroyed();
   RootInlineBox* root_box = CreateRootInlineBox();
   line_boxes_.AppendLineBox(root_box);
 
@@ -2510,6 +2564,7 @@
 // Note: When this function is called from |LayoutInline::SplitFlow()|, some
 // fragments point to destroyed |LayoutObject|.
 void LayoutBlockFlow::DeleteLineBoxTree() {
+  CheckIsNotDestroyed();
   if (ContainsFloats())
     floating_objects_->ClearLineBoxTreePointers();
 
@@ -2524,6 +2579,7 @@
 
 int LayoutBlockFlow::LineCount(
     const RootInlineBox* stop_root_inline_box) const {
+  CheckIsNotDestroyed();
 #if DCHECK_IS_ON()
   DCHECK(!stop_root_inline_box ||
          stop_root_inline_box->Block().DebugPointer() == this);
@@ -2542,6 +2598,7 @@
 }
 
 LayoutUnit LayoutBlockFlow::FirstLineBoxBaseline() const {
+  CheckIsNotDestroyed();
   if (ShouldApplyLayoutContainment())
     return LayoutUnit(-1);
   // Orthogonal grid items can participante in baseline alignment along column
@@ -2583,6 +2640,7 @@
 
 LayoutUnit LayoutBlockFlow::InlineBlockBaseline(
     LineDirectionMode line_direction) const {
+  CheckIsNotDestroyed();
   if (UseLogicalBottomMarginEdgeForInlineBlockBaseline()) {
     // We are not calling baselinePosition here because the caller should add
     // the margin-top/margin-right, not us.
@@ -2612,6 +2670,7 @@
 }
 
 void LayoutBlockFlow::RemoveFloatingObjectsFromDescendants() {
+  CheckIsNotDestroyed();
   if (!ContainsFloats())
     return;
   RemoveFloatingObjects();
@@ -2649,6 +2708,7 @@
 void LayoutBlockFlow::MarkAllDescendantsWithFloatsForLayout(
     LayoutBox* float_to_remove,
     bool in_layout) {
+  CheckIsNotDestroyed();
   if (!EverHadLayout() && !ContainsFloats())
     return;
 
@@ -2692,6 +2752,7 @@
 
 void LayoutBlockFlow::MarkSiblingsWithFloatsForLayout(
     LayoutBox* float_to_remove) {
+  CheckIsNotDestroyed();
   if (!floating_objects_)
     return;
 
@@ -2718,6 +2779,7 @@
 
 LayoutUnit LayoutBlockFlow::GetClearDelta(LayoutBox* child,
                                           LayoutUnit logical_top) {
+  CheckIsNotDestroyed();
   // There is no need to compute clearance if we have no floats.
   if (!ContainsFloats())
     return LayoutUnit();
@@ -2776,11 +2838,13 @@
 }
 
 void LayoutBlockFlow::CreateFloatingObjects() {
+  CheckIsNotDestroyed();
   floating_objects_ =
       std::make_unique<FloatingObjects>(this, IsHorizontalWritingMode());
 }
 
 void LayoutBlockFlow::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   // Make sure to destroy anonymous children first while they are still
   // connected to the rest of the tree, so that they will properly dirty line
   // boxes that they are removed from. Effects that do :before/:after only on
@@ -2820,6 +2884,7 @@
 
 void LayoutBlockFlow::StyleWillChange(StyleDifference diff,
                                       const ComputedStyle& new_style) {
+  CheckIsNotDestroyed();
   const ComputedStyle* old_style = Style();
   can_propagate_float_into_sibling_ = old_style &&
                                       !IsFloatingOrOutOfFlowPositioned() &&
@@ -2836,6 +2901,7 @@
 DISABLE_CFI_PERF
 void LayoutBlockFlow::StyleDidChange(StyleDifference diff,
                                      const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   bool had_self_painting_layer = HasSelfPaintingLayer();
   LayoutBlock::StyleDidChange(diff, old_style);
 
@@ -2907,6 +2973,7 @@
 void LayoutBlockFlow::UpdateBlockChildDirtyBitsBeforeLayout(
     bool relayout_children,
     LayoutBox& child) {
+  CheckIsNotDestroyed();
   if (child.IsLayoutMultiColumnSpannerPlaceholder())
     ToLayoutMultiColumnSpannerPlaceholder(child)
         .MarkForLayoutIfObjectInFlowThreadNeedsLayout();
@@ -2917,6 +2984,7 @@
     LayoutBox& child,
     LayoutUnit logical_top,
     IndentTextOrNot indent_text) {
+  CheckIsNotDestroyed();
   if (child.StyleRef().IsOriginalDisplayInlineType())
     SetStaticInlinePositionForChild(
         child, StartAlignedOffsetForLine(logical_top, indent_text));
@@ -2927,10 +2995,12 @@
 void LayoutBlockFlow::SetStaticInlinePositionForChild(
     LayoutBox& child,
     LayoutUnit inline_position) {
+  CheckIsNotDestroyed();
   child.Layer()->SetStaticInlinePosition(inline_position);
 }
 
 LayoutInline* LayoutBlockFlow::InlineElementContinuation() const {
+  CheckIsNotDestroyed();
   LayoutBoxModelObject* continuation = Continuation();
   return continuation && continuation->IsInline() ? ToLayoutInline(continuation)
                                                   : nullptr;
@@ -2938,6 +3008,7 @@
 
 void LayoutBlockFlow::AddChild(LayoutObject* new_child,
                                LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   if (LayoutMultiColumnFlowThread* flow_thread = MultiColumnFlowThread()) {
     if (before_child == flow_thread)
       before_child = flow_thread->FirstChild();
@@ -3020,6 +3091,7 @@
 }
 
 void LayoutBlockFlow::RemoveChild(LayoutObject* old_child) {
+  CheckIsNotDestroyed();
   // No need to waste time in merging or removing empty anonymous blocks.
   // We can just bail out if our document is getting destroyed.
   if (DocumentBeingDestroyed()) {
@@ -3126,6 +3198,7 @@
 void LayoutBlockFlow::MoveAllChildrenIncludingFloatsTo(
     LayoutBlock* to_block,
     bool full_remove_insert) {
+  CheckIsNotDestroyed();
   auto* to_block_flow = To<LayoutBlockFlow>(to_block);
 
   DCHECK(full_remove_insert ||
@@ -3171,6 +3244,7 @@
 }
 
 void LayoutBlockFlow::ChildBecameFloatingOrOutOfFlow(LayoutBox* child) {
+  CheckIsNotDestroyed();
   MakeChildrenInlineIfPossible();
 
   // Reparent the child to an adjacent anonymous block if one is available.
@@ -3191,6 +3265,7 @@
 }
 
 void LayoutBlockFlow::CollapseAnonymousBlockChild(LayoutBlockFlow* child) {
+  CheckIsNotDestroyed();
   // It's possible that this block's destruction may have been triggered by the
   // child's removal. Just bail if the anonymous child block is already being
   // destroyed. See crbug.com/282088
@@ -3220,6 +3295,7 @@
 
 bool LayoutBlockFlow::MergeSiblingContiguousAnonymousBlock(
     LayoutBlockFlow* sibling_that_may_be_deleted) {
+  CheckIsNotDestroyed();
   // Note: |this| and |siblingThatMayBeDeleted| may not be adjacent siblings at
   // this point. There may be an object between them which is about to be
   // removed.
@@ -3245,6 +3321,7 @@
 }
 
 void LayoutBlockFlow::ReparentSubsequentFloatingOrOutOfFlowSiblings() {
+  CheckIsNotDestroyed();
   auto* parent_block_flow = DynamicTo<LayoutBlockFlow>(Parent());
   if (!parent_block_flow)
     return;
@@ -3265,6 +3342,7 @@
 }
 
 void LayoutBlockFlow::ReparentPrecedingFloatingOrOutOfFlowSiblings() {
+  CheckIsNotDestroyed();
   auto* parent_block_flow = DynamicTo<LayoutBlockFlow>(Parent());
   if (!parent_block_flow)
     return;
@@ -3279,6 +3357,7 @@
 }
 
 void LayoutBlockFlow::MakeChildrenInlineIfPossible() {
+  CheckIsNotDestroyed();
   // Collapsing away anonymous wrappers isn't relevant for the children of
   // anonymous blocks, unless they are ruby bases.
   if (IsAnonymousBlock() && !IsRubyBase())
@@ -3379,6 +3458,7 @@
 }
 
 void LayoutBlockFlow::MakeChildrenNonInline(LayoutObject* insertion_point) {
+  CheckIsNotDestroyed();
   // makeChildrenNonInline takes a block whose children are *all* inline and it
   // makes sure that inline children are coalesced under anonymous blocks.
   // If |insertionPoint| is defined, then it represents the insertion point for
@@ -3422,6 +3502,7 @@
 }
 
 void LayoutBlockFlow::ChildBecameNonInline(LayoutObject*) {
+  CheckIsNotDestroyed();
   MakeChildrenNonInline();
   auto* parent_layout_block = DynamicTo<LayoutBlock>(Parent());
   if (IsAnonymousBlock() && parent_layout_block)
@@ -3430,6 +3511,7 @@
 }
 
 void LayoutBlockFlow::ClearFloats(EClear clear) {
+  CheckIsNotDestroyed();
   PlaceNewFloats(LogicalHeight());
   // set y position
   LayoutUnit new_y = LowestFloatLogicalBottom(clear);
@@ -3438,12 +3520,14 @@
 }
 
 bool LayoutBlockFlow::ContainsFloat(LayoutBox* layout_box) const {
+  CheckIsNotDestroyed();
   return floating_objects_ &&
          floating_objects_->Set().Contains<FloatingObjectHashTranslator>(
              layout_box);
 }
 
 void LayoutBlockFlow::RemoveFloatingObjects() {
+  CheckIsNotDestroyed();
   if (!floating_objects_)
     return;
 
@@ -3455,6 +3539,7 @@
 LayoutPoint LayoutBlockFlow::FlipFloatForWritingModeForChild(
     const FloatingObject& child,
     const LayoutPoint& point) const {
+  CheckIsNotDestroyed();
   if (!StyleRef().IsFlippedBlocksWritingMode())
     return point;
 
@@ -3472,6 +3557,7 @@
     LayoutUnit logical_top,
     LayoutUnit fixed_offset,
     LayoutUnit* height_remaining) const {
+  CheckIsNotDestroyed();
   LayoutUnit offset = fixed_offset;
   if (floating_objects_ && floating_objects_->HasLeftObjects())
     offset = floating_objects_->LogicalLeftOffsetForPositioningFloat(
@@ -3483,6 +3569,7 @@
     LayoutUnit logical_top,
     LayoutUnit fixed_offset,
     LayoutUnit* height_remaining) const {
+  CheckIsNotDestroyed();
   LayoutUnit offset = fixed_offset;
   if (floating_objects_ && floating_objects_->HasRightObjects())
     offset = floating_objects_->LogicalRightOffsetForPositioningFloat(
@@ -3493,6 +3580,7 @@
 LayoutUnit LayoutBlockFlow::AdjustLogicalLeftOffsetForLine(
     LayoutUnit offset_from_floats,
     IndentTextOrNot apply_text_indent) const {
+  CheckIsNotDestroyed();
   LayoutUnit left = offset_from_floats;
 
   if (apply_text_indent == kIndentText && StyleRef().IsLeftToRightDirection())
@@ -3504,6 +3592,7 @@
 LayoutUnit LayoutBlockFlow::AdjustLogicalRightOffsetForLine(
     LayoutUnit offset_from_floats,
     IndentTextOrNot apply_text_indent) const {
+  CheckIsNotDestroyed();
   LayoutUnit right = offset_from_floats;
 
   if (apply_text_indent == kIndentText && !StyleRef().IsLeftToRightDirection())
@@ -3515,6 +3604,7 @@
 LayoutPoint LayoutBlockFlow::ComputeLogicalLocationForFloat(
     const FloatingObject& floating_object,
     LayoutUnit logical_top_offset) const {
+  CheckIsNotDestroyed();
   LayoutBox* child_box = floating_object.GetLayoutObject();
   LayoutUnit logical_left_offset =
       LogicalLeftOffsetForContent();  // Constant part of left offset.
@@ -3569,6 +3659,7 @@
 }
 
 FloatingObject* LayoutBlockFlow::InsertFloatingObject(LayoutBox& float_box) {
+  CheckIsNotDestroyed();
   DCHECK(float_box.IsFloating());
 
   // Create the list of special objects if we don't aleady have one
@@ -3594,6 +3685,7 @@
 }
 
 void LayoutBlockFlow::RemoveFloatingObject(LayoutBox* float_box) {
+  CheckIsNotDestroyed();
   if (floating_objects_) {
     const FloatingObjectSet& floating_object_set = floating_objects_->Set();
     FloatingObjectSetIterator it =
@@ -3634,6 +3726,7 @@
 
 void LayoutBlockFlow::RemoveFloatingObjectsBelow(FloatingObject* last_float,
                                                  LayoutUnit logical_offset) {
+  CheckIsNotDestroyed();
   if (!ContainsFloats())
     return;
 
@@ -3650,6 +3743,7 @@
 
 FloatingObject* LayoutBlockFlow::LastPlacedFloat(
     FloatingObjectSetIterator* iterator) const {
+  CheckIsNotDestroyed();
   const FloatingObjectSet& floating_object_set = floating_objects_->Set();
   FloatingObjectSetIterator it = floating_object_set.end();
   --it;  // Go to last item.
@@ -3670,6 +3764,7 @@
 
 bool LayoutBlockFlow::PlaceNewFloats(LayoutUnit logical_top_margin_edge,
                                      LineWidth* width) {
+  CheckIsNotDestroyed();
   if (!floating_objects_)
     return false;
 
@@ -3716,6 +3811,7 @@
 LayoutUnit LayoutBlockFlow::PositionAndLayoutFloat(
     FloatingObject& floating_object,
     LayoutUnit logical_top_margin_edge) {
+  CheckIsNotDestroyed();
   // Once a float has been placed, we cannot update its position, or the float
   // interval tree will be out of sync with reality. This may in turn lead to
   // objects being used after they have been deleted.
@@ -3845,6 +3941,7 @@
 }
 
 bool LayoutBlockFlow::HasOverhangingFloat(LayoutBox* layout_box) {
+  CheckIsNotDestroyed();
   if (!floating_objects_ || !Parent())
     return false;
 
@@ -3860,6 +3957,7 @@
 void LayoutBlockFlow::AddIntrudingFloats(LayoutBlockFlow* prev,
                                          LayoutUnit logical_left_offset,
                                          LayoutUnit logical_top_offset) {
+  CheckIsNotDestroyed();
   DCHECK(!CreatesNewFormattingContext());
 
   // If we create our own block formatting context then our contents don't
@@ -3911,6 +4009,7 @@
 
 void LayoutBlockFlow::AddOverhangingFloats(LayoutBlockFlow* child,
                                            bool make_child_paint_other_floats) {
+  CheckIsNotDestroyed();
   // Prevent floats from being added to the canvas by the root element, e.g.,
   // <html>.
   if (!child->ContainsFloats() || child->CreatesNewFormattingContext())
@@ -3993,6 +4092,7 @@
 }
 
 LayoutUnit LayoutBlockFlow::LowestFloatLogicalBottom(EClear clear) const {
+  CheckIsNotDestroyed();
   if (clear == EClear::kNone || !floating_objects_)
     return LayoutUnit();
 
@@ -4006,6 +4106,7 @@
 
 LayoutUnit LayoutBlockFlow::NextFloatLogicalBottomBelow(
     LayoutUnit logical_height) const {
+  CheckIsNotDestroyed();
   if (!floating_objects_)
     return logical_height;
   return floating_objects_->FindNextFloatLogicalBottomBelow(logical_height);
@@ -4013,6 +4114,7 @@
 
 LayoutUnit LayoutBlockFlow::NextFloatLogicalBottomBelowForBlock(
     LayoutUnit logical_height) const {
+  CheckIsNotDestroyed();
   if (!floating_objects_)
     return logical_height;
 
@@ -4021,11 +4123,13 @@
 }
 
 LayoutUnit LayoutBlockFlow::LogicalHeightWithVisibleOverflow() const {
+  CheckIsNotDestroyed();
   LayoutUnit logical_height = LayoutBlock::LogicalHeightWithVisibleOverflow();
   return std::max(logical_height, LowestFloatLogicalBottom());
 }
 
 Node* LayoutBlockFlow::NodeForHitTest() const {
+  CheckIsNotDestroyed();
   // If we are in the margins of block elements that are part of a
   // continuation we're actually still inside the enclosing element
   // that was split. Use the appropriate inner node.
@@ -4037,6 +4141,7 @@
                                       const HitTestLocation& hit_test_location,
                                       const PhysicalOffset& accumulated_offset,
                                       HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   PhysicalOffset scrolled_offset = accumulated_offset;
   if (IsScrollContainer())
     scrolled_offset -= PhysicalOffset(PixelSnappedScrolledContentOffset());
@@ -4068,6 +4173,7 @@
 bool LayoutBlockFlow::HitTestFloats(HitTestResult& result,
                                     const HitTestLocation& hit_test_location,
                                     const PhysicalOffset& accumulated_offset) {
+  CheckIsNotDestroyed();
   if (!floating_objects_)
     return false;
 
@@ -4098,6 +4204,7 @@
 }
 
 PhysicalOffset LayoutBlockFlow::AccumulateRelativePositionOffsets() const {
+  CheckIsNotDestroyed();
   if (!IsAnonymousBlock() || !IsInFlowPositioned())
     return PhysicalOffset();
   PhysicalOffset offset;
@@ -4113,6 +4220,7 @@
     LayoutUnit logical_top,
     LayoutUnit fixed_offset,
     LayoutUnit logical_height) const {
+  CheckIsNotDestroyed();
   if (floating_objects_ && floating_objects_->HasLeftObjects())
     return floating_objects_->LogicalLeftOffset(fixed_offset, logical_top,
                                                 logical_height);
@@ -4124,6 +4232,7 @@
     LayoutUnit logical_top,
     LayoutUnit fixed_offset,
     LayoutUnit logical_height) const {
+  CheckIsNotDestroyed();
   if (floating_objects_ && floating_objects_->HasRightObjects())
     return floating_objects_->LogicalRightOffset(fixed_offset, logical_top,
                                                  logical_height);
@@ -4135,6 +4244,7 @@
     LayoutUnit logical_top,
     LayoutUnit fixed_offset,
     LayoutUnit logical_height) const {
+  CheckIsNotDestroyed();
   if (floating_objects_ && floating_objects_->HasLeftObjects()) {
     return floating_objects_->LogicalLeftOffsetForAvoidingFloats(
         fixed_offset, logical_top, logical_height);
@@ -4147,6 +4257,7 @@
     LayoutUnit logical_top,
     LayoutUnit fixed_offset,
     LayoutUnit logical_height) const {
+  CheckIsNotDestroyed();
   if (floating_objects_ && floating_objects_->HasRightObjects()) {
     return floating_objects_->LogicalRightOffsetForAvoidingFloats(
         fixed_offset, logical_top, logical_height);
@@ -4210,6 +4321,7 @@
 }
 
 bool LayoutBlockFlow::AllowsPaginationStrut() const {
+  CheckIsNotDestroyed();
   // The block needs to be contained by a LayoutBlockFlow (and not by e.g. a
   // flexbox, grid, or a table (the latter being the case for table cell or
   // table caption)). The reason for this limitation is simply that
@@ -4256,6 +4368,7 @@
 }
 
 void LayoutBlockFlow::SetPaginationStrutPropagatedFromChild(LayoutUnit strut) {
+  CheckIsNotDestroyed();
   strut = std::max(strut, LayoutUnit());
   if (!rare_data_) {
     if (!strut)
@@ -4266,6 +4379,7 @@
 }
 
 void LayoutBlockFlow::SetFirstForcedBreakOffset(LayoutUnit block_offset) {
+  CheckIsNotDestroyed();
   if (!rare_data_) {
     if (!block_offset)
       return;
@@ -4275,24 +4389,28 @@
 }
 
 const AtomicString LayoutBlockFlow::StartPageName() const {
+  CheckIsNotDestroyed();
   if (const AtomicString& propagated_name = PropagatedStartPageName())
     return propagated_name;
   return StyleRef().Page();
 }
 
 const AtomicString LayoutBlockFlow::EndPageName() const {
+  CheckIsNotDestroyed();
   if (const AtomicString& propagated_name = PropagatedEndPageName())
     return propagated_name;
   return StyleRef().Page();
 }
 
 const AtomicString LayoutBlockFlow::PropagatedStartPageName() const {
+  CheckIsNotDestroyed();
   if (!rare_data_)
     return AtomicString();
   return rare_data_->propagated_start_page_name_;
 }
 
 void LayoutBlockFlow::SetPropagatedStartPageName(const AtomicString& name) {
+  CheckIsNotDestroyed();
   if (name.IsEmpty() && !rare_data_)
     return;
   LayoutBlockFlowRareData& rare_data = EnsureRareData();
@@ -4300,12 +4418,14 @@
 }
 
 const AtomicString LayoutBlockFlow::PropagatedEndPageName() const {
+  CheckIsNotDestroyed();
   if (!rare_data_)
     return AtomicString();
   return rare_data_->propagated_end_page_name_;
 }
 
 void LayoutBlockFlow::SetPropagatedEndPageName(const AtomicString& name) {
+  CheckIsNotDestroyed();
   if (name.IsEmpty() && !rare_data_)
     return;
   LayoutBlockFlowRareData& rare_data = EnsureRareData();
@@ -4314,6 +4434,7 @@
 
 void LayoutBlockFlow::PositionSpannerDescendant(
     LayoutMultiColumnSpannerPlaceholder& child) {
+  CheckIsNotDestroyed();
   LayoutBox& spanner = *child.LayoutObjectInFlowThread();
   // FIXME: |spanner| is a descendant, but never a direct child, so the names
   // here are bad, if nothing else.
@@ -4323,6 +4444,7 @@
 
 DISABLE_CFI_PERF
 bool LayoutBlockFlow::CreatesNewFormattingContext() const {
+  CheckIsNotDestroyed();
   if (IsInline() || IsFloatingOrOutOfFlowPositioned() || IsScrollContainer() ||
       IsFlexItemIncludingDeprecatedAndNG() || IsCustomItem() ||
       IsDocumentElement() || IsGridItemIncludingNG() || IsWritingModeRoot() ||
@@ -4349,6 +4471,7 @@
                                      LayoutObject* end_child,
                                      LayoutObject* before_child,
                                      bool full_remove_insert) {
+  CheckIsNotDestroyed();
   if (ChildrenInline())
     DeleteLineBoxTree();
   LayoutBoxModelObject::MoveChildrenTo(to_box_model_object, start_child,
@@ -4357,11 +4480,13 @@
 }
 
 RootInlineBox* LayoutBlockFlow::CreateRootInlineBox() {
+  CheckIsNotDestroyed();
   return new RootInlineBox(LineLayoutItem(this));
 }
 
 void LayoutBlockFlow::CreateOrDestroyMultiColumnFlowThreadIfNeeded(
     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   bool specifies_columns = StyleRef().SpecifiesColumns();
 
   if (MultiColumnFlowThread()) {
@@ -4428,6 +4553,7 @@
 }
 
 LayoutBlockFlow::LayoutBlockFlowRareData& LayoutBlockFlow::EnsureRareData() {
+  CheckIsNotDestroyed();
   if (rare_data_)
     return *rare_data_;
 
@@ -4436,6 +4562,7 @@
 }
 
 void LayoutBlockFlow::PositionDialog() {
+  CheckIsNotDestroyed();
   base::Optional<LayoutUnit> y =
       ComputeAbsoluteDialogYPosition(*this, Size().Height());
   if (y.has_value())
@@ -4443,6 +4570,7 @@
 }
 
 void LayoutBlockFlow::SimplifiedNormalFlowInlineLayout() {
+  CheckIsNotDestroyed();
   DCHECK(ChildrenInline());
   LinkedHashSet<RootInlineBox*> line_boxes;
   for (InlineWalker walker(LineLayoutBlockFlow(this)); !walker.AtEnd();
@@ -4472,6 +4600,7 @@
 }
 
 bool LayoutBlockFlow::RecalcInlineChildrenLayoutOverflow() {
+  CheckIsNotDestroyed();
   DCHECK(ChildrenInline());
   bool children_layout_overflow_changed = false;
   HashSet<RootInlineBox*> line_boxes;
@@ -4502,6 +4631,7 @@
 }
 
 void LayoutBlockFlow::RecalcInlineChildrenVisualOverflow() {
+  CheckIsNotDestroyed();
   DCHECK(ChildrenInline());
 
   if (const NGPaintFragment* paint_fragment = PaintFragment()) {
@@ -4555,6 +4685,7 @@
 PositionWithAffinity LayoutBlockFlow::PositionForPoint(
     const LayoutObject& offset_parent,
     const PhysicalOffset& offset) const {
+  CheckIsNotDestroyed();
   // Currently this function is called only from an inline child of this
   // |LayoutBlockFlow|.
   DCHECK(offset_parent.IsInline());
@@ -4576,6 +4707,7 @@
 
 PositionWithAffinity LayoutBlockFlow::PositionForPoint(
     const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   if (IsAtomicInlineLevel()) {
     PositionWithAffinity position =
         PositionForPointIfOutsideAtomicInlineLevel(point);
@@ -4710,6 +4842,7 @@
 
 bool LayoutBlockFlow::ShouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom()
     const {
+  CheckIsNotDestroyed();
   return GetDocument()
       .GetFrame()
       ->GetEditor()
@@ -4724,6 +4857,7 @@
                                           const InlineBox* marked_box2,
                                           const char* marked_label2,
                                           const LayoutObject* obj) const {
+  CheckIsNotDestroyed();
   StringBuilder string_blockflow;
   DumpLayoutObject(string_blockflow, true, kShowTreeCharacterOffset);
   for (const RootInlineBox* root = FirstRootBox(); root;
@@ -4740,6 +4874,7 @@
     Vector<PhysicalRect>& rects,
     const PhysicalOffset& additional_offset,
     NGOutlineType include_block_overflows) const {
+  CheckIsNotDestroyed();
   // For blocks inside inlines, we go ahead and include margins so that we run
   // right up to the inline boxes above and below us (thus getting merged with
   // them to form a single irregular shape).
@@ -4806,11 +4941,13 @@
 
 void LayoutBlockFlow::InvalidateDisplayItemClients(
     PaintInvalidationReason invalidation_reason) const {
+  CheckIsNotDestroyed();
   BlockFlowPaintInvalidator(*this).InvalidateDisplayItemClients(
       invalidation_reason);
 }
 
 void LayoutBlockFlow::IncrementLayoutPassCount() {
+  CheckIsNotDestroyed();
   int layout_pass_count = 0;
   HashMap<LayoutBlockFlow*, int>::iterator layout_count_iterator =
       GetLayoutPassCountMap().find(this);
@@ -4820,6 +4957,7 @@
 }
 
 int LayoutBlockFlow::GetLayoutPassCountForTesting() {
+  CheckIsNotDestroyed();
   return GetLayoutPassCountMap().find(this)->value;
 }
 
@@ -4837,6 +4975,7 @@
 LayoutBlockFlow::LayoutBlockFlowRareData::~LayoutBlockFlowRareData() = default;
 
 void LayoutBlockFlow::ClearOffsetMappingIfNeeded() {
+  CheckIsNotDestroyed();
   DCHECK(!IsLayoutNGObject());
   if (!rare_data_)
     return;
@@ -4844,6 +4983,7 @@
 }
 
 const NGOffsetMapping* LayoutBlockFlow::GetOffsetMapping() const {
+  CheckIsNotDestroyed();
   DCHECK(!IsLayoutNGObject());
   CHECK(!SelfNeedsLayout());
   CHECK(!NeedsLayout() || ChildLayoutBlockedByDisplayLock());
@@ -4852,6 +4992,7 @@
 
 void LayoutBlockFlow::SetOffsetMapping(
     std::unique_ptr<NGOffsetMapping> offset_mapping) {
+  CheckIsNotDestroyed();
   DCHECK(!IsLayoutNGObject());
   DCHECK(offset_mapping);
   EnsureRareData().offset_mapping_ = std::move(offset_mapping);
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 ebbcaff..4192f31c 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow.h
+++ b/third_party/blink/renderer/core/layout/layout_block_flow.h
@@ -105,7 +105,10 @@
                                           scoped_refptr<ComputedStyle>,
                                           LegacyLayout);
 
-  bool IsLayoutBlockFlow() const final { return true; }
+  bool IsLayoutBlockFlow() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   void UpdateBlockLayout(bool relayout_children) override;
 
@@ -121,6 +124,7 @@
       LayoutUnit position,
       IndentTextOrNot indent_text,
       LayoutUnit logical_height = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     return (LogicalRightOffsetForLine(position, indent_text, logical_height) -
             LogicalLeftOffsetForLine(position, indent_text, logical_height))
         .ClampNegativeToZero();
@@ -129,6 +133,7 @@
       LayoutUnit position,
       IndentTextOrNot indent_text,
       LayoutUnit logical_height = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     return LogicalRightOffsetForLine(position, LogicalRightOffsetForContent(),
                                      indent_text, logical_height);
   }
@@ -136,6 +141,7 @@
       LayoutUnit position,
       IndentTextOrNot indent_text,
       LayoutUnit logical_height = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     return LogicalLeftOffsetForLine(position, LogicalLeftOffsetForContent(),
                                     indent_text, logical_height);
   }
@@ -143,6 +149,7 @@
       LayoutUnit position,
       IndentTextOrNot indent_text,
       LayoutUnit logical_height = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     return StyleRef().IsLeftToRightDirection()
                ? LogicalLeftOffsetForLine(position, indent_text, logical_height)
                : LogicalWidth() - LogicalRightOffsetForLine(
@@ -152,6 +159,7 @@
   LayoutUnit AvailableLogicalWidthForAvoidingFloats(
       LayoutUnit position,
       LayoutUnit logical_height = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     return (LogicalRightOffsetForAvoidingFloats(position, logical_height) -
             LogicalLeftOffsetForAvoidingFloats(position, logical_height))
         .ClampNegativeToZero();
@@ -159,18 +167,21 @@
   LayoutUnit LogicalLeftOffsetForAvoidingFloats(
       LayoutUnit position,
       LayoutUnit logical_height = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     return LogicalLeftFloatOffsetForAvoidingFloats(
         position, LogicalLeftOffsetForContent(), logical_height);
   }
   LayoutUnit LogicalRightOffsetForAvoidingFloats(
       LayoutUnit position,
       LayoutUnit logical_height = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     return LogicalRightFloatOffsetForAvoidingFloats(
         position, LogicalRightOffsetForContent(), logical_height);
   }
   LayoutUnit StartOffsetForAvoidingFloats(
       LayoutUnit position,
       LayoutUnit logical_height = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     return StyleRef().IsLeftToRightDirection()
                ? LogicalLeftOffsetForAvoidingFloats(position, logical_height)
                : LogicalWidth() - LogicalRightOffsetForAvoidingFloats(
@@ -179,20 +190,35 @@
   LayoutUnit EndOffsetForAvoidingFloats(
       LayoutUnit position,
       LayoutUnit logical_height = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     return !StyleRef().IsLeftToRightDirection()
                ? LogicalLeftOffsetForAvoidingFloats(position, logical_height)
                : LogicalWidth() - LogicalRightOffsetForAvoidingFloats(
                                       position, logical_height);
   }
 
-  const LineBoxList& LineBoxes() const { return line_boxes_; }
-  LineBoxList* LineBoxes() { return &line_boxes_; }
-  InlineFlowBox* FirstLineBox() const { return line_boxes_.First(); }
-  InlineFlowBox* LastLineBox() const { return line_boxes_.Last(); }
+  const LineBoxList& LineBoxes() const {
+    CheckIsNotDestroyed();
+    return line_boxes_;
+  }
+  LineBoxList* LineBoxes() {
+    CheckIsNotDestroyed();
+    return &line_boxes_;
+  }
+  InlineFlowBox* FirstLineBox() const {
+    CheckIsNotDestroyed();
+    return line_boxes_.First();
+  }
+  InlineFlowBox* LastLineBox() const {
+    CheckIsNotDestroyed();
+    return line_boxes_.Last();
+  }
   RootInlineBox* FirstRootBox() const {
+    CheckIsNotDestroyed();
     return static_cast<RootInlineBox*>(FirstLineBox());
   }
   RootInlineBox* LastRootBox() const {
+    CheckIsNotDestroyed();
     return static_cast<RootInlineBox*>(LastLineBox());
   }
 
@@ -215,6 +241,7 @@
   void MarkSiblingsWithFloatsForLayout(LayoutBox* float_to_remove = nullptr);
 
   bool ContainsFloats() const {
+    CheckIsNotDestroyed();
     return floating_objects_ && !floating_objects_->Set().IsEmpty();
   }
   bool ContainsFloat(LayoutBox*) const;
@@ -222,9 +249,11 @@
   void RemoveFloatingObjects();
 
   LayoutBoxModelObject* VirtualContinuation() const final {
+    CheckIsNotDestroyed();
     return Continuation();
   }
   bool IsAnonymousBlockContinuation() const {
+    CheckIsNotDestroyed();
     return Continuation() && IsAnonymousBlock();
   }
 
@@ -246,29 +275,35 @@
   bool GeneratesLineBoxesForInlineChild(LayoutObject*);
 
   LayoutUnit LogicalTopForFloat(const FloatingObject& floating_object) const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? floating_object.Y()
                                      : floating_object.X();
   }
   LayoutUnit LogicalBottomForFloat(
       const FloatingObject& floating_object) const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? floating_object.MaxY()
                                      : floating_object.MaxX();
   }
   LayoutUnit LogicalLeftForFloat(const FloatingObject& floating_object) const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? floating_object.X()
                                      : floating_object.Y();
   }
   LayoutUnit LogicalRightForFloat(const FloatingObject& floating_object) const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? floating_object.MaxX()
                                      : floating_object.MaxY();
   }
   LayoutUnit LogicalWidthForFloat(const FloatingObject& floating_object) const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? floating_object.Width()
                                      : floating_object.Height();
   }
 
   void SetLogicalTopForFloat(FloatingObject& floating_object,
                              LayoutUnit logical_top) {
+    CheckIsNotDestroyed();
     if (IsHorizontalWritingMode())
       floating_object.SetY(logical_top);
     else
@@ -276,6 +311,7 @@
   }
   void SetLogicalLeftForFloat(FloatingObject& floating_object,
                               LayoutUnit logical_left) {
+    CheckIsNotDestroyed();
     if (IsHorizontalWritingMode())
       floating_object.SetX(logical_left);
     else
@@ -283,6 +319,7 @@
   }
   void SetLogicalHeightForFloat(FloatingObject& floating_object,
                                 LayoutUnit logical_height) {
+    CheckIsNotDestroyed();
     if (IsHorizontalWritingMode())
       floating_object.SetHeight(logical_height);
     else
@@ -290,6 +327,7 @@
   }
   void SetLogicalWidthForFloat(FloatingObject& floating_object,
                                LayoutUnit logical_width) {
+    CheckIsNotDestroyed();
     if (IsHorizontalWritingMode())
       floating_object.SetWidth(logical_width);
     else
@@ -310,9 +348,11 @@
   }
 
   LayoutMultiColumnFlowThread* MultiColumnFlowThread() const {
+    CheckIsNotDestroyed();
     return rare_data_ ? rare_data_->multi_column_flow_thread_ : nullptr;
   }
   void ResetMultiColumnFlowThread() {
+    CheckIsNotDestroyed();
     if (rare_data_)
       rare_data_->multi_column_flow_thread_ = nullptr;
   }
@@ -343,12 +383,14 @@
   // between the content logical top of an object and its first child or line
   // (only *between* blocks or lines).
   LayoutUnit PaginationStrutPropagatedFromChild() const {
+    CheckIsNotDestroyed();
     return rare_data_ ? rare_data_->pagination_strut_propagated_from_child_
                       : LayoutUnit();
   }
   void SetPaginationStrutPropagatedFromChild(LayoutUnit);
 
   LayoutUnit FirstForcedBreakOffset() const {
+    CheckIsNotDestroyed();
     if (!rare_data_)
       return LayoutUnit();
     return rare_data_->first_forced_break_offset_;
@@ -371,6 +413,7 @@
 
   LayoutUnit XPositionForFloatIncludingMargin(
       const FloatingObject& child) const {
+    CheckIsNotDestroyed();
     LayoutUnit scrollbar_adjustment(OriginAdjustmentForScrollbars().Width());
     if (IsHorizontalWritingMode()) {
       return child.X() + child.GetLayoutObject()->MarginLeft() +
@@ -382,6 +425,7 @@
   DISABLE_CFI_PERF
   LayoutUnit YPositionForFloatIncludingMargin(
       const FloatingObject& child) const {
+    CheckIsNotDestroyed();
     if (IsHorizontalWritingMode())
       return child.Y() + MarginBeforeForChild(*child.GetLayoutObject());
 
@@ -391,7 +435,10 @@
   LayoutPoint FlipFloatForWritingModeForChild(const FloatingObject&,
                                               const LayoutPoint&) const;
 
-  const char* GetName() const override { return "LayoutBlockFlow"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutBlockFlow";
+  }
 
   FloatingObject* InsertFloatingObject(LayoutBox&);
 
@@ -423,6 +470,7 @@
   LayoutUnit NextFloatLogicalBottomBelowForBlock(LayoutUnit) const;
 
   FloatingObject* LastFloatFromPreviousLine() const {
+    CheckIsNotDestroyed();
     return ContainsFloats() ? floating_objects_->Set().back().get() : nullptr;
   }
 
@@ -440,16 +488,19 @@
   LayoutUnit LowestFloatLogicalBottom(EClear = EClear::kBoth) const;
 
   bool HasOverhangingFloats() const {
+    CheckIsNotDestroyed();
     return Parent() && ContainsFloats() &&
            LowestFloatLogicalBottom() > LogicalHeight();
   }
   bool IsOverhangingFloat(const FloatingObject& float_object) const {
+    CheckIsNotDestroyed();
     return LogicalBottomForFloat(float_object) > LogicalHeight();
   }
 
   LayoutUnit LogicalHeightWithVisibleOverflow() const final;
 
   void SetIsSelfCollapsingFromNG(bool is_self_collapsing) {
+    CheckIsNotDestroyed();
     is_self_collapsing_ = is_self_collapsing;
   }
 
@@ -459,12 +510,21 @@
   void AddVisualOverflowFromFloats(const NGPhysicalContainerFragment& fragment);
   void AddLayoutOverflowFromFloats();
 
-  virtual NGInlineNodeData* TakeNGInlineNodeData() { return nullptr; }
-  virtual NGInlineNodeData* GetNGInlineNodeData() const { return nullptr; }
-  virtual void ResetNGInlineNodeData() {}
-  virtual void ClearNGInlineNodeData() {}
-  virtual bool HasNGInlineNodeData() const { return false; }
-  virtual void WillCollectInlines() {}
+  virtual NGInlineNodeData* TakeNGInlineNodeData() {
+    CheckIsNotDestroyed();
+    return nullptr;
+  }
+  virtual NGInlineNodeData* GetNGInlineNodeData() const {
+    CheckIsNotDestroyed();
+    return nullptr;
+  }
+  virtual void ResetNGInlineNodeData() { CheckIsNotDestroyed(); }
+  virtual void ClearNGInlineNodeData() { CheckIsNotDestroyed(); }
+  virtual bool HasNGInlineNodeData() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
+  virtual void WillCollectInlines() { CheckIsNotDestroyed(); }
   virtual void SetPaintFragment(const NGBlockBreakToken*,
                                 scoped_refptr<const NGPhysicalFragment>);
   const NGFragmentItems* FragmentItems() const;
@@ -502,6 +562,7 @@
       LayoutUnit fixed_offset,
       IndentTextOrNot apply_text_indent,
       LayoutUnit logical_height = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     return AdjustLogicalRightOffsetForLine(
         LogicalRightFloatOffsetForLine(logical_top, fixed_offset,
                                        logical_height),
@@ -512,6 +573,7 @@
       LayoutUnit fixed_offset,
       IndentTextOrNot apply_text_indent,
       LayoutUnit logical_height = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     return AdjustLogicalLeftOffsetForLine(
         LogicalLeftFloatOffsetForLine(logical_top, fixed_offset,
                                       logical_height),
@@ -625,6 +687,7 @@
   void DirtyLinesFromChangedChild(
       LayoutObject* child,
       MarkingBehavior marking_behaviour = kMarkContainerChain) override {
+    CheckIsNotDestroyed();
     line_boxes_.DirtyLinesFromChangedChild(
         LineLayoutItem(this), LineLayoutItem(child),
         marking_behaviour == kMarkContainerChain);
@@ -659,16 +722,19 @@
                                       unsigned expansion_opportunity_count);
 
   bool ShouldBreakAtLineToAvoidWidow() const {
+    CheckIsNotDestroyed();
     return rare_data_ && rare_data_->line_break_to_avoid_widow_ >= 0;
   }
   void ClearShouldBreakAtLineToAvoidWidow() const;
   int LineBreakToAvoidWidow() const {
+    CheckIsNotDestroyed();
     return rare_data_ ? rare_data_->line_break_to_avoid_widow_ : -1;
   }
   void SetBreakAtLineToAvoidWidow(int);
   void ClearDidBreakAtLineToAvoidWidow();
   void SetDidBreakAtLineToAvoidWidow();
   bool DidBreakAtLineToAvoidWidow() const {
+    CheckIsNotDestroyed();
     return rare_data_ && rare_data_->did_break_at_line_to_avoid_widow_;
   }
 
@@ -802,6 +868,7 @@
   void SetOffsetMapping(std::unique_ptr<NGOffsetMapping>);
 
   const FloatingObjects* GetFloatingObjects() const {
+    CheckIsNotDestroyed();
     return floating_objects_.get();
   }
 
@@ -817,21 +884,25 @@
 
  protected:
   LayoutUnit MaxPositiveMarginBefore() const {
+    CheckIsNotDestroyed();
     return rare_data_
                ? rare_data_->margins_.PositiveMarginBefore()
                : LayoutBlockFlowRareData::PositiveMarginBeforeDefault(this);
   }
   LayoutUnit MaxNegativeMarginBefore() const {
+    CheckIsNotDestroyed();
     return rare_data_
                ? rare_data_->margins_.NegativeMarginBefore()
                : LayoutBlockFlowRareData::NegativeMarginBeforeDefault(this);
   }
   LayoutUnit MaxPositiveMarginAfter() const {
+    CheckIsNotDestroyed();
     return rare_data_
                ? rare_data_->margins_.PositiveMarginAfter()
                : LayoutBlockFlowRareData::PositiveMarginAfterDefault(this);
   }
   LayoutUnit MaxNegativeMarginAfter() const {
+    CheckIsNotDestroyed();
     return rare_data_
                ? rare_data_->margins_.NegativeMarginAfter()
                : LayoutBlockFlowRareData::NegativeMarginAfterDefault(this);
@@ -841,6 +912,7 @@
   void SetMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg);
 
   void InitMaxMarginValues() {
+    CheckIsNotDestroyed();
     if (rare_data_) {
       rare_data_->margins_ = MarginValues(
           LayoutBlockFlowRareData::PositiveMarginBeforeDefault(this),
@@ -854,9 +926,11 @@
 
  private:
   LayoutUnit CollapsedMarginBefore() const final {
+    CheckIsNotDestroyed();
     return MaxPositiveMarginBefore() - MaxNegativeMarginBefore();
   }
   LayoutUnit CollapsedMarginAfter() const final {
+    CheckIsNotDestroyed();
     return MaxPositiveMarginAfter() - MaxNegativeMarginAfter();
   }
 
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 94fa554..5284d11 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
@@ -181,6 +181,7 @@
 InlineFlowBox* LayoutBlockFlow::CreateLineBoxes(LineLayoutItem line_layout_item,
                                                 const LineInfo& line_info,
                                                 InlineBox* child_box) {
+  CheckIsNotDestroyed();
   // See if we have an unconstructed line box for this object that is also
   // the last item on the line.
   unsigned line_depth = 1;
@@ -287,6 +288,7 @@
 
 RootInlineBox* LayoutBlockFlow::ConstructLine(BidiRunList<BidiRun>& bidi_runs,
                                               const LineInfo& line_info) {
+  CheckIsNotDestroyed();
   DCHECK(bidi_runs.FirstRun());
 
   InlineFlowBox* parent_box = nullptr;
@@ -366,6 +368,7 @@
 
 ETextAlign LayoutBlockFlow::TextAlignmentForLine(
     bool ends_with_soft_break) const {
+  CheckIsNotDestroyed();
   return StyleRef().GetTextAlign(!ends_with_soft_break);
 }
 
@@ -474,6 +477,7 @@
                                            LayoutRubyRun* layout_ruby_run,
                                            LayoutObject* previous_object,
                                            const LineInfo& line_info) {
+  CheckIsNotDestroyed();
   int start_overhang;
   int end_overhang;
   LayoutObject* next_object = nullptr;
@@ -661,6 +665,7 @@
     LayoutUnit& total_logical_width,
     LayoutUnit& available_logical_width,
     unsigned expansion_opportunity_count) {
+  CheckIsNotDestroyed();
   TextDirection direction;
   if (root_inline_box &&
       root_inline_box->GetLineLayoutItem().StyleRef().GetUnicodeBidi() ==
@@ -729,6 +734,7 @@
 }
 
 bool LayoutBlockFlow::CanContainFirstFormattedLine() const {
+  CheckIsNotDestroyed();
   // The 'text-indent' only affects a line if it is the first formatted
   // line of an element. For example, the first line of an anonymous block
   // box is only affected if it is the first child of its parent element.
@@ -761,6 +767,7 @@
     GlyphOverflowAndFallbackFontsMap& text_box_data_map,
     VerticalPositionCache& vertical_position_cache,
     const WordMeasurements& word_measurements) {
+  CheckIsNotDestroyed();
   bool is_first_line =
       line_info.IsFirstLine() && CanContainFirstFormattedLine();
   bool is_after_hard_line_break =
@@ -802,6 +809,7 @@
     GlyphOverflowAndFallbackFontsMap& text_box_data_map,
     VerticalPositionCache& vertical_position_cache,
     const WordMeasurements& word_measurements) {
+  CheckIsNotDestroyed();
   bool needs_word_spacing = true;
   LayoutUnit total_logical_width = line_box->GetFlowSpacingLogicalWidth();
   bool is_after_expansion = true;
@@ -880,6 +888,7 @@
     BidiRun* first_run,
     GlyphOverflowAndFallbackFontsMap& text_box_data_map,
     VerticalPositionCache& vertical_position_cache) {
+  CheckIsNotDestroyed();
   SetLogicalHeight(line_box->AlignBoxesInBlockDirection(
       LogicalHeight(), text_box_data_map, vertical_position_cache));
 
@@ -907,6 +916,7 @@
 
 void LayoutBlockFlow::AppendFloatingObjectToLastLine(
     FloatingObject& floating_object) {
+  CheckIsNotDestroyed();
   DCHECK(!floating_object.OriginatingLine());
   floating_object.SetOriginatingLine(LastRootBox());
   LastRootBox()->AppendFloat(floating_object.GetLayoutObject());
@@ -922,6 +932,7 @@
     VerticalPositionCache& vertical_position_cache,
     BidiRun* trailing_space_run,
     const WordMeasurements& word_measurements) {
+  CheckIsNotDestroyed();
   if (!bidi_runs.RunCount())
     return nullptr;
 
@@ -983,6 +994,7 @@
 }
 
 void LayoutBlockFlow::LayoutRunsAndFloats(LineLayoutState& layout_state) {
+  CheckIsNotDestroyed();
   // We want to skip ahead to the first dirty line
   InlineBidiResolver resolver;
   RootInlineBox* start_line = DetermineStartPosition(layout_state, resolver);
@@ -1016,6 +1028,7 @@
     FloatingObject* last_float_from_previous_line,
     InlineBidiResolver& resolver,
     const InlineIterator& old_end) {
+  CheckIsNotDestroyed();
   RemoveFloatingObjectsBelow(last_float_from_previous_line, old_logical_height);
   SetLogicalHeight(new_logical_height);
   resolver.SetPositionIgnoringNestedIsolates(old_end);
@@ -1027,6 +1040,7 @@
     const InlineIterator& clean_line_start,
     const InlineBidiResolver& resolver,
     const BidiStatus& clean_line_bidi_status) {
+  CheckIsNotDestroyed();
   const FloatingObjectSet& floating_object_set = floating_objects_->Set();
   FloatingObjectSetIterator it = floating_object_set.begin();
   FloatingObjectSetIterator end = floating_object_set.end();
@@ -1075,6 +1089,7 @@
     InlineBidiResolver& resolver,
     const InlineIterator& clean_line_start,
     const BidiStatus& clean_line_bidi_status) {
+  CheckIsNotDestroyed();
   const ComputedStyle& style_to_use = StyleRef();
   bool paginated =
       View()->GetLayoutState() && View()->GetLayoutState()->IsPaginated();
@@ -1387,6 +1402,7 @@
 }
 
 void LayoutBlockFlow::LinkToEndLineIfNeeded(LineLayoutState& layout_state) {
+  CheckIsNotDestroyed();
   if (layout_state.EndLine()) {
     if (layout_state.EndLineMatched()) {
       bool recalculate_struts =
@@ -1432,6 +1448,7 @@
 
 void LayoutBlockFlow::MarkDirtyFloatsForPaintInvalidation(
     Vector<FloatWithRect>& floats) {
+  CheckIsNotDestroyed();
   size_t float_count = floats.size();
   // Floats that did not have layout did not paint invalidations when we laid
   // them out. They would have painted by now if they had moved, but if they
@@ -1614,6 +1631,7 @@
 void LayoutBlockFlow::ComputeInlinePreferredLogicalWidths(
     LayoutUnit& min_logical_width,
     LayoutUnit& max_logical_width) {
+  CheckIsNotDestroyed();
   LayoutUnit inline_max;
   LayoutUnit inline_min;
 
@@ -1940,6 +1958,7 @@
 }
 
 bool LayoutBlockFlow::ShouldTruncateOverflowingText() const {
+  CheckIsNotDestroyed();
   const LayoutObject* object_to_check = this;
   if (IsAnonymousBlock()) {
     const LayoutObject* parent = Parent();
@@ -1954,6 +1973,7 @@
 DISABLE_CFI_PERF
 void LayoutBlockFlow::LayoutInlineChildren(bool relayout_children,
                                            LayoutUnit after_edge) {
+  CheckIsNotDestroyed();
   // Figure out if we should clear out our line boxes.
   // FIXME: Handle resize eventually!
   bool is_full_layout =
@@ -2100,6 +2120,7 @@
 RootInlineBox* LayoutBlockFlow::DetermineStartPosition(
     LineLayoutState& layout_state,
     InlineBidiResolver& resolver) {
+  CheckIsNotDestroyed();
   RootInlineBox* curr = nullptr;
   RootInlineBox* last = nullptr;
   RootInlineBox* first_line_box_with_break_and_clearance = nullptr;
@@ -2228,6 +2249,7 @@
 }
 
 bool LayoutBlockFlow::LineBoxHasBRWithClearance(RootInlineBox* curr) {
+  CheckIsNotDestroyed();
   // If the linebox breaks cleanly and with clearance then dirty from at least
   // this point onwards so that we can clear the correct floats without
   // difficulty.
@@ -2244,6 +2266,7 @@
                                            RootInlineBox* start_line,
                                            InlineIterator& clean_line_start,
                                            BidiStatus& clean_line_bidi_status) {
+  CheckIsNotDestroyed();
   DCHECK(!layout_state.EndLine());
   RootInlineBox* last = nullptr;
   bool previous_was_clean = false;
@@ -2289,6 +2312,7 @@
 
 bool LayoutBlockFlow::CheckPaginationAndFloatsAtEndLine(
     LineLayoutState& layout_state) {
+  CheckIsNotDestroyed();
   if (!floating_objects_ || !layout_state.EndLine())
     return true;
 
@@ -2340,6 +2364,7 @@
                                      const InlineBidiResolver& resolver,
                                      const InlineIterator& end_line_start,
                                      const BidiStatus& end_line_status) {
+  CheckIsNotDestroyed();
   if (resolver.GetPosition() == end_line_start) {
     if (resolver.Status() != end_line_status)
       return false;
@@ -2380,6 +2405,7 @@
 bool LayoutBlockFlow::GeneratesLineBoxesForInlineChild(LayoutObject* inline_obj)
 
 {
+  CheckIsNotDestroyed();
   DCHECK_EQ(inline_obj->Parent(), this);
 
   InlineIterator it(LineLayoutBlockFlow(this), LineLayoutItem(inline_obj), 0);
@@ -2391,6 +2417,7 @@
 }
 
 void LayoutBlockFlow::AddVisualOverflowFromInlineChildren() {
+  CheckIsNotDestroyed();
   DCHECK(!NeedsLayout());
   DCHECK(!ChildPrePaintBlockedByDisplayLock());
 
@@ -2456,6 +2483,7 @@
 }
 
 void LayoutBlockFlow::AddLayoutOverflowFromInlineChildren() {
+  CheckIsNotDestroyed();
   DCHECK(!ChildLayoutBlockedByDisplayLock());
 
   LayoutUnit end_padding =
@@ -2502,6 +2530,7 @@
 }
 
 void LayoutBlockFlow::DeleteEllipsisLineBoxes() {
+  CheckIsNotDestroyed();
   ETextAlign text_align = StyleRef().GetTextAlign();
   IndentTextOrNot indent_text = kIndentText;
   for (RootInlineBox* curr = FirstRootBox(); curr; curr = curr->NextRootBox()) {
@@ -2528,6 +2557,7 @@
 }
 
 void LayoutBlockFlow::ClearTruncationOnAtomicInlines(RootInlineBox* root) {
+  CheckIsNotDestroyed();
   bool ltr = StyleRef().IsLeftToRightDirection();
   InlineBox* first_child = ltr ? root->LastChild() : root->FirstChild();
   for (InlineBox* box = first_child; box;
@@ -2544,6 +2574,7 @@
 }
 
 void LayoutBlockFlow::CheckLinesForTextOverflow() {
+  CheckIsNotDestroyed();
   // Determine the width of the ellipsis using the current font.
   const Font& font = StyleRef().GetFont();
 
@@ -2652,6 +2683,7 @@
     LayoutUnit ellipsis_width,
     const AtomicString& selected_ellipsis_str,
     InlineBox* box_truncation_starts_at) {
+  CheckIsNotDestroyed();
   bool found_box = box_truncation_starts_at ? true : false;
   bool ltr = StyleRef().IsLeftToRightDirection();
   LayoutUnit logical_left_offset = block_left_edge;
@@ -2730,6 +2762,7 @@
 void LayoutBlockFlow::MarkLinesDirtyInBlockRange(LayoutUnit logical_top,
                                                  LayoutUnit logical_bottom,
                                                  RootInlineBox* highest) {
+  CheckIsNotDestroyed();
   if (logical_top >= logical_bottom)
     return;
 
@@ -2753,6 +2786,7 @@
 LayoutUnit LayoutBlockFlow::StartAlignedOffsetForLine(
     LayoutUnit position,
     IndentTextOrNot indent_text) {
+  CheckIsNotDestroyed();
   ETextAlign text_align = StyleRef().GetTextAlign();
 
   bool apply_indent_text;
@@ -2793,6 +2827,7 @@
 }
 
 void LayoutBlockFlow::SetShouldDoFullPaintInvalidationForFirstLine() {
+  CheckIsNotDestroyed();
   DCHECK(ChildrenInline());
 
   if (const NGPaintFragment* paint_fragment = PaintFragment()) {
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 8d973c0..72192f4 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -291,6 +291,7 @@
 LayoutBox::~LayoutBox() = default;
 
 PaintLayerType LayoutBox::LayerTypeRequired() const {
+  CheckIsNotDestroyed();
   if (IsStacked() || HasHiddenBackface() ||
       (StyleRef().SpecifiesColumns() && !CanTraversePhysicalFragments()) ||
       IsEffectiveRootScroller())
@@ -306,6 +307,7 @@
 }
 
 void LayoutBox::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   ClearOverrideSize();
   ClearOverrideContainingBlockContentSize();
   ClearOverridePercentageResolutionBlockSize();
@@ -337,6 +339,7 @@
 }
 
 void LayoutBox::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   LayoutBoxModelObject::InsertedIntoTree();
   AddScrollSnapMapping();
   AddCustomLayoutChildIfNeeded();
@@ -346,6 +349,7 @@
 }
 
 void LayoutBox::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   if (!DocumentBeingDestroyed() && IsOrthogonalWritingModeRoot())
     UnmarkOrthogonalWritingModeRoot();
 
@@ -355,6 +359,7 @@
 }
 
 void LayoutBox::RemoveFloatingOrPositionedChildFromBlockLists() {
+  CheckIsNotDestroyed();
   DCHECK(IsFloatingOrOutOfFlowPositioned());
 
   if (DocumentBeingDestroyed())
@@ -382,6 +387,7 @@
 
 void LayoutBox::StyleWillChange(StyleDifference diff,
                                 const ComputedStyle& new_style) {
+  CheckIsNotDestroyed();
   const ComputedStyle* old_style = Style();
   if (old_style) {
     LayoutFlowThread* flow_thread = FlowThreadContainingBlock();
@@ -441,6 +447,7 @@
 
 void LayoutBox::StyleDidChange(StyleDifference diff,
                                const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   // Horizontal writing mode definition is updated in LayoutBoxModelObject::
   // updateFromStyle, (as part of the LayoutBoxModelObject::styleDidChange call
   // below). So, we can safely cache the horizontal writing mode value before
@@ -560,6 +567,7 @@
 }
 
 void LayoutBox::UpdateBackgroundAttachmentFixedStatusAfterStyleChange() {
+  CheckIsNotDestroyed();
   if (!GetFrameView())
     return;
 
@@ -571,6 +579,7 @@
 void LayoutBox::UpdateShapeOutsideInfoAfterStyleChange(
     const ComputedStyle& style,
     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   const ShapeValue* shape_outside = style.ShapeOutside();
   const ShapeValue* old_shape_outside =
       old_style ? old_style->ShapeOutside()
@@ -603,6 +612,7 @@
 
 void LayoutBox::UpdateGridPositionAfterStyleChange(
     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   if (!old_style || !Parent() || !Parent()->IsLayoutGrid())
     return;
 
@@ -627,6 +637,7 @@
 
 void LayoutBox::UpdateScrollSnapMappingAfterStyleChange(
     const ComputedStyle& old_style) {
+  CheckIsNotDestroyed();
   DCHECK(Style());
   SnapCoordinator& snap_coordinator = GetDocument().GetSnapCoordinator();
   // scroll-snap-type and scroll-padding invalidate the snap container.
@@ -654,16 +665,19 @@
 }
 
 void LayoutBox::AddScrollSnapMapping() {
+  CheckIsNotDestroyed();
   SnapCoordinator& snap_coordinator = GetDocument().GetSnapCoordinator();
   snap_coordinator.SnapAreaDidChange(*this, Style()->GetScrollSnapAlign());
 }
 
 void LayoutBox::ClearScrollSnapMapping() {
+  CheckIsNotDestroyed();
   SnapCoordinator& snap_coordinator = GetDocument().GetSnapCoordinator();
   snap_coordinator.SnapAreaDidChange(*this, cc::ScrollSnapAlign());
 }
 
 void LayoutBox::UpdateFromStyle() {
+  CheckIsNotDestroyed();
   LayoutBoxModelObject::UpdateFromStyle();
 
   const ComputedStyle& style_to_use = StyleRef();
@@ -676,6 +690,7 @@
 }
 
 void LayoutBox::LayoutSubtreeRoot() {
+  CheckIsNotDestroyed();
   if (RuntimeEnabledFeatures::LayoutNGEnabled() &&
       !NGBlockNode::CanUseNewLayout(*this) && GetCachedLayoutResult()) {
     // If this object is laid out by the legacy engine, while its containing
@@ -725,6 +740,7 @@
 }
 
 void LayoutBox::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
 
@@ -752,6 +768,7 @@
 // border and scrollbar.
 DISABLE_CFI_PERF
 LayoutUnit LayoutBox::ClientWidth() const {
+  CheckIsNotDestroyed();
   // We need to clamp negative values. This function may be called during layout
   // before frame_rect_ gets the final proper value. Another reason: While
   // border side values are currently limited to 2^20px (a recent change in the
@@ -769,6 +786,7 @@
 
 DISABLE_CFI_PERF
 LayoutUnit LayoutBox::ClientHeight() const {
+  CheckIsNotDestroyed();
   // We need to clamp negative values. This function can be called during layout
   // before frame_rect_ gets the final proper value. The scrollbar may be wider
   // than the padding box. Another reason: While border side values are
@@ -786,15 +804,18 @@
 }
 
 int LayoutBox::PixelSnappedClientWidth() const {
+  CheckIsNotDestroyed();
   return SnapSizeToPixel(ClientWidth(), Location().X() + ClientLeft());
 }
 
 DISABLE_CFI_PERF
 int LayoutBox::PixelSnappedClientHeight() const {
+  CheckIsNotDestroyed();
   return SnapSizeToPixel(ClientHeight(), Location().Y() + ClientTop());
 }
 
 int LayoutBox::PixelSnappedClientWidthWithTableSpecialBehavior() const {
+  CheckIsNotDestroyed();
   // clientWidth/Height is the visual portion of the box content, not including
   // borders or scroll bars, but includes padding. And per
   // https://www.w3.org/TR/CSS2/tables.html#model,
@@ -813,6 +834,7 @@
 
 DISABLE_CFI_PERF
 int LayoutBox::PixelSnappedClientHeightWithTableSpecialBehavior() const {
+  CheckIsNotDestroyed();
   // clientWidth/Height is the visual portion of the box content, not including
   // borders or scroll bars, but includes padding. And per
   // https://www.w3.org/TR/CSS2/tables.html#model,
@@ -830,14 +852,17 @@
 }
 
 int LayoutBox::PixelSnappedOffsetWidth(const Element*) const {
+  CheckIsNotDestroyed();
   return SnapSizeToPixel(OffsetWidth(), Location().X() + ClientLeft());
 }
 
 int LayoutBox::PixelSnappedOffsetHeight(const Element*) const {
+  CheckIsNotDestroyed();
   return SnapSizeToPixel(OffsetHeight(), Location().Y() + ClientTop());
 }
 
 LayoutUnit LayoutBox::ScrollWidth() const {
+  CheckIsNotDestroyed();
   if (IsScrollContainer() || StyleRef().ScrollbarGutterIsForce())
     return GetScrollableArea()->ScrollWidth();
   // For objects with visible overflow, this matches IE.
@@ -849,6 +874,7 @@
 }
 
 LayoutUnit LayoutBox::ScrollHeight() const {
+  CheckIsNotDestroyed();
   if (IsScrollContainer() || StyleRef().ScrollbarGutterIsForce())
     return GetScrollableArea()->ScrollHeight();
   // For objects with visible overflow, this matches IE.
@@ -857,10 +883,12 @@
 }
 
 int LayoutBox::PixelSnappedScrollWidth() const {
+  CheckIsNotDestroyed();
   return SnapSizeToPixel(ScrollWidth(), Location().X() + ClientLeft());
 }
 
 int LayoutBox::PixelSnappedScrollHeight() const {
+  CheckIsNotDestroyed();
   if (IsScrollContainer())
     return SnapSizeToPixel(GetScrollableArea()->ScrollHeight(),
                            Location().Y() + ClientTop());
@@ -872,6 +900,7 @@
 PhysicalRect LayoutBox::ScrollRectToVisibleRecursive(
     const PhysicalRect& absolute_rect,
     mojom::blink::ScrollIntoViewParamsPtr params) {
+  CheckIsNotDestroyed();
   DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
          params->type == mojom::blink::ScrollType::kUser);
 
@@ -951,6 +980,7 @@
 }
 
 void LayoutBox::SetMargin(const NGPhysicalBoxStrut& box) {
+  CheckIsNotDestroyed();
   margin_box_outsets_.SetTop(box.top);
   margin_box_outsets_.SetRight(box.right);
   margin_box_outsets_.SetBottom(box.bottom);
@@ -959,6 +989,7 @@
 
 void LayoutBox::AbsoluteQuads(Vector<FloatQuad>& quads,
                               MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   if (LayoutFlowThread* flow_thread = FlowThreadContainingBlock()) {
     flow_thread->AbsoluteQuadsForDescendant(*this, quads, mode);
     return;
@@ -967,11 +998,13 @@
 }
 
 FloatRect LayoutBox::LocalBoundingBoxRectForAccessibility() const {
+  CheckIsNotDestroyed();
   return FloatRect(0, 0, frame_rect_.Width().ToFloat(),
                    frame_rect_.Height().ToFloat());
 }
 
 void LayoutBox::UpdateAfterLayout() {
+  CheckIsNotDestroyed();
   // Transform-origin depends on box size, so we need to update the layer
   // transform after layout.
   if (HasLayer()) {
@@ -997,6 +1030,7 @@
 }
 
 bool LayoutBox::HasOverrideIntrinsicContentWidth() const {
+  CheckIsNotDestroyed();
   if (!ShouldApplySizeContainment())
     return false;
 
@@ -1005,6 +1039,7 @@
 }
 
 bool LayoutBox::HasOverrideIntrinsicContentHeight() const {
+  CheckIsNotDestroyed();
   if (!ShouldApplySizeContainment())
     return false;
 
@@ -1013,6 +1048,7 @@
 }
 
 LayoutUnit LayoutBox::OverrideIntrinsicContentWidth() const {
+  CheckIsNotDestroyed();
   DCHECK(HasOverrideIntrinsicContentWidth());
   const auto& style = StyleRef();
   const Length& intrinsic_length = style.ContainIntrinsicSize().Width();
@@ -1023,6 +1059,7 @@
 }
 
 LayoutUnit LayoutBox::OverrideIntrinsicContentHeight() const {
+  CheckIsNotDestroyed();
   DCHECK(HasOverrideIntrinsicContentHeight());
   const auto& style = StyleRef();
   const Length& intrinsic_length = style.ContainIntrinsicSize().Height();
@@ -1033,6 +1070,7 @@
 }
 
 LayoutUnit LayoutBox::DefaultIntrinsicContentInlineSize() const {
+  CheckIsNotDestroyed();
   // If the intrinsic-inline-size is specified, then we shouldn't ever need to
   // get here.
   DCHECK(!HasOverrideIntrinsicContentLogicalWidth());
@@ -1060,6 +1098,7 @@
 }
 
 LayoutUnit LayoutBox::DefaultIntrinsicContentBlockSize() const {
+  CheckIsNotDestroyed();
   // If the intrinsic-block-size is specified, then we shouldn't ever need to
   // get here.
   DCHECK(!HasOverrideIntrinsicContentLogicalHeight());
@@ -1076,6 +1115,7 @@
 }
 
 LayoutUnit LayoutBox::LogicalHeightWithVisibleOverflow() const {
+  CheckIsNotDestroyed();
   if (!LayoutOverflowIsSet() || IsScrollContainer() ||
       StyleRef().OverflowY() == EOverflow::kClip)
     return LogicalHeight();
@@ -1089,6 +1129,7 @@
     LayoutUnit logical_width,
     LayoutUnit available_width,
     const LayoutBlock* cb) const {
+  CheckIsNotDestroyed();
   const ComputedStyle& style_to_use = StyleRef();
 
   // This implements the transferred min/max sizes per
@@ -1122,6 +1163,7 @@
 LayoutUnit LayoutBox::ConstrainLogicalHeightByMinMax(
     LayoutUnit logical_height,
     LayoutUnit intrinsic_content_height) const {
+  CheckIsNotDestroyed();
   // Note that the values 'min-content', 'max-content' and 'fit-content' should
   // behave as the initial value if specified in the block direction.
   const Length& logical_max_height = StyleRef().LogicalMaxHeight();
@@ -1152,6 +1194,7 @@
 LayoutUnit LayoutBox::ConstrainContentBoxLogicalHeightByMinMax(
     LayoutUnit logical_height,
     LayoutUnit intrinsic_content_height) const {
+  CheckIsNotDestroyed();
   // If the min/max height and logical height are both percentages we take
   // advantage of already knowing the current resolved percentage height
   // to avoid recursing up through our containing blocks again to determine it.
@@ -1191,6 +1234,7 @@
 
 void LayoutBox::SetLocationAndUpdateOverflowControlsIfNeeded(
     const LayoutPoint& location) {
+  CheckIsNotDestroyed();
   if (!HasLayer()) {
     SetLocation(location);
     return;
@@ -1216,12 +1260,14 @@
 }
 
 FloatQuad LayoutBox::AbsoluteContentQuad(MapCoordinatesFlags flags) const {
+  CheckIsNotDestroyed();
   PhysicalRect rect = PhysicalContentBoxRect();
   return LocalRectToAbsoluteQuad(rect, flags);
 }
 
 PhysicalRect LayoutBox::PhysicalBackgroundRect(
     BackgroundRectType rect_type) const {
+  CheckIsNotDestroyed();
   // If the background transfers to view, the used background of this object
   // is transparent.
   if (rect_type == kBackgroundKnownOpaqueRect && BackgroundTransfersToView())
@@ -1295,10 +1341,12 @@
 void LayoutBox::AddOutlineRects(Vector<PhysicalRect>& rects,
                                 const PhysicalOffset& additional_offset,
                                 NGOutlineType) const {
+  CheckIsNotDestroyed();
   rects.emplace_back(additional_offset, Size());
 }
 
 bool LayoutBox::CanResize() const {
+  CheckIsNotDestroyed();
   // We need a special case for <iframe> because they never have
   // hasOverflowClip(). However, they do "implicitly" clip their contents, so
   // we want to allow resizing them also.
@@ -1306,6 +1354,7 @@
 }
 
 MinMaxSizes LayoutBox::ComputeMinMaxLogicalWidthFromAspectRatio() const {
+  CheckIsNotDestroyed();
   DCHECK(StyleRef().LogicalAspectRatio());
 
   // The spec requires us to clamp these by the specified size (it calls it the
@@ -1344,6 +1393,7 @@
 }
 
 bool LayoutBox::HasScrollbarGutters(ScrollbarOrientation orientation) const {
+  CheckIsNotDestroyed();
   if (StyleRef().ScrollbarGutterIsAuto())
     return false;
 
@@ -1371,6 +1421,7 @@
 NGPhysicalBoxStrut LayoutBox::ComputeScrollbarsInternal(
     ShouldClampToContentBox clamp_to_content_box,
     OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior) const {
+  CheckIsNotDestroyed();
   NGPhysicalBoxStrut scrollbars;
   PaintLayerScrollableArea* scrollable_area = GetScrollableArea();
   if (!scrollable_area)
@@ -1424,12 +1475,14 @@
 }
 
 bool LayoutBox::CanBeScrolledAndHasScrollableArea() const {
+  CheckIsNotDestroyed();
   return CanBeProgramaticallyScrolled() &&
          (PixelSnappedScrollHeight() != PixelSnappedClientHeight() ||
           PixelSnappedScrollWidth() != PixelSnappedClientWidth());
 }
 
 bool LayoutBox::CanBeProgramaticallyScrolled() const {
+  CheckIsNotDestroyed();
   Node* node = GetNode();
   if (node && node->IsDocumentNode())
     return true;
@@ -1446,6 +1499,7 @@
 }
 
 void LayoutBox::Autoscroll(const PhysicalOffset& position_in_root_frame) {
+  CheckIsNotDestroyed();
   LocalFrame* frame = GetFrame();
   if (!frame)
     return;
@@ -1465,6 +1519,7 @@
 }
 
 bool LayoutBox::CanAutoscroll() const {
+  CheckIsNotDestroyed();
   // TODO(skobes): Remove one of these methods.
   return CanBeScrolledAndHasScrollableArea();
 }
@@ -1474,6 +1529,7 @@
 // direction of scrolling.
 PhysicalOffset LayoutBox::CalculateAutoscrollDirection(
     const FloatPoint& point_in_root_frame) const {
+  CheckIsNotDestroyed();
   if (!GetFrame())
     return PhysicalOffset();
 
@@ -1532,6 +1588,7 @@
 }
 
 void LayoutBox::ScrollByRecursively(const ScrollOffset& delta) {
+  CheckIsNotDestroyed();
   if (delta.IsZero() || !IsScrollContainer())
     return;
 
@@ -1562,11 +1619,13 @@
 }
 
 bool LayoutBox::NeedsPreferredWidthsRecalculation() const {
+  CheckIsNotDestroyed();
   return StyleRef().PaddingStart().IsPercentOrCalc() ||
          StyleRef().PaddingEnd().IsPercentOrCalc();
 }
 
 IntSize LayoutBox::OriginAdjustmentForScrollbars() const {
+  CheckIsNotDestroyed();
   if (CanSkipComputeScrollbars()) {
     return IntSize();
   } else {
@@ -1577,22 +1636,26 @@
 }
 
 IntPoint LayoutBox::ScrollOrigin() const {
+  CheckIsNotDestroyed();
   return GetScrollableArea() ? GetScrollableArea()->ScrollOrigin() : IntPoint();
 }
 
 LayoutSize LayoutBox::ScrolledContentOffset() const {
+  CheckIsNotDestroyed();
   DCHECK(IsScrollContainer());
   DCHECK(GetScrollableArea());
   return LayoutSize(GetScrollableArea()->GetScrollOffset());
 }
 
 LayoutSize LayoutBox::PixelSnappedScrolledContentOffset() const {
+  CheckIsNotDestroyed();
   DCHECK(IsScrollContainer());
   DCHECK(GetScrollableArea());
   return LayoutSize(GetScrollableArea()->ScrollOffsetInt());
 }
 
 PhysicalRect LayoutBox::ClippingRect(const PhysicalOffset& location) const {
+  CheckIsNotDestroyed();
   PhysicalRect result(PhysicalRect::InfiniteIntRect());
   if (ShouldClipOverflow())
     result = OverflowClipRect(location);
@@ -1609,6 +1672,7 @@
     const LayoutObject* ancestor,
     VisualRectFlags visual_rect_flags,
     TransformState& transform_state) const {
+  CheckIsNotDestroyed();
   bool container_preserve_3d = container_object->StyleRef().Preserves3D();
 
   TransformState::TransformAccumulation accumulation =
@@ -1708,6 +1772,7 @@
     TransformState::TransformAccumulation accumulation,
     const LayoutObject& contents,
     VisualRectFlags visual_rect_flags) const {
+  CheckIsNotDestroyed();
   if (!HasClipRelatedProperty())
     return true;
 
@@ -1718,6 +1783,7 @@
 }
 
 bool LayoutBox::ContainedContentsScroll(const LayoutObject& contents) const {
+  CheckIsNotDestroyed();
   if (IsA<LayoutView>(this) &&
       contents.StyleRef().GetPosition() == EPosition::kFixed) {
     return false;
@@ -1729,6 +1795,7 @@
     TransformState& transform_state,
     TransformState::TransformAccumulation accumulation,
     VisualRectFlags visual_rect_flags) const {
+  CheckIsNotDestroyed();
   // This won't work fully correctly for fixed-position elements, who should
   // receive CSS clip but for whom the current object is not in the containing
   // block chain.
@@ -1749,11 +1816,13 @@
 }
 
 MinMaxSizes LayoutBox::PreferredLogicalWidths() const {
+  CheckIsNotDestroyed();
   NOTREACHED();
   return MinMaxSizes();
 }
 
 MinMaxSizes LayoutBox::IntrinsicLogicalWidths(MinMaxSizesType type) const {
+  CheckIsNotDestroyed();
   if (type == MinMaxSizesType::kContent && StyleRef().AspectRatio()) {
     MinMaxSizes sizes;
     if (ComputeLogicalWidthFromAspectRatio(&sizes.min_size)) {
@@ -1766,6 +1835,7 @@
 }
 
 void LayoutBox::UpdateCachedIntrinsicLogicalWidthsIfNeeded() {
+  CheckIsNotDestroyed();
   if (!IntrinsicLogicalWidthsDirty())
     return;
 
@@ -1780,6 +1850,7 @@
 }
 
 LayoutUnit LayoutBox::OverrideLogicalWidth() const {
+  CheckIsNotDestroyed();
   DCHECK(HasOverrideLogicalWidth());
   if (extra_input_ && extra_input_->override_inline_size)
     return *extra_input_->override_inline_size;
@@ -1787,6 +1858,7 @@
 }
 
 LayoutUnit LayoutBox::OverrideLogicalHeight() const {
+  CheckIsNotDestroyed();
   DCHECK(HasOverrideLogicalHeight());
   if (extra_input_ && extra_input_->override_block_size)
     return *extra_input_->override_block_size;
@@ -1794,63 +1866,74 @@
 }
 
 bool LayoutBox::IsOverrideLogicalHeightDefinite() const {
+  CheckIsNotDestroyed();
   return extra_input_ && extra_input_->is_override_block_size_definite;
 }
 
 bool LayoutBox::HasOverrideLogicalHeight() const {
+  CheckIsNotDestroyed();
   if (extra_input_ && extra_input_->override_block_size)
     return true;
   return rare_data_ && rare_data_->override_logical_height_ != -1;
 }
 
 bool LayoutBox::HasOverrideLogicalWidth() const {
+  CheckIsNotDestroyed();
   if (extra_input_ && extra_input_->override_inline_size)
     return true;
   return rare_data_ && rare_data_->override_logical_width_ != -1;
 }
 
 void LayoutBox::SetOverrideLogicalHeight(LayoutUnit height) {
+  CheckIsNotDestroyed();
   DCHECK(!extra_input_);
   DCHECK_GE(height, 0);
   EnsureRareData().override_logical_height_ = height;
 }
 
 void LayoutBox::SetOverrideLogicalWidth(LayoutUnit width) {
+  CheckIsNotDestroyed();
   DCHECK(!extra_input_);
   DCHECK_GE(width, 0);
   EnsureRareData().override_logical_width_ = width;
 }
 
 void LayoutBox::ClearOverrideLogicalHeight() {
+  CheckIsNotDestroyed();
   DCHECK(!extra_input_);
   if (rare_data_)
     rare_data_->override_logical_height_ = LayoutUnit(-1);
 }
 
 void LayoutBox::ClearOverrideLogicalWidth() {
+  CheckIsNotDestroyed();
   DCHECK(!extra_input_);
   if (rare_data_)
     rare_data_->override_logical_width_ = LayoutUnit(-1);
 }
 
 void LayoutBox::ClearOverrideSize() {
+  CheckIsNotDestroyed();
   ClearOverrideLogicalHeight();
   ClearOverrideLogicalWidth();
 }
 
 LayoutUnit LayoutBox::OverrideContentLogicalWidth() const {
+  CheckIsNotDestroyed();
   return (OverrideLogicalWidth() - BorderAndPaddingLogicalWidth() -
           ComputeLogicalScrollbars().InlineSum())
       .ClampNegativeToZero();
 }
 
 LayoutUnit LayoutBox::OverrideContentLogicalHeight() const {
+  CheckIsNotDestroyed();
   return (OverrideLogicalHeight() - BorderAndPaddingLogicalHeight() -
           ComputeLogicalScrollbars().BlockSum())
       .ClampNegativeToZero();
 }
 
 LayoutUnit LayoutBox::OverrideContainingBlockContentWidth() const {
+  CheckIsNotDestroyed();
   DCHECK(HasOverrideContainingBlockContentWidth());
   return ContainingBlock()->StyleRef().IsHorizontalWritingMode()
              ? OverrideContainingBlockContentLogicalWidth()
@@ -1858,6 +1941,7 @@
 }
 
 LayoutUnit LayoutBox::OverrideContainingBlockContentHeight() const {
+  CheckIsNotDestroyed();
   DCHECK(HasOverrideContainingBlockContentHeight());
   return ContainingBlock()->StyleRef().IsHorizontalWritingMode()
              ? OverrideContainingBlockContentLogicalHeight()
@@ -1865,6 +1949,7 @@
 }
 
 bool LayoutBox::HasOverrideContainingBlockContentWidth() const {
+  CheckIsNotDestroyed();
   if (!ContainingBlock())
     return false;
 
@@ -1874,6 +1959,7 @@
 }
 
 bool LayoutBox::HasOverrideContainingBlockContentHeight() const {
+  CheckIsNotDestroyed();
   if (!ContainingBlock())
     return false;
 
@@ -1885,6 +1971,7 @@
 // TODO (lajava) Shouldn't we implement these functions based on physical
 // direction ?.
 LayoutUnit LayoutBox::OverrideContainingBlockContentLogicalWidth() const {
+  CheckIsNotDestroyed();
   DCHECK(HasOverrideContainingBlockContentLogicalWidth());
   if (extra_input_)
     return extra_input_->containing_block_content_inline_size;
@@ -1894,6 +1981,7 @@
 // TODO (lajava) Shouldn't we implement these functions based on physical
 // direction ?.
 LayoutUnit LayoutBox::OverrideContainingBlockContentLogicalHeight() const {
+  CheckIsNotDestroyed();
   DCHECK(HasOverrideContainingBlockContentLogicalHeight());
   if (extra_input_)
     return extra_input_->containing_block_content_block_size;
@@ -1903,6 +1991,7 @@
 // TODO (lajava) Shouldn't we implement these functions based on physical
 // direction ?.
 bool LayoutBox::HasOverrideContainingBlockContentLogicalWidth() const {
+  CheckIsNotDestroyed();
   if (extra_input_)
     return true;
   return rare_data_ &&
@@ -1912,6 +2001,7 @@
 // TODO (lajava) Shouldn't we implement these functions based on physical
 // direction ?.
 bool LayoutBox::HasOverrideContainingBlockContentLogicalHeight() const {
+  CheckIsNotDestroyed();
   if (extra_input_)
     return true;
   return rare_data_ &&
@@ -1922,6 +2012,7 @@
 // direction ?.
 void LayoutBox::SetOverrideContainingBlockContentLogicalWidth(
     LayoutUnit logical_width) {
+  CheckIsNotDestroyed();
   DCHECK(!extra_input_);
   DCHECK_GE(logical_width, LayoutUnit(-1));
   EnsureRareData().override_containing_block_content_logical_width_ =
@@ -1933,6 +2024,7 @@
 // direction ?.
 void LayoutBox::SetOverrideContainingBlockContentLogicalHeight(
     LayoutUnit logical_height) {
+  CheckIsNotDestroyed();
   DCHECK(!extra_input_);
   DCHECK_GE(logical_height, LayoutUnit(-1));
   EnsureRareData().override_containing_block_content_logical_height_ =
@@ -1943,6 +2035,7 @@
 // TODO (lajava) Shouldn't we implement these functions based on physical
 // direction ?.
 void LayoutBox::ClearOverrideContainingBlockContentSize() {
+  CheckIsNotDestroyed();
   DCHECK(!extra_input_);
   if (!rare_data_)
     return;
@@ -1952,17 +2045,20 @@
 }
 
 LayoutUnit LayoutBox::OverridePercentageResolutionBlockSize() const {
+  CheckIsNotDestroyed();
   DCHECK(HasOverridePercentageResolutionBlockSize());
   return rare_data_->override_percentage_resolution_block_size_;
 }
 
 bool LayoutBox::HasOverridePercentageResolutionBlockSize() const {
+  CheckIsNotDestroyed();
   return rare_data_ &&
          rare_data_->has_override_percentage_resolution_block_size_;
 }
 
 void LayoutBox::SetOverridePercentageResolutionBlockSize(
     LayoutUnit logical_height) {
+  CheckIsNotDestroyed();
   DCHECK_GE(logical_height, LayoutUnit(-1));
   auto& rare_data = EnsureRareData();
   rare_data.override_percentage_resolution_block_size_ = logical_height;
@@ -1970,12 +2066,14 @@
 }
 
 void LayoutBox::ClearOverridePercentageResolutionBlockSize() {
+  CheckIsNotDestroyed();
   if (!rare_data_)
     return;
   EnsureRareData().has_override_percentage_resolution_block_size_ = false;
 }
 
 LayoutUnit LayoutBox::OverrideAvailableInlineSize() const {
+  CheckIsNotDestroyed();
   DCHECK(HasOverrideAvailableInlineSize());
   if (extra_input_)
     return extra_input_->available_inline_size;
@@ -1984,6 +2082,7 @@
 
 LayoutUnit LayoutBox::AdjustBorderBoxLogicalWidthForBoxSizing(
     float width) const {
+  CheckIsNotDestroyed();
   LayoutUnit borders_plus_padding = CollapsedBorderAndCSSPaddingLogicalWidth();
   LayoutUnit result(width);
   if (StyleRef().BoxSizing() == EBoxSizing::kContentBox)
@@ -1993,6 +2092,7 @@
 
 LayoutUnit LayoutBox::AdjustBorderBoxLogicalHeightForBoxSizing(
     float height) const {
+  CheckIsNotDestroyed();
   LayoutUnit borders_plus_padding = CollapsedBorderAndCSSPaddingLogicalHeight();
   LayoutUnit result(height);
   if (StyleRef().BoxSizing() == EBoxSizing::kContentBox)
@@ -2002,6 +2102,7 @@
 
 LayoutUnit LayoutBox::AdjustContentBoxLogicalWidthForBoxSizing(
     float width) const {
+  CheckIsNotDestroyed();
   LayoutUnit result(width);
   if (StyleRef().BoxSizing() == EBoxSizing::kBorderBox)
     result -= CollapsedBorderAndCSSPaddingLogicalWidth();
@@ -2010,6 +2111,7 @@
 
 LayoutUnit LayoutBox::AdjustContentBoxLogicalHeightForBoxSizing(
     float height) const {
+  CheckIsNotDestroyed();
   LayoutUnit result(height);
   if (StyleRef().BoxSizing() == EBoxSizing::kBorderBox)
     result -= CollapsedBorderAndCSSPaddingLogicalHeight();
@@ -2021,6 +2123,7 @@
                                  const HitTestLocation& hit_test_location,
                                  const PhysicalOffset& accumulated_offset,
                                  HitTestFilter hit_test_filter) {
+  CheckIsNotDestroyed();
   // Check if we need to do anything at all.
   // If we have clipping, then we can't have any spillout.
   // TODO(pdr): Why is this optimization not valid for the effective root?
@@ -2048,6 +2151,7 @@
                             const HitTestLocation& hit_test_location,
                             const PhysicalOffset& accumulated_offset,
                             HitTestAction action) {
+  CheckIsNotDestroyed();
   bool should_hit_test_self = IsInSelfHitTestingPhase(action);
 
   if (should_hit_test_self && IsScrollContainer() &&
@@ -2110,6 +2214,7 @@
                                 const HitTestLocation& hit_test_location,
                                 const PhysicalOffset& accumulated_offset,
                                 HitTestAction action) {
+  CheckIsNotDestroyed();
   for (LayoutObject* child = SlowLastChild(); child;
        child = child->PreviousSibling()) {
     if (child->HasLayer() &&
@@ -2131,6 +2236,7 @@
 bool LayoutBox::HitTestClippedOutByBorder(
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& border_box_location) const {
+  CheckIsNotDestroyed();
   PhysicalRect border_rect = PhysicalBorderBoxRect();
   border_rect.Move(border_box_location);
   return !hit_test_location.Intersects(
@@ -2139,16 +2245,19 @@
 }
 
 void LayoutBox::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   BoxPainter(*this).Paint(paint_info);
 }
 
 void LayoutBox::PaintBoxDecorationBackground(
     const PaintInfo& paint_info,
     const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   BoxPainter(*this).PaintBoxDecorationBackground(paint_info, paint_offset);
 }
 
 bool LayoutBox::GetBackgroundPaintedExtent(PhysicalRect& painted_extent) const {
+  CheckIsNotDestroyed();
   DCHECK(StyleRef().HasBackground());
 
   // LayoutView is special in the sense that it expands to the whole canvas,
@@ -2184,6 +2293,7 @@
 
 bool LayoutBox::BackgroundIsKnownToBeOpaqueInRect(
     const PhysicalRect& local_rect) const {
+  CheckIsNotDestroyed();
   // If the element has appearance, it might be painted by theme.
   // We cannot be sure if theme paints the background opaque.
   // In this case it is safe to not assume opaqueness.
@@ -2206,6 +2316,7 @@
 // TODO(wangxianzhu): The current rules are very basic. May use more complex
 // rules if they can improve LCD text.
 bool LayoutBox::TextIsKnownToBeOnOpaqueBackground() const {
+  CheckIsNotDestroyed();
   // Text may overflow the background area.
   if (!ShouldClipOverflow())
     return false;
@@ -2234,6 +2345,7 @@
 bool LayoutBox::ForegroundIsKnownToBeOpaqueInRect(
     const PhysicalRect& local_rect,
     unsigned max_depth_to_test) const {
+  CheckIsNotDestroyed();
   if (!max_depth_to_test)
     return false;
   for (LayoutObject* child = SlowFirstChild(); child;
@@ -2266,6 +2378,7 @@
 
 DISABLE_CFI_PERF
 bool LayoutBox::ComputeBackgroundIsKnownToBeObscured() const {
+  CheckIsNotDestroyed();
   if (ScrollsOverflow())
     return false;
   // Test to see if the children trivially obscure the background.
@@ -2285,11 +2398,13 @@
 
 void LayoutBox::PaintMask(const PaintInfo& paint_info,
                           const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   BoxPainter(*this).PaintMask(paint_info, paint_offset);
 }
 
 void LayoutBox::ImageChanged(WrappedImagePtr image,
                              CanDeferInvalidation defer) {
+  CheckIsNotDestroyed();
   bool is_box_reflect_image =
       (StyleRef().BoxReflect() && StyleRef().BoxReflect()->Mask().GetImage() &&
        StyleRef().BoxReflect()->Mask().GetImage()->Data() == image);
@@ -2349,6 +2464,7 @@
 }
 
 ResourcePriority LayoutBox::ComputeResourcePriority() const {
+  CheckIsNotDestroyed();
   PhysicalRect view_bounds = ViewRect();
   PhysicalRect object_bounds = PhysicalContentBoxRect();
   // TODO(japhet): Is this IgnoreTransforms correct? Would it be better to use
@@ -2379,6 +2495,7 @@
 }
 
 void LayoutBox::LocationChanged() {
+  CheckIsNotDestroyed();
   // The location may change because of layout of other objects. Should check
   // this object for paint invalidation.
   if (!NeedsLayout())
@@ -2386,6 +2503,7 @@
 }
 
 void LayoutBox::SizeChanged() {
+  CheckIsNotDestroyed();
   // The size may change because of layout of other objects. Should check this
   // object for paint invalidation.
   if (!NeedsLayout())
@@ -2393,6 +2511,7 @@
 }
 
 bool LayoutBox::IntersectsVisibleViewport() const {
+  CheckIsNotDestroyed();
   PhysicalRect rect = PhysicalVisualOverflowRect();
   LayoutView* layout_view = View();
   while (layout_view->GetFrame()->OwnerLayoutObject())
@@ -2403,6 +2522,7 @@
 }
 
 void LayoutBox::EnsureIsReadyForPaintInvalidation() {
+  CheckIsNotDestroyed();
   LayoutBoxModelObject::EnsureIsReadyForPaintInvalidation();
 
   bool new_obscured = ComputeBackgroundIsKnownToBeObscured();
@@ -2429,6 +2549,7 @@
 }
 
 void LayoutBox::InvalidatePaintRectangle(const PhysicalRect& dirty_rect) {
+  CheckIsNotDestroyed();
   DCHECK_NE(GetDocument().Lifecycle().GetState(), DocumentLifecycle::kInPaint);
 
   if (dirty_rect.IsEmpty())
@@ -2439,11 +2560,13 @@
 }
 
 void LayoutBox::ClearPartialInvalidationVisualRect() const {
+  CheckIsNotDestroyed();
   if (rare_data_)
     rare_data_->partial_invalidation_rect_ = PhysicalRect();
 }
 
 IntRect LayoutBox::PartialInvalidationVisualRect() const {
+  CheckIsNotDestroyed();
   if (!rare_data_)
     return IntRect();
   PhysicalRect rect = rare_data_->partial_invalidation_rect_;
@@ -2454,10 +2577,12 @@
 }
 
 void LayoutBox::InvalidatePaint(const PaintInvalidatorContext& context) const {
+  CheckIsNotDestroyed();
   BoxPaintInvalidator(*this, context).InvalidatePaint();
 }
 
 void LayoutBox::ClearPaintFlags() {
+  CheckIsNotDestroyed();
   LayoutObject::ClearPaintFlags();
 
   if (auto* scrollable_area = GetScrollableArea()) {
@@ -2473,6 +2598,7 @@
 PhysicalRect LayoutBox::OverflowClipRect(
     const PhysicalOffset& location,
     OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior) const {
+  CheckIsNotDestroyed();
   PhysicalRect clip_rect;
 
   if (IsEffectiveRootScroller()) {
@@ -2516,6 +2642,7 @@
 }
 
 bool LayoutBox::HasControlClip() const {
+  CheckIsNotDestroyed();
   return UNLIKELY(IsTextField() || IsFileUploadControl() || IsMenuList(this) ||
                   (IsButtonOrNGButton() && IsA<HTMLInputElement>(GetNode())));
 }
@@ -2523,6 +2650,7 @@
 void LayoutBox::ExcludeScrollbars(
     PhysicalRect& rect,
     OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior) const {
+  CheckIsNotDestroyed();
   if (CanSkipComputeScrollbars())
     return;
 
@@ -2536,6 +2664,7 @@
 }
 
 PhysicalRect LayoutBox::ClipRect(const PhysicalOffset& location) const {
+  CheckIsNotDestroyed();
   PhysicalRect clip_rect(location, Size());
   LayoutUnit width = Size().Width();
   LayoutUnit height = Size().Height();
@@ -2580,6 +2709,7 @@
     LayoutUnit child_margin_start,
     LayoutUnit child_margin_end,
     const LayoutBlockFlow* cb) const {
+  CheckIsNotDestroyed();
   LayoutUnit logical_top_position = LogicalTop();
   LayoutUnit start_offset_for_content = cb->StartOffsetForContent();
   LayoutUnit end_offset_for_content = cb->EndOffsetForContent();
@@ -2622,6 +2752,7 @@
 }
 
 LayoutUnit LayoutBox::ContainingBlockLogicalHeightForGetComputedStyle() const {
+  CheckIsNotDestroyed();
   if (HasOverrideContainingBlockContentLogicalHeight())
     return OverrideContainingBlockContentLogicalHeight();
 
@@ -2637,6 +2768,7 @@
 }
 
 LayoutUnit LayoutBox::ContainingBlockLogicalWidthForContent() const {
+  CheckIsNotDestroyed();
   if (HasOverrideContainingBlockContentLogicalWidth())
     return OverrideContainingBlockContentLogicalWidth();
 
@@ -2648,6 +2780,7 @@
 
 LayoutUnit LayoutBox::ContainingBlockLogicalHeightForContent(
     AvailableLogicalHeightType height_type) const {
+  CheckIsNotDestroyed();
   if (HasOverrideContainingBlockContentLogicalHeight())
     return OverrideContainingBlockContentLogicalHeight();
 
@@ -2656,6 +2789,7 @@
 }
 
 LayoutUnit LayoutBox::ContainingBlockAvailableLineWidth() const {
+  CheckIsNotDestroyed();
   LayoutBlock* cb = ContainingBlock();
   auto* child_block_flow = DynamicTo<LayoutBlockFlow>(cb);
   if (child_block_flow) {
@@ -2666,6 +2800,7 @@
 }
 
 LayoutUnit LayoutBox::PerpendicularContainingBlockLogicalHeight() const {
+  CheckIsNotDestroyed();
   if (HasOverrideContainingBlockContentLogicalHeight())
     return OverrideContainingBlockContentLogicalHeight();
 
@@ -2698,6 +2833,7 @@
 void LayoutBox::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                                    TransformState& transform_state,
                                    MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   bool is_fixed_pos = StyleRef().GetPosition() == EPosition::kFixed;
 
   // If this box has a transform or contains paint, it acts as a fixed position
@@ -2714,6 +2850,7 @@
 void LayoutBox::MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
                                    TransformState& transform_state,
                                    MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   if (this == ancestor)
     return;
 
@@ -2733,6 +2870,7 @@
 PhysicalOffset LayoutBox::OffsetFromContainerInternal(
     const LayoutObject* o,
     bool ignore_scroll_offset) const {
+  CheckIsNotDestroyed();
   DCHECK_EQ(o, Container());
 
   PhysicalOffset offset;
@@ -2753,10 +2891,12 @@
 }
 
 InlineBox* LayoutBox::CreateInlineBox() {
+  CheckIsNotDestroyed();
   return new InlineBox(LineLayoutItem(this));
 }
 
 void LayoutBox::DirtyLineBoxes(bool full_layout) {
+  CheckIsNotDestroyed();
   if (!IsInLayoutNGInlineFormattingContext() && inline_box_wrapper_) {
     if (full_layout) {
       inline_box_wrapper_->Destroy();
@@ -2768,6 +2908,7 @@
 }
 
 bool LayoutBox::HasInlineFragments() const {
+  CheckIsNotDestroyed();
   if (!IsInLayoutNGInlineFormattingContext())
     return inline_box_wrapper_;
   if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
@@ -2776,18 +2917,21 @@
 }
 
 void LayoutBox::SetFirstInlineFragment(NGPaintFragment* fragment) {
+  CheckIsNotDestroyed();
   CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
   DCHECK(!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
   first_paint_fragment_ = fragment;
 }
 
 void LayoutBox::ClearFirstInlineFragmentItemIndex() {
+  CheckIsNotDestroyed();
   CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
   DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
   first_fragment_item_index_ = 0u;
 }
 
 void LayoutBox::SetFirstInlineFragmentItemIndex(wtf_size_t index) {
+  CheckIsNotDestroyed();
   CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
   DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
   DCHECK_NE(index, 0u);
@@ -2795,6 +2939,7 @@
 }
 
 void LayoutBox::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
       SetFirstInlineFragment(nullptr);
@@ -2823,6 +2968,7 @@
 
 void LayoutBox::SetCachedLayoutResult(
     scoped_refptr<const NGLayoutResult> result) {
+  CheckIsNotDestroyed();
   DCHECK(!result->PhysicalFragment().BreakToken());
   DCHECK(!result->IsSingleUse());
 
@@ -2847,6 +2993,7 @@
 
 void LayoutBox::AddLayoutResult(scoped_refptr<const NGLayoutResult> result,
                                 wtf_size_t index) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess);
   if (index != WTF::kNotFound && layout_results_.size() > index) {
     if (layout_results_.size() > index + 1)
@@ -2868,6 +3015,7 @@
 
 void LayoutBox::ReplaceLayoutResult(scoped_refptr<const NGLayoutResult> result,
                                     wtf_size_t index) {
+  CheckIsNotDestroyed();
   DCHECK_LE(index, layout_results_.size());
   const NGLayoutResult* old_result = layout_results_[index].get();
   if (old_result == result.get())
@@ -2901,6 +3049,7 @@
 }
 
 void LayoutBox::ClearLayoutResults() {
+  CheckIsNotDestroyed();
   if (measure_result_)
     InvalidateItems(*measure_result_);
   measure_result_ = nullptr;
@@ -2909,6 +3058,7 @@
 }
 
 void LayoutBox::ShrinkLayoutResults(wtf_size_t results_to_keep) {
+  CheckIsNotDestroyed();
   DCHECK_GE(layout_results_.size(), results_to_keep);
   // Invalidate if inline |DisplayItemClient|s will be destroyed.
   for (wtf_size_t i = results_to_keep; i < layout_results_.size(); i++)
@@ -2923,6 +3073,7 @@
 }
 
 void LayoutBox::InvalidateItems(const NGLayoutResult& result) {
+  CheckIsNotDestroyed();
   // Invalidate if inline |DisplayItemClient|s will be destroyed.
   const auto& box_fragment =
       To<NGPhysicalBoxFragment>(result.PhysicalFragment());
@@ -2939,6 +3090,7 @@
 }
 
 const NGLayoutResult* LayoutBox::GetCachedLayoutResult() const {
+  CheckIsNotDestroyed();
   if (layout_results_.IsEmpty())
     return nullptr;
   // Only return re-usable results.
@@ -2952,6 +3104,7 @@
 }
 
 const NGLayoutResult* LayoutBox::GetCachedMeasureResult() const {
+  CheckIsNotDestroyed();
   if (!measure_result_)
     return nullptr;
 
@@ -2967,6 +3120,7 @@
     const NGEarlyBreak* early_break,
     base::Optional<NGFragmentGeometry>* initial_fragment_geometry,
     NGLayoutCacheStatus* out_cache_status) {
+  CheckIsNotDestroyed();
   *out_cache_status = NGLayoutCacheStatus::kNeedsLayout;
 
   const bool use_layout_cache_slot =
@@ -3194,6 +3348,7 @@
 
 const NGPhysicalBoxFragment* LayoutBox::GetPhysicalFragment(
     wtf_size_t index) const {
+  CheckIsNotDestroyed();
   return &To<NGPhysicalBoxFragment>(layout_results_[index]->PhysicalFragment());
 }
 
@@ -3204,6 +3359,7 @@
 
 const FragmentData* LayoutBox::FragmentDataFromPhysicalFragment(
     const NGPhysicalBoxFragment& physical_fragment) const {
+  CheckIsNotDestroyed();
   const FragmentData* fragment_data = &FirstFragment();
   for (const auto& result : layout_results_) {
     if (&result->PhysicalFragment() == &physical_fragment)
@@ -3216,6 +3372,7 @@
 }
 
 void LayoutBox::PositionLineBox(InlineBox* box) {
+  CheckIsNotDestroyed();
   if (IsOutOfFlowPositioned()) {
     // Cache the x position only if we were an INLINE type originally.
     bool originally_inline = StyleRef().IsOriginalDisplayInlineType();
@@ -3247,6 +3404,7 @@
 }
 
 void LayoutBox::MoveWithEdgeOfInlineContainerIfNecessary(bool is_horizontal) {
+  CheckIsNotDestroyed();
   DCHECK(IsOutOfFlowPositioned());
   DCHECK(Container()->IsLayoutInline());
   DCHECK(Container()->CanContainOutOfFlowPositionedElement(
@@ -3263,6 +3421,7 @@
 }
 
 void LayoutBox::DeleteLineBoxWrapper() {
+  CheckIsNotDestroyed();
   if (!IsInLayoutNGInlineFormattingContext() && inline_box_wrapper_) {
     if (!DocumentBeingDestroyed())
       inline_box_wrapper_->Remove();
@@ -3273,24 +3432,28 @@
 
 void LayoutBox::SetSpannerPlaceholder(
     LayoutMultiColumnSpannerPlaceholder& placeholder) {
+  CheckIsNotDestroyed();
   // Not expected to change directly from one spanner to another.
   CHECK(!rare_data_ || !rare_data_->spanner_placeholder_);
   EnsureRareData().spanner_placeholder_ = &placeholder;
 }
 
 void LayoutBox::ClearSpannerPlaceholder() {
+  CheckIsNotDestroyed();
   if (!rare_data_)
     return;
   rare_data_->spanner_placeholder_ = nullptr;
 }
 
 void LayoutBox::SetPaginationStrut(LayoutUnit strut) {
+  CheckIsNotDestroyed();
   if (!strut && !rare_data_)
     return;
   EnsureRareData().pagination_strut_ = strut;
 }
 
 bool LayoutBox::IsBreakBetweenControllable(EBreakBetween break_value) const {
+  CheckIsNotDestroyed();
   if (break_value == EBreakBetween::kAuto)
     return true;
   // We currently only support non-auto break-before and break-after values on
@@ -3330,6 +3493,7 @@
 }
 
 bool LayoutBox::IsBreakInsideControllable(EBreakInside break_value) const {
+  CheckIsNotDestroyed();
   if (break_value == EBreakInside::kAuto)
     return true;
   // First check multicol.
@@ -3350,6 +3514,7 @@
 }
 
 EBreakBetween LayoutBox::BreakAfter() const {
+  CheckIsNotDestroyed();
   EBreakBetween break_value = StyleRef().BreakAfter();
   if (break_value == EBreakBetween::kAuto ||
       IsBreakBetweenControllable(break_value))
@@ -3358,6 +3523,7 @@
 }
 
 EBreakBetween LayoutBox::BreakBefore() const {
+  CheckIsNotDestroyed();
   EBreakBetween break_value = StyleRef().BreakBefore();
   if (break_value == EBreakBetween::kAuto ||
       IsBreakBetweenControllable(break_value))
@@ -3366,6 +3532,7 @@
 }
 
 EBreakInside LayoutBox::BreakInside() const {
+  CheckIsNotDestroyed();
   EBreakInside break_value = StyleRef().BreakInside();
   if (break_value == EBreakInside::kAuto ||
       IsBreakInsideControllable(break_value))
@@ -3375,6 +3542,7 @@
 
 EBreakBetween LayoutBox::ClassABreakPointValue(
     EBreakBetween previous_break_after_value) const {
+  CheckIsNotDestroyed();
   // First assert that we're at a class A break point.
   DCHECK(IsBreakBetweenControllable(previous_break_after_value));
 
@@ -3384,6 +3552,7 @@
 
 bool LayoutBox::NeedsForcedBreakBefore(
     EBreakBetween previous_break_after_value) const {
+  CheckIsNotDestroyed();
   // Forced break values are only honored when specified on in-flow objects, but
   // floats and out-of-flow positioned objects may be affected by a break-after
   // value of the previous in-flow object, even though we're not at a class A
@@ -3396,14 +3565,17 @@
 }
 
 const AtomicString LayoutBox::StartPageName() const {
+  CheckIsNotDestroyed();
   return StyleRef().Page();
 }
 
 const AtomicString LayoutBox::EndPageName() const {
+  CheckIsNotDestroyed();
   return StyleRef().Page();
 }
 
 PhysicalRect LayoutBox::LocalVisualRectIgnoringVisibility() const {
+  CheckIsNotDestroyed();
   return PhysicalSelfVisualOverflowRect();
 }
 
@@ -3411,6 +3583,7 @@
     TransformState& transform_state,
     const LayoutObject& container,
     const LayoutBoxModelObject* ancestor_to_stop_at) const {
+  CheckIsNotDestroyed();
   transform_state.Flatten();
   // Apply visual overflow caused by reflections and filters defined on objects
   // between this object and container (not included) or ancestorToStopAt
@@ -3437,6 +3610,7 @@
     const LayoutBoxModelObject* ancestor,
     TransformState& transform_state,
     VisualRectFlags visual_rect_flags) const {
+  CheckIsNotDestroyed();
   InflateVisualRectForFilter(transform_state);
 
   if (ancestor == this)
@@ -3524,6 +3698,7 @@
 
 void LayoutBox::InflateVisualRectForFilter(
     TransformState& transform_state) const {
+  CheckIsNotDestroyed();
   if (!Layer() || !Layer()->PaintsWithFilters())
     return;
 
@@ -3558,6 +3733,7 @@
 }
 
 void LayoutBox::UpdateLogicalWidth() {
+  CheckIsNotDestroyed();
   if (NeedsPreferredWidthsRecalculation()) {
     if (ShouldRecalculateMinMaxWidthsAffectedByAncestor(this)) {
       // Laying out this object means that its containing block is also being
@@ -3619,6 +3795,7 @@
 }
 
 LayoutUnit LayoutBox::ContainerWidthInInlineDirection() const {
+  CheckIsNotDestroyed();
   LayoutBlock* cb = ContainingBlock();
 
   if (IsParallelWritingMode(cb->StyleRef().GetWritingMode(),
@@ -3634,6 +3811,7 @@
 
 bool LayoutBox::ShouldComputeLogicalWidthFromAspectRatio(
     LayoutUnit* out_logical_height) const {
+  CheckIsNotDestroyed();
   if (!StyleRef().AspectRatio() ||
       (!StyleRef().LogicalHeight().IsFixed() &&
        !StyleRef().LogicalHeight().IsPercentOrCalc())) {
@@ -3653,6 +3831,7 @@
 
 bool LayoutBox::ComputeLogicalWidthFromAspectRatio(
     LayoutUnit* out_logical_width) const {
+  CheckIsNotDestroyed();
   LayoutUnit logical_height_for_ar;
   if (!ShouldComputeLogicalWidthFromAspectRatio(&logical_height_for_ar))
     return false;
@@ -3675,6 +3854,7 @@
 DISABLE_CFI_PERF
 void LayoutBox::ComputeLogicalWidth(
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   computed_values.position_ = LogicalLeft();
   computed_values.margins_.start_ = MarginStart();
   computed_values.margins_.end_ = MarginEnd();
@@ -3790,6 +3970,7 @@
 
 LayoutUnit LayoutBox::FillAvailableMeasure(
     LayoutUnit available_logical_width) const {
+  CheckIsNotDestroyed();
   LayoutUnit margin_start;
   LayoutUnit margin_end;
   return FillAvailableMeasure(available_logical_width, margin_start,
@@ -3799,6 +3980,7 @@
 LayoutUnit LayoutBox::FillAvailableMeasure(LayoutUnit available_logical_width,
                                            LayoutUnit& margin_start,
                                            LayoutUnit& margin_end) const {
+  CheckIsNotDestroyed();
   DCHECK_GE(available_logical_width, 0);
 
   bool isOrthogonalElement =
@@ -3823,6 +4005,7 @@
 LayoutUnit LayoutBox::ComputeIntrinsicLogicalWidthUsing(
     const Length& logical_width_length,
     LayoutUnit available_logical_width) const {
+  CheckIsNotDestroyed();
   if (logical_width_length.IsFillAvailable()) {
     if (!IsA<HTMLMarqueeElement>(GetNode())) {
       UseCounter::Count(GetDocument(),
@@ -3859,6 +4042,7 @@
     const Length& logical_width,
     LayoutUnit available_logical_width,
     const LayoutBlock* cb) const {
+  CheckIsNotDestroyed();
   DCHECK(width_type == kMinSize || width_type == kMainOrPreferredSize ||
          !logical_width.IsAuto());
   if (width_type == kMinSize && logical_width.IsAuto())
@@ -3906,6 +4090,7 @@
 }
 
 bool LayoutBox::ColumnFlexItemHasStretchAlignment() const {
+  CheckIsNotDestroyed();
   // auto margins mean we don't stretch. Note that this function will only be
   // used for widths, so we don't have to check marginBefore/marginAfter.
   const auto& parent_style = Parent()->StyleRef();
@@ -3920,6 +4105,7 @@
 }
 
 bool LayoutBox::IsStretchingColumnFlexItem() const {
+  CheckIsNotDestroyed();
   LayoutObject* parent = Parent();
   if (parent->StyleRef().IsDeprecatedWebkitBox() &&
       parent->StyleRef().BoxOrient() == EBoxOrient::kVertical &&
@@ -3939,6 +4125,7 @@
 // TODO (lajava) Can/Should we move this inside specific layout classes (flex.
 // grid)? Can we refactor columnFlexItemHasStretchAlignment logic?
 bool LayoutBox::HasStretchedLogicalWidth() const {
+  CheckIsNotDestroyed();
   const ComputedStyle& style = StyleRef();
   if (!style.LogicalWidth().IsAuto() || style.MarginStart().IsAuto() ||
       style.MarginEnd().IsAuto())
@@ -3964,6 +4151,7 @@
 
 bool LayoutBox::SizesLogicalWidthToFitContent(
     const Length& logical_width) const {
+  CheckIsNotDestroyed();
   if (IsFloating() || IsInlineBlockOrInlineTable() ||
       StyleRef().HasOutOfFlowPosition())
     return true;
@@ -4015,6 +4203,7 @@
 }
 
 bool LayoutBox::AutoWidthShouldFitContent() const {
+  CheckIsNotDestroyed();
   return GetNode() &&
          (IsA<HTMLInputElement>(*GetNode()) ||
           IsA<HTMLSelectElement>(*GetNode()) ||
@@ -4030,6 +4219,7 @@
                                            LayoutUnit& margin_end,
                                            Length margin_start_length,
                                            Length margin_end_length) const {
+  CheckIsNotDestroyed();
   // First assert that we're not calling this method on box types that don't
   // support margins.
   DCHECK(!IsTableCell());
@@ -4139,6 +4329,7 @@
 
 DISABLE_CFI_PERF
 void LayoutBox::UpdateLogicalHeight() {
+  CheckIsNotDestroyed();
   if (!HasOverrideLogicalHeight()) {
     // If we have an override height, our children will have sized themselves
     // relative to our override height, which would make our intrinsic size
@@ -4164,6 +4355,7 @@
 
 void LayoutBox::ComputeLogicalHeight(
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   LayoutUnit height;
   if (HasOverrideIntrinsicContentLogicalHeight()) {
     height = OverrideIntrinsicContentLogicalHeight() +
@@ -4188,6 +4380,7 @@
     LayoutUnit logical_height,
     LayoutUnit logical_top,
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   computed_values.extent_ = logical_height;
   computed_values.position_ = logical_top;
 
@@ -4304,6 +4497,7 @@
 }
 
 LayoutUnit LayoutBox::ComputeLogicalHeightWithoutLayout() const {
+  CheckIsNotDestroyed();
   LogicalExtentComputedValues computed_values;
 
   if (!SelfNeedsLayout() && HasOverrideIntrinsicContentLogicalHeight()) {
@@ -4324,6 +4518,7 @@
     SizeType height_type,
     const Length& height,
     LayoutUnit intrinsic_content_height) const {
+  CheckIsNotDestroyed();
   LayoutUnit logical_height = ComputeContentAndScrollbarLogicalHeightUsing(
       height_type, height, intrinsic_content_height);
   if (logical_height != -1) {
@@ -4339,6 +4534,7 @@
     SizeType height_type,
     const Length& height,
     LayoutUnit intrinsic_content_height) const {
+  CheckIsNotDestroyed();
   LayoutUnit height_including_scrollbar =
       ComputeContentAndScrollbarLogicalHeightUsing(height_type, height,
                                                    intrinsic_content_height);
@@ -4358,6 +4554,7 @@
     const Length& logical_height_length,
     LayoutUnit intrinsic_content_height,
     LayoutUnit border_and_padding) const {
+  CheckIsNotDestroyed();
   // FIXME(cbiesinger): The css-sizing spec is considering changing what
   // min-content/max-content should resolve to.
   // If that happens, this code will have to change.
@@ -4386,6 +4583,7 @@
     SizeType height_type,
     const Length& height,
     LayoutUnit intrinsic_content_height) const {
+  CheckIsNotDestroyed();
   if (height.IsAuto())
     return height_type == kMinSize ? LayoutUnit() : LayoutUnit(-1);
   // FIXME(cbiesinger): The css-sizing spec is considering changing what
@@ -4407,6 +4605,7 @@
 }
 
 bool LayoutBox::StretchesToViewportInQuirksMode() const {
+  CheckIsNotDestroyed();
   if (!IsDocumentElement() && !IsBody())
     return false;
   return StyleRef().LogicalHeight().IsAuto() &&
@@ -4458,6 +4657,7 @@
 LayoutUnit LayoutBox::ContainingBlockLogicalHeightForPercentageResolution(
     LayoutBlock** out_cb,
     bool* out_skipped_auto_height_containing_block) const {
+  CheckIsNotDestroyed();
   LayoutBlock* cb = ContainingBlock();
   const LayoutBlock* const real_cb = cb;
   const LayoutBox* containing_block_child = this;
@@ -4549,6 +4749,7 @@
 
 LayoutUnit LayoutBox::ComputePercentageLogicalHeight(
     const Length& height) const {
+  CheckIsNotDestroyed();
   bool skipped_auto_height_containing_block = false;
   LayoutBlock* cb = nullptr;
   LayoutUnit available_height =
@@ -4583,6 +4784,7 @@
 
 LayoutUnit LayoutBox::ComputeReplacedLogicalWidth(
     ShouldComputePreferred should_compute_preferred) const {
+  CheckIsNotDestroyed();
   return ComputeReplacedLogicalWidthRespectingMinMaxWidth(
       ComputeReplacedLogicalWidthUsing(kMainOrPreferredSize,
                                        StyleRef().LogicalWidth()),
@@ -4592,6 +4794,7 @@
 LayoutUnit LayoutBox::ComputeReplacedLogicalWidthRespectingMinMaxWidth(
     LayoutUnit logical_width,
     ShouldComputePreferred should_compute_preferred) const {
+  CheckIsNotDestroyed();
   LayoutUnit min_logical_width =
       (should_compute_preferred == kComputePreferred &&
        StyleRef().LogicalMinWidth().IsPercentOrCalc())
@@ -4612,6 +4815,7 @@
 LayoutUnit LayoutBox::ComputeReplacedLogicalWidthUsing(
     SizeType size_type,
     const Length& logical_width) const {
+  CheckIsNotDestroyed();
   DCHECK(size_type == kMinSize || size_type == kMainOrPreferredSize ||
          !logical_width.IsAuto());
   if (size_type == kMinSize && logical_width.IsAuto())
@@ -4670,12 +4874,14 @@
 }
 
 LayoutUnit LayoutBox::ComputeReplacedLogicalHeight(LayoutUnit) const {
+  CheckIsNotDestroyed();
   return ComputeReplacedLogicalHeightRespectingMinMaxHeight(
       ComputeReplacedLogicalHeightUsing(kMainOrPreferredSize,
                                         StyleRef().LogicalHeight()));
 }
 
 bool LayoutBox::LogicalHeightComputesAsNone(SizeType size_type) const {
+  CheckIsNotDestroyed();
   DCHECK(size_type == kMinSize || size_type == kMaxSize);
   const Length& logical_height = size_type == kMinSize
                                      ? StyleRef().LogicalMinHeight()
@@ -4715,6 +4921,7 @@
 
 LayoutUnit LayoutBox::ComputeReplacedLogicalHeightRespectingMinMaxHeight(
     LayoutUnit logical_height) const {
+  CheckIsNotDestroyed();
   // If the height of the containing block is not specified explicitly (i.e., it
   // depends on content height), and this element is not absolutely positioned,
   // the percentage value is treated as '0' (for 'min-height') or 'none' (for
@@ -4736,6 +4943,7 @@
 LayoutUnit LayoutBox::ComputeReplacedLogicalHeightUsing(
     SizeType size_type,
     const Length& logical_height) const {
+  CheckIsNotDestroyed();
   DCHECK(size_type == kMinSize || size_type == kMainOrPreferredSize ||
          !logical_height.IsAuto());
   if (size_type == kMinSize && logical_height.IsAuto())
@@ -4826,6 +5034,7 @@
 
 LayoutUnit LayoutBox::AvailableLogicalHeight(
     AvailableLogicalHeightType height_type) const {
+  CheckIsNotDestroyed();
   if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
     // LayoutNG code is correct, Legacy code incorrectly ConstrainsMinMax
     // when height is -1, and returns 0, not -1.
@@ -4850,6 +5059,7 @@
 LayoutUnit LayoutBox::AvailableLogicalHeightUsing(
     const Length& h,
     AvailableLogicalHeightType height_type) const {
+  CheckIsNotDestroyed();
   if (auto* layout_view = DynamicTo<LayoutView>(this)) {
     return LayoutUnit(IsHorizontalWritingMode()
                           ? layout_view->GetFrameView()->Size().Height()
@@ -4941,6 +5151,7 @@
 
 void LayoutBox::ComputeAndSetBlockDirectionMargins(
     const LayoutBlock* containing_block) {
+  CheckIsNotDestroyed();
   LayoutUnit margin_before;
   LayoutUnit margin_after;
   DCHECK(containing_block);
@@ -4960,6 +5171,7 @@
 LayoutUnit LayoutBox::ContainingBlockLogicalWidthForPositioned(
     const LayoutBoxModelObject* containing_block,
     bool check_for_perpendicular_writing_mode) const {
+  CheckIsNotDestroyed();
   if (check_for_perpendicular_writing_mode &&
       containing_block->IsHorizontalWritingMode() != IsHorizontalWritingMode())
     return ContainingBlockLogicalHeightForPositioned(containing_block, false);
@@ -5031,6 +5243,7 @@
 LayoutUnit LayoutBox::ContainingBlockLogicalHeightForPositioned(
     const LayoutBoxModelObject* containing_block,
     bool check_for_perpendicular_writing_mode) const {
+  CheckIsNotDestroyed();
   if (check_for_perpendicular_writing_mode &&
       containing_block->IsHorizontalWritingMode() != IsHorizontalWritingMode())
     return ContainingBlockLogicalWidthForPositioned(containing_block, false);
@@ -5203,6 +5416,7 @@
 
 void LayoutBox::ComputePositionedLogicalWidth(
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   // QUESTIONS
   // FIXME 1: Should we still deal with these the cases of 'left' or 'right'
   // having the type 'static' in determining whether to calculate the static
@@ -5369,6 +5583,7 @@
 LayoutUnit LayoutBox::ShrinkToFitLogicalWidth(
     LayoutUnit available_logical_width,
     LayoutUnit borders_plus_padding) const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes = PreferredLogicalWidths();
   sizes -= borders_plus_padding;
   return sizes.ShrinkToFit(available_logical_width);
@@ -5386,6 +5601,7 @@
     const Length& margin_logical_left,
     const Length& margin_logical_right,
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   LayoutUnit logical_width_value;
 
   DCHECK(width_size_type == kMinSize ||
@@ -5662,6 +5878,7 @@
 
 void LayoutBox::ComputePositionedLogicalHeight(
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   // The following is based off of the W3C Working Draft from April 11, 2006 of
   // CSS 2.1: Section 10.6.4 "Absolutely positioned, non-replaced elements"
   // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-non-replaced-height>
@@ -5827,6 +6044,7 @@
     const Length& margin_before,
     const Length& margin_after,
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   DCHECK(height_size_type == kMinSize ||
          height_size_type == kMainOrPreferredSize ||
          !logical_height_length.IsAuto());
@@ -6019,6 +6237,7 @@
     const InlineBox* box,
     int caret_offset,
     LayoutUnit* extra_width_to_end_of_line) const {
+  CheckIsNotDestroyed();
   // VisiblePositions at offsets inside containers either a) refer to the
   // positions before/after those containers (tables and select elements) or
   // b) refer to the position inside an empty block.
@@ -6078,6 +6297,7 @@
 
 PositionWithAffinity LayoutBox::PositionForPoint(
     const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   // no children...return this layout object's element, if there is one, and
   // offset 0
   LayoutObject* first_child = SlowFirstChild();
@@ -6181,6 +6401,7 @@
 
 DISABLE_CFI_PERF
 bool LayoutBox::ShrinkToAvoidFloats() const {
+  CheckIsNotDestroyed();
   // Floating objects don't shrink.  Objects that don't avoid floats don't
   // shrink.
   if (IsInline() || !CreatesNewFormattingContext() || IsFloating())
@@ -6209,6 +6430,7 @@
 
 DISABLE_CFI_PERF
 bool LayoutBox::ShouldBeConsideredAsReplaced() const {
+  CheckIsNotDestroyed();
   if (IsAtomicInlineLevel())
     return true;
   // We need to detect all types of objects that should be treated as replaced.
@@ -6234,6 +6456,7 @@
 }
 
 void LayoutBox::UpdateFragmentationInfoForChild(LayoutBox& child) {
+  CheckIsNotDestroyed();
   LayoutState* layout_state = View()->GetLayoutState();
   DCHECK(layout_state->IsPaginated());
   child.SetOffsetToNextPage(LayoutUnit());
@@ -6249,6 +6472,7 @@
 }
 
 bool LayoutBox::ChildNeedsRelayoutForPagination(const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   // TODO(mstensho): Should try to get this to work for floats too, instead of
   // just marking and bailing here.
   if (child.IsFloating())
@@ -6291,6 +6515,7 @@
 void LayoutBox::MarkChildForPaginationRelayoutIfNeeded(
     LayoutBox& child,
     SubtreeLayoutScope& layout_scope) {
+  CheckIsNotDestroyed();
   DCHECK(!child.NeedsLayout() || child.ChildLayoutBlockedByDisplayLock());
   LayoutState* layout_state = View()->GetLayoutState();
 
@@ -6300,11 +6525,13 @@
 }
 
 void LayoutBox::MarkOrthogonalWritingModeRoot() {
+  CheckIsNotDestroyed();
   DCHECK(GetFrameView());
   GetFrameView()->AddOrthogonalWritingModeRoot(*this);
 }
 
 void LayoutBox::UnmarkOrthogonalWritingModeRoot() {
+  CheckIsNotDestroyed();
   DCHECK(GetFrameView());
   GetFrameView()->RemoveOrthogonalWritingModeRoot(*this);
 }
@@ -6312,6 +6539,7 @@
 // Children of LayoutCustom object's are only considered "items" when it has a
 // loaded algorithm.
 bool LayoutBox::IsCustomItem() const {
+  CheckIsNotDestroyed();
   auto* parent_layout_box = DynamicTo<LayoutNGCustom>(Parent());
   return parent_layout_box && parent_layout_box->IsLoaded();
 }
@@ -6319,11 +6547,13 @@
 // LayoutCustom items are only shrink-to-fit during the web-developer defined
 // layout phase (not during fallback).
 bool LayoutBox::IsCustomItemShrinkToFit() const {
+  CheckIsNotDestroyed();
   DCHECK(IsCustomItem());
   return To<LayoutNGCustom>(Parent())->IsLoaded();
 }
 
 void LayoutBox::AddVisualEffectOverflow() {
+  CheckIsNotDestroyed();
   if (!StyleRef().HasVisualOverflowingEffect())
     return;
 
@@ -6341,6 +6571,7 @@
 }
 
 LayoutRectOutsets LayoutBox::ComputeVisualEffectOverflowOutsets() {
+  CheckIsNotDestroyed();
   const ComputedStyle& style = StyleRef();
   DCHECK(style.HasVisualOverflowingEffect());
 
@@ -6363,6 +6594,7 @@
 
 void LayoutBox::AddVisualOverflowFromChild(const LayoutBox& child,
                                            const LayoutSize& delta) {
+  CheckIsNotDestroyed();
   // Never allow flow threads to propagate overflow up to a parent.
   if (child.IsLayoutFlowThread())
     return;
@@ -6382,6 +6614,7 @@
 DISABLE_CFI_PERF
 void LayoutBox::AddLayoutOverflowFromChild(const LayoutBox& child,
                                            const LayoutSize& delta) {
+  CheckIsNotDestroyed();
   DCHECK(!ChildLayoutBlockedByDisplayLock());
 
   // Never allow flow threads to propagate overflow up to a parent.
@@ -6399,17 +6632,20 @@
 }
 
 void LayoutBox::SetLayoutClientAfterEdge(LayoutUnit client_after_edge) {
+  CheckIsNotDestroyed();
   if (LayoutOverflowIsSet())
     overflow_->layout_overflow->SetLayoutClientAfterEdge(client_after_edge);
 }
 
 LayoutUnit LayoutBox::LayoutClientAfterEdge() const {
+  CheckIsNotDestroyed();
   return LayoutOverflowIsSet()
              ? overflow_->layout_overflow->LayoutClientAfterEdge()
              : ClientLogicalBottom();
 }
 
 PhysicalRect LayoutBox::PhysicalVisualOverflowRectIncludingFilters() const {
+  CheckIsNotDestroyed();
   PhysicalRect bounds_rect = PhysicalVisualOverflowRect();
   if (!StyleRef().HasFilter())
     return bounds_rect;
@@ -6420,15 +6656,18 @@
 }
 
 bool LayoutBox::HasTopOverflow() const {
+  CheckIsNotDestroyed();
   return !StyleRef().IsLeftToRightDirection() && !IsHorizontalWritingMode();
 }
 
 bool LayoutBox::HasLeftOverflow() const {
+  CheckIsNotDestroyed();
   return !StyleRef().IsLeftToRightDirection() && IsHorizontalWritingMode();
 }
 
 DISABLE_CFI_PERF
 void LayoutBox::AddLayoutOverflow(const LayoutRect& rect) {
+  CheckIsNotDestroyed();
   if (rect.IsEmpty())
     return;
 
@@ -6473,6 +6712,7 @@
 }
 
 void LayoutBox::AddSelfVisualOverflow(const LayoutRect& rect) {
+  CheckIsNotDestroyed();
   if (rect.IsEmpty())
     return;
 
@@ -6491,6 +6731,7 @@
 }
 
 void LayoutBox::AddContentsVisualOverflow(const LayoutRect& rect) {
+  CheckIsNotDestroyed();
   if (rect.IsEmpty())
     return;
 
@@ -6513,6 +6754,7 @@
 }
 
 void LayoutBox::ClearLayoutOverflow() {
+  CheckIsNotDestroyed();
   if (overflow_)
     overflow_->layout_overflow.reset();
   // overflow_ will be reset by MutableForPainting::ClearPreviousOverflowData()
@@ -6520,6 +6762,7 @@
 }
 
 void LayoutBox::ClearVisualOverflow() {
+  CheckIsNotDestroyed();
   if (overflow_)
     overflow_->visual_overflow.reset();
   // overflow_ will be reset by MutableForPainting::ClearPreviousOverflowData()
@@ -6527,12 +6770,14 @@
 }
 
 bool LayoutBox::PercentageLogicalHeightIsResolvable() const {
+  CheckIsNotDestroyed();
   Length fake_length = Length::Percent(100);
   return ComputePercentageLogicalHeight(fake_length) != -1;
 }
 
 DISABLE_CFI_PERF
 bool LayoutBox::HasUnsplittableScrollingOverflow() const {
+  CheckIsNotDestroyed();
   // We will paginate as long as we don't scroll overflow in the pagination
   // direction.
   bool is_horizontal = IsHorizontalWritingMode();
@@ -6566,6 +6811,7 @@
 
 LayoutBox::PaginationBreakability LayoutBox::GetPaginationBreakability(
     FragmentationEngine engine) const {
+  CheckIsNotDestroyed();
   if (ShouldBeConsideredAsReplaced() || HasUnsplittableScrollingOverflow() ||
       (Parent() && IsWritingModeRoot()) ||
       (IsOutOfFlowPositioned() &&
@@ -6617,6 +6863,7 @@
 }
 
 PaintLayer* LayoutBox::EnclosingFloatPaintingLayer() const {
+  CheckIsNotDestroyed();
   const LayoutObject* curr = this;
   while (curr) {
     PaintLayer* layer = curr->HasLayer() && curr->IsBox()
@@ -6630,6 +6877,7 @@
 }
 
 const LayoutBlock& LayoutBox::EnclosingScrollportBox() const {
+  CheckIsNotDestroyed();
   const LayoutBlock* ancestor = ContainingBlock();
   for (; ancestor; ancestor = ancestor->ContainingBlock()) {
     if (ancestor->IsScrollContainer())
@@ -6640,6 +6888,7 @@
 }
 
 LayoutRect LayoutBox::LogicalVisualOverflowRectForPropagation() const {
+  CheckIsNotDestroyed();
   LayoutRect rect = VisualOverflowRectForPropagation();
   if (!Parent()->StyleRef().IsHorizontalWritingMode())
     return rect.TransposedRect();
@@ -6648,6 +6897,7 @@
 
 DISABLE_CFI_PERF
 LayoutRect LayoutBox::RectForOverflowPropagation(const LayoutRect& rect) const {
+  CheckIsNotDestroyed();
   // If the child and parent are in the same blocks direction, then we don't
   // have to do anything fancy. Just return the rect.
   if (Parent()->StyleRef().IsFlippedBlocksWritingMode() ==
@@ -6664,6 +6914,7 @@
 DISABLE_CFI_PERF
 LayoutRect LayoutBox::LogicalLayoutOverflowRectForPropagation(
     LayoutObject* container) const {
+  CheckIsNotDestroyed();
   LayoutRect rect = LayoutOverflowRectForPropagation(container);
   if (!Parent()->StyleRef().IsHorizontalWritingMode())
     return rect.TransposedRect();
@@ -6673,6 +6924,7 @@
 DISABLE_CFI_PERF
 LayoutRect LayoutBox::LayoutOverflowRectForPropagation(
     LayoutObject* container) const {
+  CheckIsNotDestroyed();
   // Only propagate interior layout overflow if we don't clip it.
   LayoutRect rect = BorderBoxRect();
 
@@ -6709,10 +6961,12 @@
 
 DISABLE_CFI_PERF
 LayoutRect LayoutBox::NoOverflowRect() const {
+  CheckIsNotDestroyed();
   return FlipForWritingMode(PhysicalPaddingBoxRect());
 }
 
 LayoutRect LayoutBox::VisualOverflowRect() const {
+  CheckIsNotDestroyed();
   if (!VisualOverflowIsSet())
     return BorderBoxRect();
   if (ShouldClipOverflow() || HasMask())
@@ -6722,18 +6976,22 @@
 }
 
 PhysicalOffset LayoutBox::OffsetPoint(const Element* parent) const {
+  CheckIsNotDestroyed();
   return AdjustedPositionRelativeTo(PhysicalLocation(), parent);
 }
 
 LayoutUnit LayoutBox::OffsetLeft(const Element* parent) const {
+  CheckIsNotDestroyed();
   return OffsetPoint(parent).left;
 }
 
 LayoutUnit LayoutBox::OffsetTop(const Element* parent) const {
+  CheckIsNotDestroyed();
   return OffsetPoint(parent).top;
 }
 
 LayoutBox* LayoutBox::LocationContainer() const {
+  CheckIsNotDestroyed();
   // Location of a non-root SVG object derived from LayoutBox should not be
   // affected by writing-mode of the containing box (SVGRoot).
   if (IsSVGChild())
@@ -6747,12 +7005,14 @@
 }
 
 bool LayoutBox::HasRelativeLogicalWidth() const {
+  CheckIsNotDestroyed();
   return StyleRef().LogicalWidth().IsPercentOrCalc() ||
          StyleRef().LogicalMinWidth().IsPercentOrCalc() ||
          StyleRef().LogicalMaxWidth().IsPercentOrCalc();
 }
 
 bool LayoutBox::HasRelativeLogicalHeight() const {
+  CheckIsNotDestroyed();
   return StyleRef().LogicalHeight().IsPercentOrCalc() ||
          StyleRef().LogicalMinHeight().IsPercentOrCalc() ||
          StyleRef().LogicalMaxHeight().IsPercentOrCalc();
@@ -6787,6 +7047,7 @@
 
 LayoutObject* LayoutBox::SplitAnonymousBoxesAroundChild(
     LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   LayoutBox* box_at_top_of_new_branch = nullptr;
 
   while (before_child->Parent() != this) {
@@ -6839,6 +7100,7 @@
 }
 
 LayoutUnit LayoutBox::OffsetFromLogicalTopOfFirstPage() const {
+  CheckIsNotDestroyed();
   LayoutState* layout_state = View()->GetLayoutState();
   if (!layout_state || !layout_state->IsPaginated())
     return LayoutUnit();
@@ -6860,6 +7122,7 @@
 }
 
 void LayoutBox::SetOffsetToNextPage(LayoutUnit offset) {
+  CheckIsNotDestroyed();
   if (!rare_data_ && !offset)
     return;
   EnsureRareData().offset_to_next_page_ = offset;
@@ -6868,6 +7131,7 @@
 void LayoutBox::LogicalExtentAfterUpdatingLogicalWidth(
     const LayoutUnit& new_logical_top,
     LayoutBox::LogicalExtentComputedValues& computed_values) {
+  CheckIsNotDestroyed();
   // FIXME: None of this is right for perpendicular writing-mode children.
   LayoutUnit old_logical_width = LogicalWidth();
   LayoutUnit old_logical_left = LogicalLeft();
@@ -6891,10 +7155,12 @@
 }
 
 ShapeOutsideInfo* LayoutBox::GetShapeOutsideInfo() const {
+  CheckIsNotDestroyed();
   return ShapeOutsideInfo::Info(*this);
 }
 
 void LayoutBox::SetPercentHeightContainer(LayoutBlock* container) {
+  CheckIsNotDestroyed();
   DCHECK(!container || !PercentHeightContainer());
   if (!container && !rare_data_)
     return;
@@ -6902,6 +7168,7 @@
 }
 
 void LayoutBox::RemoveFromPercentHeightContainer() {
+  CheckIsNotDestroyed();
   if (!PercentHeightContainer())
     return;
 
@@ -6913,6 +7180,7 @@
 }
 
 void LayoutBox::ClearPercentHeightDescendants() {
+  CheckIsNotDestroyed();
   for (LayoutObject* curr = SlowFirstChild(); curr;
        curr = curr->NextInPreOrder(this)) {
     if (curr->IsBox())
@@ -6921,6 +7189,7 @@
 }
 
 LayoutUnit LayoutBox::PageLogicalHeightForOffset(LayoutUnit offset) const {
+  CheckIsNotDestroyed();
   // We need to have calculated some fragmentainer logical height (even a
   // tentative one will do, though) in order to tell how tall one fragmentainer
   // is.
@@ -6940,6 +7209,7 @@
 }
 
 bool LayoutBox::IsPageLogicalHeightKnown() const {
+  CheckIsNotDestroyed();
   if (const LayoutFlowThread* flow_thread = FlowThreadContainingBlock())
     return flow_thread->IsPageLogicalHeightKnown();
   return View()->PageLogicalHeight();
@@ -6948,6 +7218,7 @@
 LayoutUnit LayoutBox::PageRemainingLogicalHeightForOffset(
     LayoutUnit offset,
     PageBoundaryRule page_boundary_rule) const {
+  CheckIsNotDestroyed();
   DCHECK(IsPageLogicalHeightKnown());
   LayoutView* layout_view = View();
   offset += OffsetFromLogicalTopOfFirstPage();
@@ -6974,12 +7245,14 @@
 }
 
 int LayoutBox::CurrentPageNumber(LayoutUnit child_logical_top) const {
+  CheckIsNotDestroyed();
   LayoutUnit offset = OffsetFromLogicalTopOfFirstPage() + child_logical_top;
   return (offset / View()->PageLogicalHeight()).Floor();
 }
 
 bool LayoutBox::CrossesPageBoundary(LayoutUnit offset,
                                     LayoutUnit logical_height) const {
+  CheckIsNotDestroyed();
   if (!IsPageLogicalHeightKnown())
     return false;
   return PageRemainingLogicalHeightForOffset(offset, kAssociateWithLatterPage) <
@@ -6989,6 +7262,7 @@
 LayoutUnit LayoutBox::CalculatePaginationStrutToFitContent(
     LayoutUnit offset,
     LayoutUnit content_logical_height) const {
+  CheckIsNotDestroyed();
   LayoutUnit strut_to_next_page =
       PageRemainingLogicalHeightForOffset(offset, kAssociateWithLatterPage);
 
@@ -7028,10 +7302,12 @@
 }
 
 LayoutBox* LayoutBox::SnapContainer() const {
+  CheckIsNotDestroyed();
   return rare_data_ ? rare_data_->snap_container_ : nullptr;
 }
 
 void LayoutBox::SetSnapContainer(LayoutBox* new_container) {
+  CheckIsNotDestroyed();
   LayoutBox* old_container = SnapContainer();
   if (old_container == new_container)
     return;
@@ -7046,6 +7322,7 @@
 }
 
 void LayoutBox::ClearSnapAreas() {
+  CheckIsNotDestroyed();
   if (SnapAreaSet* areas = SnapAreas()) {
     for (auto* const snap_area : *areas)
       snap_area->rare_data_->snap_container_ = nullptr;
@@ -7054,10 +7331,12 @@
 }
 
 void LayoutBox::AddSnapArea(LayoutBox& snap_area) {
+  CheckIsNotDestroyed();
   EnsureRareData().EnsureSnapAreas().insert(&snap_area);
 }
 
 void LayoutBox::RemoveSnapArea(const LayoutBox& snap_area) {
+  CheckIsNotDestroyed();
   // 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_)
@@ -7065,6 +7344,7 @@
 }
 
 void LayoutBox::ReassignSnapAreas(LayoutBox& new_container) {
+  CheckIsNotDestroyed();
   SnapAreaSet* areas = SnapAreas();
   if (!areas)
     return;
@@ -7077,6 +7357,7 @@
 
 bool LayoutBox::AllowedToPropagateRecursiveScrollToParentFrame(
     const mojom::blink::ScrollIntoViewParamsPtr& params) {
+  CheckIsNotDestroyed();
   if (!GetFrameView()->SafeToPropagateScrollToParent())
     return false;
 
@@ -7087,16 +7368,19 @@
 }
 
 SnapAreaSet* LayoutBox::SnapAreas() const {
+  CheckIsNotDestroyed();
   return rare_data_ ? rare_data_->snap_areas_.get() : nullptr;
 }
 
 CustomLayoutChild* LayoutBox::GetCustomLayoutChild() const {
+  CheckIsNotDestroyed();
   DCHECK(rare_data_);
   DCHECK(rare_data_->layout_child_);
   return rare_data_->layout_child_.Get();
 }
 
 void LayoutBox::AddCustomLayoutChildIfNeeded() {
+  CheckIsNotDestroyed();
   if (!IsCustomItem())
     return;
 
@@ -7116,6 +7400,7 @@
 }
 
 void LayoutBox::ClearCustomLayoutChild() {
+  CheckIsNotDestroyed();
   if (!rare_data_)
     return;
 
@@ -7126,10 +7411,12 @@
 }
 
 PhysicalRect LayoutBox::DebugRect() const {
+  CheckIsNotDestroyed();
   return PhysicalRect(PhysicalLocation(), Size());
 }
 
 bool LayoutBox::ComputeShouldClipOverflow() const {
+  CheckIsNotDestroyed();
   return HasNonVisibleOverflow() || ShouldApplyPaintContainment() ||
          HasControlClip();
 }
@@ -7173,6 +7460,7 @@
 }
 
 RasterEffectOutset LayoutBox::VisualRectOutsetForRasterEffects() const {
+  CheckIsNotDestroyed();
   // If the box has subpixel visual effect outsets, as the visual effect may be
   // painted along the pixel-snapped border box, the pixels on the anti-aliased
   // edge of the effect may overflow the calculated visual rect. Expand visual
@@ -7184,6 +7472,7 @@
 }
 
 TextDirection LayoutBox::ResolvedDirection() const {
+  CheckIsNotDestroyed();
   if (IsInline() && IsAtomicInlineLevel()) {
     if (IsInLayoutNGInlineFormattingContext()) {
       NGInlineCursor cursor;
@@ -7199,6 +7488,7 @@
 
 bool LayoutBox::NeedsScrollNode(
     CompositingReasons direct_compositing_reasons) const {
+  CheckIsNotDestroyed();
   if (!IsScrollContainer())
     return false;
 
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h
index 7c7bbcc..6c0284acb 100644
--- a/third_party/blink/renderer/core/layout/layout_box.h
+++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -228,7 +228,10 @@
       const PhysicalRect& local_rect) const override;
   bool TextIsKnownToBeOnOpaqueBackground() const override;
 
-  virtual bool BackgroundShouldAlwaysBeClipped() const { return false; }
+  virtual bool BackgroundShouldAlwaysBeClipped() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   // Returns whether this object needs a scroll paint property tree node. These
   // are a requirement for composited scrolling but are also created for
@@ -241,28 +244,38 @@
   LayoutBox* LastChildBox() const;
 
   // TODO(crbug.com/962299): This is incorrect in some cases.
-  int PixelSnappedWidth() const { return frame_rect_.PixelSnappedWidth(); }
-  int PixelSnappedHeight() const { return frame_rect_.PixelSnappedHeight(); }
+  int PixelSnappedWidth() const {
+    CheckIsNotDestroyed();
+    return frame_rect_.PixelSnappedWidth();
+  }
+  int PixelSnappedHeight() const {
+    CheckIsNotDestroyed();
+    return frame_rect_.PixelSnappedHeight();
+  }
 
   void SetX(LayoutUnit x) {
+    CheckIsNotDestroyed();
     if (x == frame_rect_.X())
       return;
     frame_rect_.SetX(x);
     LocationChanged();
   }
   void SetY(LayoutUnit y) {
+    CheckIsNotDestroyed();
     if (y == frame_rect_.Y())
       return;
     frame_rect_.SetY(y);
     LocationChanged();
   }
   void SetWidth(LayoutUnit width) {
+    CheckIsNotDestroyed();
     if (width == frame_rect_.Width())
       return;
     frame_rect_.SetWidth(width);
     SizeChanged();
   }
   void SetHeight(LayoutUnit height) {
+    CheckIsNotDestroyed();
     if (height == frame_rect_.Height())
       return;
     frame_rect_.SetHeight(height);
@@ -270,20 +283,30 @@
   }
 
   LayoutUnit LogicalLeft() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? frame_rect_.X()
                                                 : frame_rect_.Y();
   }
-  LayoutUnit LogicalRight() const { return LogicalLeft() + LogicalWidth(); }
+  LayoutUnit LogicalRight() const {
+    CheckIsNotDestroyed();
+    return LogicalLeft() + LogicalWidth();
+  }
   LayoutUnit LogicalTop() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? frame_rect_.Y()
                                                 : frame_rect_.X();
   }
-  LayoutUnit LogicalBottom() const { return LogicalTop() + LogicalHeight(); }
+  LayoutUnit LogicalBottom() const {
+    CheckIsNotDestroyed();
+    return LogicalTop() + LogicalHeight();
+  }
   LayoutUnit LogicalWidth() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? frame_rect_.Width()
                                                 : frame_rect_.Height();
   }
   LayoutUnit LogicalHeight() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? frame_rect_.Height()
                                                 : frame_rect_.Width();
   }
@@ -304,49 +327,58 @@
 
   // TODO(crbug.com/962299): This is incorrect in some cases.
   int PixelSnappedLogicalHeight() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? PixelSnappedHeight()
                                                 : PixelSnappedWidth();
   }
   int PixelSnappedLogicalWidth() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? PixelSnappedWidth()
                                                 : PixelSnappedHeight();
   }
 
   LayoutUnit MinimumLogicalHeightForEmptyLine() const {
+    CheckIsNotDestroyed();
     return BorderAndPaddingLogicalHeight() +
            ComputeLogicalScrollbars().BlockSum() + LogicalHeightForEmptyLine();
   }
   LayoutUnit LogicalHeightForEmptyLine() const {
+    CheckIsNotDestroyed();
     return LineHeight(
         true, IsHorizontalWritingMode() ? kHorizontalLine : kVerticalLine,
         kPositionOfInteriorLineBoxes);
   }
 
   void SetLogicalLeft(LayoutUnit left) {
+    CheckIsNotDestroyed();
     if (StyleRef().IsHorizontalWritingMode())
       SetX(left);
     else
       SetY(left);
   }
   void SetLogicalTop(LayoutUnit top) {
+    CheckIsNotDestroyed();
     if (StyleRef().IsHorizontalWritingMode())
       SetY(top);
     else
       SetX(top);
   }
   void SetLogicalLocation(const LayoutPoint& location) {
+    CheckIsNotDestroyed();
     if (StyleRef().IsHorizontalWritingMode())
       SetLocation(location);
     else
       SetLocation(location.TransposedPoint());
   }
   void SetLogicalWidth(LayoutUnit size) {
+    CheckIsNotDestroyed();
     if (StyleRef().IsHorizontalWritingMode())
       SetWidth(size);
     else
       SetHeight(size);
   }
   void SetLogicalHeight(LayoutUnit size) {
+    CheckIsNotDestroyed();
     if (StyleRef().IsHorizontalWritingMode())
       SetHeight(size);
     else
@@ -354,15 +386,26 @@
   }
 
   // See frame_rect_.
-  LayoutPoint Location() const { return frame_rect_.Location(); }
+  LayoutPoint Location() const {
+    CheckIsNotDestroyed();
+    return frame_rect_.Location();
+  }
   LayoutSize LocationOffset() const {
+    CheckIsNotDestroyed();
     return LayoutSize(frame_rect_.X(), frame_rect_.Y());
   }
-  LayoutSize Size() const { return frame_rect_.Size(); }
+  LayoutSize Size() const {
+    CheckIsNotDestroyed();
+    return frame_rect_.Size();
+  }
   // TODO(crbug.com/962299): This is incorrect in some cases.
-  IntSize PixelSnappedSize() const { return frame_rect_.PixelSnappedSize(); }
+  IntSize PixelSnappedSize() const {
+    CheckIsNotDestroyed();
+    return frame_rect_.PixelSnappedSize();
+  }
 
   void SetLocation(const LayoutPoint& location) {
+    CheckIsNotDestroyed();
     if (location == frame_rect_.Location())
       return;
     frame_rect_.SetLocation(location);
@@ -381,12 +424,14 @@
   void SetLocationAndUpdateOverflowControlsIfNeeded(const LayoutPoint&);
 
   void SetSize(const LayoutSize& size) {
+    CheckIsNotDestroyed();
     if (size == frame_rect_.Size())
       return;
     frame_rect_.SetSize(size);
     SizeChanged();
   }
   void Move(LayoutUnit dx, LayoutUnit dy) {
+    CheckIsNotDestroyed();
     if (!dx && !dy)
       return;
     frame_rect_.Move(dx, dy);
@@ -394,8 +439,12 @@
   }
 
   // See frame_rect_.
-  LayoutRect FrameRect() const { return frame_rect_; }
+  LayoutRect FrameRect() const {
+    CheckIsNotDestroyed();
+    return frame_rect_;
+  }
   void SetFrameRect(const LayoutRect& rect) {
+    CheckIsNotDestroyed();
     SetLocation(rect.Location());
     SetSize(rect.Size());
   }
@@ -405,8 +454,12 @@
   // coordinate space, it can be treated as in either physical coordinates
   // or "physical coordinates in flipped block-flow direction", and
   // FlipForWritingMode() will do nothing on it.
-  LayoutRect BorderBoxRect() const { return LayoutRect(LayoutPoint(), Size()); }
+  LayoutRect BorderBoxRect() const {
+    CheckIsNotDestroyed();
+    return LayoutRect(LayoutPoint(), Size());
+  }
   PhysicalRect PhysicalBorderBoxRect() const {
+    CheckIsNotDestroyed();
     // This doesn't need flipping because the result would be the same.
     DCHECK_EQ(PhysicalRect(BorderBoxRect()),
               FlipForWritingMode(BorderBoxRect()));
@@ -417,6 +470,7 @@
   // TODO(crbug.com/877518): Some callers of this method may actually want
   // "physical coordinates in flipped block-flow direction".
   DISABLE_CFI_PERF PhysicalRect PhysicalPaddingBoxRect() const {
+    CheckIsNotDestroyed();
     return PhysicalRect(ClientLeft(), ClientTop(), ClientWidth(),
                         ClientHeight());
   }
@@ -425,15 +479,18 @@
   // Location() is not the correct paint offset. It's also incorrect in flipped
   // blocks writing mode.
   IntRect PixelSnappedBorderBoxRect() const {
+    CheckIsNotDestroyed();
     return IntRect(IntPoint(),
                    PixelSnappedBorderBoxSize(PhysicalOffset(Location())));
   }
   // TODO(crbug.com/962299): This method is only correct when |offset| is the
   // correct paint offset.
   IntSize PixelSnappedBorderBoxSize(const PhysicalOffset& offset) const {
+    CheckIsNotDestroyed();
     return PixelSnappedIntSize(Size(), offset.ToLayoutPoint());
   }
   IntRect BorderBoundingBox() const final {
+    CheckIsNotDestroyed();
     return PixelSnappedBorderBoxRect();
   }
 
@@ -442,12 +499,14 @@
   // TODO(crbug.com/877518): Some callers of this method may actually want
   // "physical coordinates in flipped block-flow direction".
   DISABLE_CFI_PERF PhysicalRect PhysicalContentBoxRect() const {
+    CheckIsNotDestroyed();
     return PhysicalRect(ContentLeft(), ContentTop(), ContentWidth(),
                         ContentHeight());
   }
   // TODO(crbug.com/877518): Some callers of this method may actually want
   // "physical coordinates in flipped block-flow direction".
   PhysicalOffset PhysicalContentBoxOffset() const {
+    CheckIsNotDestroyed();
     return PhysicalOffset(ContentLeft(), ContentTop());
   }
   // The content box converted to absolute coords (taking transforms into
@@ -464,6 +523,7 @@
   // does include the intrinsic padding in the content box as this is what some
   // callers expect (like getComputedStyle).
   LayoutRect ComputedCSSContentBoxRect() const {
+    CheckIsNotDestroyed();
     return LayoutRect(
         BorderLeft() + ComputedCSSPaddingLeft(),
         BorderTop() + ComputedCSSPaddingTop(),
@@ -499,6 +559,7 @@
   bool ShouldComputeLogicalWidthFromAspectRatio(
       LayoutUnit* logical_height = nullptr) const;
   bool ShouldComputeLogicalHeightFromAspectRatio() const {
+    CheckIsNotDestroyed();
     Length h = StyleRef().LogicalHeight();
     return StyleRef().AspectRatio() &&
            (h.IsAuto() ||
@@ -513,48 +574,59 @@
   // in the "physical coordinates in flipped block-flow direction" of the box.
   LayoutRect NoOverflowRect() const;
   LayoutRect LayoutOverflowRect() const {
+    CheckIsNotDestroyed();
     return LayoutOverflowIsSet()
                ? overflow_->layout_overflow->LayoutOverflowRect()
                : NoOverflowRect();
   }
   PhysicalRect PhysicalLayoutOverflowRect() const {
+    CheckIsNotDestroyed();
     return FlipForWritingMode(LayoutOverflowRect());
   }
   // TODO(crbug.com/962299): This is incorrect in some cases.
   IntRect PixelSnappedLayoutOverflowRect() const {
+    CheckIsNotDestroyed();
     return PixelSnappedIntRect(LayoutOverflowRect());
   }
   LayoutSize MaxLayoutOverflow() const {
+    CheckIsNotDestroyed();
     return LayoutSize(LayoutOverflowRect().MaxX(), LayoutOverflowRect().MaxY());
   }
 
   LayoutRect VisualOverflowRect() const;
   PhysicalRect PhysicalVisualOverflowRect() const final {
+    CheckIsNotDestroyed();
     return FlipForWritingMode(VisualOverflowRect());
   }
   LayoutUnit LogicalLeftVisualOverflow() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? VisualOverflowRect().X()
                                                 : VisualOverflowRect().Y();
   }
   LayoutUnit LogicalRightVisualOverflow() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? VisualOverflowRect().MaxX()
                                                 : VisualOverflowRect().MaxY();
   }
 
   LayoutRect SelfVisualOverflowRect() const {
+    CheckIsNotDestroyed();
     return VisualOverflowIsSet()
                ? overflow_->visual_overflow->SelfVisualOverflowRect()
                : BorderBoxRect();
   }
   PhysicalRect PhysicalSelfVisualOverflowRect() const {
+    CheckIsNotDestroyed();
     return FlipForWritingMode(SelfVisualOverflowRect());
   }
   LayoutRect ContentsVisualOverflowRect() const {
+    CheckIsNotDestroyed();
     return VisualOverflowIsSet()
                ? overflow_->visual_overflow->ContentsVisualOverflowRect()
                : LayoutRect();
   }
   PhysicalRect PhysicalContentsVisualOverflowRect() const {
+    CheckIsNotDestroyed();
     return FlipForWritingMode(ContentsVisualOverflowRect());
   }
 
@@ -572,10 +644,12 @@
 
   void AddLayoutOverflow(const LayoutRect&);
   void AddSelfVisualOverflow(const PhysicalRect& r) {
+    CheckIsNotDestroyed();
     AddSelfVisualOverflow(FlipForWritingMode(r));
   }
   void AddSelfVisualOverflow(const LayoutRect&);
   void AddContentsVisualOverflow(const PhysicalRect& r) {
+    CheckIsNotDestroyed();
     AddContentsVisualOverflow(FlipForWritingMode(r));
   }
   void AddContentsVisualOverflow(const LayoutRect&);
@@ -583,9 +657,11 @@
   void AddVisualEffectOverflow();
   LayoutRectOutsets ComputeVisualEffectOverflowOutsets();
   void AddVisualOverflowFromChild(const LayoutBox& child) {
+    CheckIsNotDestroyed();
     AddVisualOverflowFromChild(child, child.LocationOffset());
   }
   void AddLayoutOverflowFromChild(const LayoutBox& child) {
+    CheckIsNotDestroyed();
     AddLayoutOverflowFromChild(child, child.LocationOffset());
   }
   void AddVisualOverflowFromChild(const LayoutBox& child,
@@ -601,12 +677,15 @@
   virtual void UpdateAfterLayout();
 
   DISABLE_CFI_PERF LayoutUnit ContentLeft() const {
+    CheckIsNotDestroyed();
     return ClientLeft() + PaddingLeft();
   }
   DISABLE_CFI_PERF LayoutUnit ContentTop() const {
+    CheckIsNotDestroyed();
     return ClientTop() + PaddingTop();
   }
   DISABLE_CFI_PERF LayoutUnit ContentWidth() const {
+    CheckIsNotDestroyed();
     // We're dealing with LayoutUnit and saturated arithmetic here, so we need
     // to guard against negative results. The value returned from clientWidth()
     // may in itself be a victim of saturated arithmetic; e.g. if both border
@@ -617,6 +696,7 @@
         .ClampNegativeToZero();
   }
   DISABLE_CFI_PERF LayoutUnit ContentHeight() const {
+    CheckIsNotDestroyed();
     // We're dealing with LayoutUnit and saturated arithmetic here, so we need
     // to guard against negative results. The value returned from clientHeight()
     // may in itself be a victim of saturated arithmetic; e.g. if both border
@@ -627,13 +707,16 @@
         .ClampNegativeToZero();
   }
   LayoutSize ContentSize() const {
+    CheckIsNotDestroyed();
     return LayoutSize(ContentWidth(), ContentHeight());
   }
   LayoutUnit ContentLogicalWidth() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? ContentWidth()
                                                 : ContentHeight();
   }
   LayoutUnit ContentLogicalHeight() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? ContentHeight()
                                                 : ContentWidth();
   }
@@ -647,21 +730,25 @@
   LayoutUnit OverrideIntrinsicContentHeight() const;
   // Logical:
   bool HasOverrideIntrinsicContentLogicalWidth() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode()
                ? HasOverrideIntrinsicContentWidth()
                : HasOverrideIntrinsicContentHeight();
   }
   bool HasOverrideIntrinsicContentLogicalHeight() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode()
                ? HasOverrideIntrinsicContentHeight()
                : HasOverrideIntrinsicContentWidth();
   }
   LayoutUnit OverrideIntrinsicContentLogicalWidth() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode()
                ? OverrideIntrinsicContentWidth()
                : OverrideIntrinsicContentHeight();
   }
   LayoutUnit OverrideIntrinsicContentLogicalHeight() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode()
                ? OverrideIntrinsicContentHeight()
                : OverrideIntrinsicContentWidth();
@@ -675,14 +762,21 @@
   // IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines
   // (LayoutFlow) to return the remaining width on a given line (and the height
   // of a single line).
-  LayoutUnit OffsetWidth() const final { return frame_rect_.Width(); }
-  LayoutUnit OffsetHeight() const final { return frame_rect_.Height(); }
+  LayoutUnit OffsetWidth() const final {
+    CheckIsNotDestroyed();
+    return frame_rect_.Width();
+  }
+  LayoutUnit OffsetHeight() const final {
+    CheckIsNotDestroyed();
+    return frame_rect_.Height();
+  }
 
   // TODO(crbug.com/962299): This is incorrect in some cases.
   int PixelSnappedOffsetWidth(const Element*) const final;
   int PixelSnappedOffsetHeight(const Element*) const final;
 
   bool UsesOverlayScrollbars() const {
+    CheckIsNotDestroyed();
     if (StyleRef().HasPseudoElementStyle(kPseudoIdScrollbar))
       return false;
     if (GetFrame()->GetPage()->GetScrollbarTheme().UsesOverlayScrollbars())
@@ -692,6 +786,7 @@
 
   // Clamps the left scrollbar size so it is not wider than the content box.
   DISABLE_CFI_PERF LayoutUnit LogicalLeftScrollbarWidth() const {
+    CheckIsNotDestroyed();
     if (CanSkipComputeScrollbars())
       return LayoutUnit();
     else if (StyleRef().IsHorizontalWritingMode())
@@ -700,6 +795,7 @@
       return ComputeScrollbarsInternal(kClampToContentBox).top;
   }
   DISABLE_CFI_PERF LayoutUnit LogicalTopScrollbarHeight() const {
+    CheckIsNotDestroyed();
     if (CanSkipComputeScrollbars())
       return LayoutUnit();
     else if (HasFlippedBlocksWritingMode())
@@ -713,12 +809,14 @@
   // interior of an object excluding borders and scrollbars.
   // Clamps the left scrollbar size so it is not wider than the content box.
   DISABLE_CFI_PERF LayoutUnit ClientLeft() const {
+    CheckIsNotDestroyed();
     if (CanSkipComputeScrollbars())
       return BorderLeft();
     else
       return BorderLeft() + ComputeScrollbarsInternal(kClampToContentBox).left;
   }
   DISABLE_CFI_PERF LayoutUnit ClientTop() const {
+    CheckIsNotDestroyed();
     if (CanSkipComputeScrollbars())
       return BorderTop();
     else
@@ -727,12 +825,15 @@
   LayoutUnit ClientWidth() const;
   LayoutUnit ClientHeight() const;
   DISABLE_CFI_PERF LayoutUnit ClientLogicalWidth() const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? ClientWidth() : ClientHeight();
   }
   DISABLE_CFI_PERF LayoutUnit ClientLogicalHeight() const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? ClientHeight() : ClientWidth();
   }
   DISABLE_CFI_PERF LayoutUnit ClientLogicalBottom() const {
+    CheckIsNotDestroyed();
     return BorderBefore() + LogicalTopScrollbarHeight() + ClientLogicalHeight();
   }
 
@@ -764,39 +865,62 @@
       const PhysicalRect&,
       mojom::blink::ScrollIntoViewParamsPtr);
 
-  LayoutRectOutsets MarginBoxOutsets() const { return margin_box_outsets_; }
-  LayoutUnit MarginTop() const override { return margin_box_outsets_.Top(); }
+  LayoutRectOutsets MarginBoxOutsets() const {
+    CheckIsNotDestroyed();
+    return margin_box_outsets_;
+  }
+  LayoutUnit MarginTop() const override {
+    CheckIsNotDestroyed();
+    return margin_box_outsets_.Top();
+  }
   LayoutUnit MarginBottom() const override {
+    CheckIsNotDestroyed();
     return margin_box_outsets_.Bottom();
   }
-  LayoutUnit MarginLeft() const override { return margin_box_outsets_.Left(); }
+  LayoutUnit MarginLeft() const override {
+    CheckIsNotDestroyed();
+    return margin_box_outsets_.Left();
+  }
   LayoutUnit MarginRight() const override {
+    CheckIsNotDestroyed();
     return margin_box_outsets_.Right();
   }
   void SetMargin(const NGPhysicalBoxStrut&);
-  void SetMarginTop(LayoutUnit margin) { margin_box_outsets_.SetTop(margin); }
+  void SetMarginTop(LayoutUnit margin) {
+    CheckIsNotDestroyed();
+    margin_box_outsets_.SetTop(margin);
+  }
   void SetMarginBottom(LayoutUnit margin) {
+    CheckIsNotDestroyed();
     margin_box_outsets_.SetBottom(margin);
   }
-  void SetMarginLeft(LayoutUnit margin) { margin_box_outsets_.SetLeft(margin); }
+  void SetMarginLeft(LayoutUnit margin) {
+    CheckIsNotDestroyed();
+    margin_box_outsets_.SetLeft(margin);
+  }
   void SetMarginRight(LayoutUnit margin) {
+    CheckIsNotDestroyed();
     margin_box_outsets_.SetRight(margin);
   }
 
   void SetMarginBefore(LayoutUnit value,
                        const ComputedStyle* override_style = nullptr) {
+    CheckIsNotDestroyed();
     LogicalMarginToPhysicalSetter(override_style).SetBefore(value);
   }
   void SetMarginAfter(LayoutUnit value,
                       const ComputedStyle* override_style = nullptr) {
+    CheckIsNotDestroyed();
     LogicalMarginToPhysicalSetter(override_style).SetAfter(value);
   }
   void SetMarginStart(LayoutUnit value,
                       const ComputedStyle* override_style = nullptr) {
+    CheckIsNotDestroyed();
     LogicalMarginToPhysicalSetter(override_style).SetStart(value);
   }
   void SetMarginEnd(LayoutUnit value,
                     const ComputedStyle* override_style = nullptr) {
+    CheckIsNotDestroyed();
     LogicalMarginToPhysicalSetter(override_style).SetEnd(value);
   }
 
@@ -806,10 +930,20 @@
   // For a non-collapsing box, such as a leaf element, this formula will simply
   // return the margin of the element.  Blocks override the maxMarginBefore and
   // maxMarginAfter methods.
-  virtual bool IsSelfCollapsingBlock() const { return false; }
-  virtual LayoutUnit CollapsedMarginBefore() const { return MarginBefore(); }
-  virtual LayoutUnit CollapsedMarginAfter() const { return MarginAfter(); }
+  virtual bool IsSelfCollapsingBlock() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
+  virtual LayoutUnit CollapsedMarginBefore() const {
+    CheckIsNotDestroyed();
+    return MarginBefore();
+  }
+  virtual LayoutUnit CollapsedMarginAfter() const {
+    CheckIsNotDestroyed();
+    return MarginAfter();
+  }
   LayoutRectOutsets CollapsedMarginBoxLogicalOutsets() const {
+    CheckIsNotDestroyed();
     return LayoutRectOutsets(CollapsedMarginBefore(), LayoutUnit(),
                              CollapsedMarginAfter(), LayoutUnit());
   }
@@ -819,9 +953,11 @@
   FloatRect LocalBoundingBoxRectForAccessibility() const final;
 
   void SetBoxLayoutExtraInput(const BoxLayoutExtraInput* input) {
+    CheckIsNotDestroyed();
     extra_input_ = input;
   }
   const BoxLayoutExtraInput* GetBoxLayoutExtraInput() const {
+    CheckIsNotDestroyed();
     return extra_input_;
   }
 
@@ -831,6 +967,7 @@
   void Paint(const PaintInfo&) const override;
 
   virtual bool IsInSelfHitTestingPhase(HitTestAction hit_test_action) const {
+    CheckIsNotDestroyed();
     return hit_test_action == kHitTestForeground;
   }
 
@@ -887,7 +1024,10 @@
   // available inline size, rather than deducing it from the containing block
   // (and then subtract space taken up by adjacent floats).
   LayoutUnit OverrideAvailableInlineSize() const;
-  bool HasOverrideAvailableInlineSize() const { return extra_input_; }
+  bool HasOverrideAvailableInlineSize() const {
+    CheckIsNotDestroyed();
+    return extra_input_;
+  }
 
   LayoutUnit AdjustBorderBoxLogicalWidthForBoxSizing(float width) const;
   LayoutUnit AdjustBorderBoxLogicalHeightForBoxSizing(float height) const;
@@ -959,6 +1099,7 @@
   // first fragmentainer it lives in. If it only lives in one fragmentainer, 0
   // is returned.
   LayoutUnit OffsetToNextPage() const {
+    CheckIsNotDestroyed();
     return rare_data_ ? rare_data_->offset_to_next_page_ : LayoutUnit();
   }
   void SetOffsetToNextPage(LayoutUnit);
@@ -1084,16 +1225,21 @@
   };
 
   NGPhysicalFragmentList PhysicalFragments() const {
+    CheckIsNotDestroyed();
     return NGPhysicalFragmentList(layout_results_);
   }
   const NGPhysicalBoxFragment* GetPhysicalFragment(wtf_size_t i) const;
   const FragmentData* FragmentDataFromPhysicalFragment(
       const NGPhysicalBoxFragment&) const;
-  wtf_size_t PhysicalFragmentCount() const { return layout_results_.size(); }
+  wtf_size_t PhysicalFragmentCount() const {
+    CheckIsNotDestroyed();
+    return layout_results_.size();
+  }
 
   void SetSpannerPlaceholder(LayoutMultiColumnSpannerPlaceholder&);
   void ClearSpannerPlaceholder();
   LayoutMultiColumnSpannerPlaceholder* SpannerPlaceholder() const final {
+    CheckIsNotDestroyed();
     return rare_data_ ? rare_data_->spanner_placeholder_ : nullptr;
   }
 
@@ -1108,10 +1254,12 @@
   // Pagination struts are either set in front of a block-level box (here) or
   // before a line (RootInlineBox::paginationStrut()).
   LayoutUnit PaginationStrut() const {
+    CheckIsNotDestroyed();
     return rare_data_ ? rare_data_->pagination_strut_ : LayoutUnit();
   }
   void SetPaginationStrut(LayoutUnit);
   void ResetPaginationStrut() {
+    CheckIsNotDestroyed();
     if (rare_data_)
       rare_data_->pagination_strut_ = LayoutUnit();
   }
@@ -1179,19 +1327,26 @@
   void ComputeLogicalWidth(LogicalExtentComputedValues&) const;
 
   bool StretchesToViewport() const {
+    CheckIsNotDestroyed();
     return GetDocument().InQuirksMode() && StretchesToViewportInQuirksMode();
   }
 
-  virtual LayoutSize IntrinsicSize() const { return LayoutSize(); }
+  virtual LayoutSize IntrinsicSize() const {
+    CheckIsNotDestroyed();
+    return LayoutSize();
+  }
   LayoutUnit IntrinsicLogicalWidth() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? IntrinsicSize().Width()
                                                 : IntrinsicSize().Height();
   }
   LayoutUnit IntrinsicLogicalHeight() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? IntrinsicSize().Height()
                                                 : IntrinsicSize().Width();
   }
   virtual LayoutUnit IntrinsicContentLogicalHeight() const {
+    CheckIsNotDestroyed();
     return HasOverrideIntrinsicContentLogicalHeight()
                ? OverrideIntrinsicContentLogicalHeight()
                : intrinsic_content_logical_height_;
@@ -1240,6 +1395,7 @@
       LayoutUnit estimated_used_width = LayoutUnit()) const;
 
   virtual bool ShouldComputeSizeAsReplaced() const {
+    CheckIsNotDestroyed();
     return IsAtomicInlineLevel() && !IsInlineBlockOrInlineTable();
   }
 
@@ -1258,7 +1414,10 @@
 
   // Block flows subclass availableWidth/Height to handle multi column layout
   // (shrinking the width/height available to children when laying out.)
-  LayoutUnit AvailableLogicalWidth() const { return ContentLogicalWidth(); }
+  LayoutUnit AvailableLogicalWidth() const {
+    CheckIsNotDestroyed();
+    return ContentLogicalWidth();
+  }
   LayoutUnit AvailableLogicalHeight(AvailableLogicalHeightType) const;
   LayoutUnit AvailableLogicalHeightUsing(const Length&,
                                          AvailableLogicalHeightType) const;
@@ -1267,11 +1426,13 @@
   // physical width and available physical height. Relative positioning is one
   // of those cases, since left/top offsets are physical.
   LayoutUnit AvailableWidth() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode()
                ? AvailableLogicalWidth()
                : AvailableLogicalHeight(kIncludeMarginBorderPadding);
   }
   LayoutUnit AvailableHeight() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode()
                ? AvailableLogicalHeight(kIncludeMarginBorderPadding)
                : AvailableLogicalWidth();
@@ -1279,12 +1440,14 @@
 
   // Return both scrollbars and scrollbar gutters (defined by scrollbar-gutter).
   inline NGPhysicalBoxStrut ComputeScrollbars() const {
+    CheckIsNotDestroyed();
     if (CanSkipComputeScrollbars())
       return NGPhysicalBoxStrut();
     else
       return ComputeScrollbarsInternal();
   }
   inline NGBoxStrut ComputeLogicalScrollbars() const {
+    CheckIsNotDestroyed();
     if (CanSkipComputeScrollbars()) {
       return NGBoxStrut();
     } else {
@@ -1303,12 +1466,15 @@
                                        bool is_middle_click_autoscroll);
 
   DISABLE_CFI_PERF bool HasAutoVerticalScrollbar() const {
+    CheckIsNotDestroyed();
     return HasNonVisibleOverflow() && StyleRef().HasAutoVerticalScroll();
   }
   DISABLE_CFI_PERF bool HasAutoHorizontalScrollbar() const {
+    CheckIsNotDestroyed();
     return HasNonVisibleOverflow() && StyleRef().HasAutoHorizontalScroll();
   }
   DISABLE_CFI_PERF bool ScrollsOverflow() const {
+    CheckIsNotDestroyed();
     return HasNonVisibleOverflow() && StyleRef().ScrollsOverflow();
   }
   // We place block-direction scrollbar on the left only if the writing-mode
@@ -1317,24 +1483,30 @@
   // used in different contexts, e.g. the former for physical coordinate
   // contexts, and the later for logical coordinate contexts.
   bool ShouldPlaceVerticalScrollbarOnLeft() const {
+    CheckIsNotDestroyed();
     return ShouldPlaceBlockDirectionScrollbarOnLogicalLeft();
   }
   virtual bool ShouldPlaceBlockDirectionScrollbarOnLogicalLeft() const {
+    CheckIsNotDestroyed();
     return StyleRef().ShouldPlaceBlockDirectionScrollbarOnLogicalLeft();
   }
 
   bool HasScrollableOverflowX() const {
+    CheckIsNotDestroyed();
     return ScrollsOverflowX() &&
            PixelSnappedScrollWidth() != PixelSnappedClientWidth();
   }
   bool HasScrollableOverflowY() const {
+    CheckIsNotDestroyed();
     return ScrollsOverflowY() &&
            PixelSnappedScrollHeight() != PixelSnappedClientHeight();
   }
   virtual bool ScrollsOverflowX() const {
+    CheckIsNotDestroyed();
     return HasNonVisibleOverflow() && StyleRef().ScrollsOverflowX();
   }
   virtual bool ScrollsOverflowY() const {
+    CheckIsNotDestroyed();
     return HasNonVisibleOverflow() && StyleRef().ScrollsOverflowY();
   }
 
@@ -1342,6 +1514,7 @@
   // scrollable outside the context of the CSS overflow style
   virtual bool IsIntrinsicallyScrollable(
       ScrollbarOrientation orientation) const {
+    CheckIsNotDestroyed();
     return false;
   }
 
@@ -1369,9 +1542,11 @@
   virtual PaginationBreakability GetPaginationBreakability(
       FragmentationEngine) const;
   PaginationBreakability GetLegacyPaginationBreakability() const {
+    CheckIsNotDestroyed();
     return GetPaginationBreakability(kLegacyFragmentationEngine);
   }
   PaginationBreakability GetNGPaginationBreakability() const {
+    CheckIsNotDestroyed();
     return GetPaginationBreakability(kNGFragmentationEngine);
   }
 
@@ -1391,6 +1566,7 @@
   LayoutRect OverflowClipRect(const LayoutPoint& location,
                               OverlayScrollbarClipBehavior behavior =
                                   kIgnoreOverlayScrollbarSize) const {
+    CheckIsNotDestroyed();
     return OverflowClipRect(PhysicalOffset(location), behavior).ToLayoutRect();
   }
 
@@ -1417,14 +1593,21 @@
 
   const LayoutBlock& EnclosingScrollportBox() const;
 
-  virtual LayoutUnit FirstLineBoxBaseline() const { return LayoutUnit(-1); }
+  virtual LayoutUnit FirstLineBoxBaseline() const {
+    CheckIsNotDestroyed();
+    return LayoutUnit(-1);
+  }
   virtual LayoutUnit InlineBlockBaseline(LineDirectionMode) const {
+    CheckIsNotDestroyed();
     return LayoutUnit(-1);
   }  // Returns -1 if we should skip this box when computing the baseline of an
      // inline-block.
 
   bool ShrinkToAvoidFloats() const;
-  virtual bool CreatesNewFormattingContext() const { return true; }
+  virtual bool CreatesNewFormattingContext() const {
+    CheckIsNotDestroyed();
+    return true;
+  }
   bool ShouldBeConsideredAsReplaced() const;
 
   void UpdateFragmentationInfoForChild(LayoutBox&);
@@ -1432,10 +1615,12 @@
   void MarkChildForPaginationRelayoutIfNeeded(LayoutBox&, SubtreeLayoutScope&);
 
   bool IsWritingModeRoot() const {
+    CheckIsNotDestroyed();
     return !Parent() ||
            Parent()->StyleRef().GetWritingMode() != StyleRef().GetWritingMode();
   }
   bool IsOrthogonalWritingModeRoot() const {
+    CheckIsNotDestroyed();
     return Parent() &&
            Parent()->IsHorizontalWritingMode() != IsHorizontalWritingMode();
   }
@@ -1446,6 +1631,7 @@
   bool IsCustomItemShrinkToFit() const;
 
   bool IsFlexItemIncludingDeprecatedAndNG() const {
+    CheckIsNotDestroyed();
     return IsFlexItemCommon() &&
            Parent()->IsFlexibleBoxIncludingDeprecatedAndNG();
   }
@@ -1454,22 +1640,32 @@
   // IsFlexItemIncludingNG when all the callsites can handle an item with an NG
   // parent.
   bool IsFlexItem() const {
+    CheckIsNotDestroyed();
     return IsFlexItemCommon() && Parent()->IsFlexibleBox();
   }
   bool IsFlexItemIncludingNG() const {
+    CheckIsNotDestroyed();
     return IsFlexItemCommon() && Parent()->IsFlexibleBoxIncludingNG();
   }
   bool IsFlexItemCommon() const {
+    CheckIsNotDestroyed();
     return !IsInline() && !IsOutOfFlowPositioned() && Parent();
   }
 
   bool IsGridItemIncludingNG() const {
+    CheckIsNotDestroyed();
     return IsGridItem() || (Parent() && Parent()->IsLayoutNGGrid());
   }
 
-  bool IsGridItem() const { return Parent() && Parent()->IsLayoutGrid(); }
+  bool IsGridItem() const {
+    CheckIsNotDestroyed();
+    return Parent() && Parent()->IsLayoutGrid();
+  }
 
-  bool IsMathItem() const { return Parent() && Parent()->IsMathML(); }
+  bool IsMathItem() const {
+    CheckIsNotDestroyed();
+    return Parent() && Parent()->IsMathML();
+  }
 
   LayoutUnit LineHeight(
       bool first_line,
@@ -1488,6 +1684,7 @@
   WARN_UNUSED_RESULT LayoutUnit
   FlipForWritingMode(LayoutUnit position,
                      LayoutUnit width = LayoutUnit()) const {
+    CheckIsNotDestroyed();
     // The offset is in the block direction (y for horizontal writing modes, x
     // for vertical writing modes).
     if (LIKELY(!HasFlippedBlocksWritingMode()))
@@ -1500,9 +1697,11 @@
 
   WARN_UNUSED_RESULT LayoutPoint
   DeprecatedFlipForWritingMode(const LayoutPoint& position) const {
+    CheckIsNotDestroyed();
     return LayoutPoint(FlipForWritingMode(position.X()), position.Y());
   }
   void DeprecatedFlipForWritingMode(LayoutRect& rect) const {
+    CheckIsNotDestroyed();
     if (LIKELY(!HasFlippedBlocksWritingMode()))
       return;
     rect = FlipForWritingMode(rect).ToLayoutRect();
@@ -1512,6 +1711,7 @@
   // that container, or LocationContainer() otherwise.
   PhysicalOffset PhysicalLocation(
       const LayoutBox* flipped_blocks_container = nullptr) const {
+    CheckIsNotDestroyed();
     return PhysicalLocationInternal(flipped_blocks_container
                                         ? flipped_blocks_container
                                         : LocationContainer());
@@ -1523,6 +1723,7 @@
 
   LayoutRect LogicalVisualOverflowRectForPropagation() const;
   LayoutRect VisualOverflowRectForPropagation() const {
+    CheckIsNotDestroyed();
     return RectForOverflowPropagation(VisualOverflowRect());
   }
   LayoutRect LogicalLayoutOverflowRectForPropagation(
@@ -1530,13 +1731,20 @@
   LayoutRect LayoutOverflowRectForPropagation(LayoutObject* container) const;
 
   bool HasSelfVisualOverflow() const {
+    CheckIsNotDestroyed();
     return VisualOverflowIsSet() &&
            !BorderBoxRect().Contains(
                overflow_->visual_overflow->SelfVisualOverflowRect());
   }
 
-  bool HasVisualOverflow() const { return VisualOverflowIsSet(); }
-  bool HasLayoutOverflow() const { return LayoutOverflowIsSet(); }
+  bool HasVisualOverflow() const {
+    CheckIsNotDestroyed();
+    return VisualOverflowIsSet();
+  }
+  bool HasLayoutOverflow() const {
+    CheckIsNotDestroyed();
+    return LayoutOverflowIsSet();
+  }
 
   // Return true if re-laying out the containing block of this object means that
   // we need to recalculate the preferred min/max logical widths of this object.
@@ -1600,23 +1808,27 @@
 
   virtual LayoutBox* CreateAnonymousBoxWithSameTypeAs(
       const LayoutObject*) const {
+    CheckIsNotDestroyed();
     NOTREACHED();
     return nullptr;
   }
 
   bool HasSameDirectionAs(const LayoutBox* object) const {
+    CheckIsNotDestroyed();
     return StyleRef().Direction() == object->StyleRef().Direction();
   }
 
   ShapeOutsideInfo* GetShapeOutsideInfo() const;
 
   void MarkShapeOutsideDependentsForLayout() {
+    CheckIsNotDestroyed();
     if (IsFloating())
       RemoveFloatingOrPositionedChildFromBlockLists();
   }
 
   void SetIntrinsicContentLogicalHeight(
       LayoutUnit intrinsic_content_logical_height) const {
+    CheckIsNotDestroyed();
     intrinsic_content_logical_height_ = intrinsic_content_logical_height;
   }
 
@@ -1630,6 +1842,7 @@
                           MapCoordinatesFlags) const override;
 
   LayoutBlock* PercentHeightContainer() const {
+    CheckIsNotDestroyed();
     return rare_data_ ? rare_data_->percent_height_container_ : nullptr;
   }
   void SetPercentHeightContainer(LayoutBlock*);
@@ -1658,6 +1871,7 @@
   virtual bool HitTestOverflowControl(HitTestResult&,
                                       const HitTestLocation&,
                                       const PhysicalOffset&) const {
+    CheckIsNotDestroyed();
     return false;
   }
 
@@ -1710,27 +1924,35 @@
   };
 
   MutableForPainting GetMutableForPainting() const {
+    CheckIsNotDestroyed();
     return MutableForPainting(*this);
   }
 
-  LayoutSize PreviousSize() const { return previous_size_; }
+  LayoutSize PreviousSize() const {
+    CheckIsNotDestroyed();
+    return previous_size_;
+  }
   PhysicalRect PreviousPhysicalContentBoxRect() const {
+    CheckIsNotDestroyed();
     return rare_data_ && rare_data_->has_previous_content_box_rect_
                ? rare_data_->previous_physical_content_box_rect_
                : PhysicalRect(PhysicalOffset(), PreviousSize());
   }
   bool PreviouslyHadNonVisibleOverflow() const {
+    CheckIsNotDestroyed();
     return overflow_ && overflow_->previous_overflow_data &&
            overflow_->previous_overflow_data
                ->previously_had_non_visible_overflow;
   }
   PhysicalRect PreviousPhysicalLayoutOverflowRect() const {
+    CheckIsNotDestroyed();
     return overflow_ && overflow_->previous_overflow_data
                ? overflow_->previous_overflow_data
                      ->previous_physical_layout_overflow_rect
                : PhysicalRect(PhysicalOffset(), PreviousSize());
   }
   PhysicalRect PreviousPhysicalSelfVisualOverflowRect() const {
+    CheckIsNotDestroyed();
     return overflow_ && overflow_->previous_overflow_data
                ? overflow_->previous_overflow_data
                      ->previous_physical_self_visual_overflow_rect
@@ -1769,6 +1991,7 @@
       bool depends_on_percentage_block_size,
       bool child_depends_on_percentage_block_size,
       const MinMaxSizes* sizes) {
+    CheckIsNotDestroyed();
     intrinsic_logical_widths_percentage_resolution_block_size_ =
         intrinsic_logical_widths_percentage_resolution_block_size;
     SetIntrinsicLogicalWidthsDependsOnPercentageBlockSize(
@@ -1786,6 +2009,7 @@
   // For non-LayoutNG code this is always LayoutUnit::Min(), and should not be
   // used for caching purposes.
   LayoutUnit IntrinsicLogicalWidthsPercentageResolutionBlockSize() const {
+    CheckIsNotDestroyed();
     return intrinsic_logical_widths_percentage_resolution_block_size_;
   }
 
@@ -1797,6 +2021,7 @@
   // a small region of a canvas changes.
   void InvalidatePaintRectangle(const PhysicalRect&);
   bool HasPartialInvalidationRect() const {
+    CheckIsNotDestroyed();
     return rare_data_ && !rare_data_->partial_invalidation_rect_.IsEmpty();
   }
 
@@ -1819,6 +2044,7 @@
 
   virtual ItemPosition SelfAlignmentNormalBehavior(
       const LayoutBox* child = nullptr) const {
+    CheckIsNotDestroyed();
     DCHECK(!child);
     return ItemPosition::kStretch;
   }
@@ -1907,13 +2133,16 @@
 
  private:
   bool HasFragmentItems() const {
+    CheckIsNotDestroyed();
     return ChildrenInline() && PhysicalFragments().HasFragmentItems();
   }
 
   inline bool LayoutOverflowIsSet() const {
+    CheckIsNotDestroyed();
     return overflow_ && overflow_->layout_overflow;
   }
   inline bool VisualOverflowIsSet() const {
+    CheckIsNotDestroyed();
     return overflow_ && overflow_->visual_overflow;
   }
 
@@ -1962,6 +2191,7 @@
                                   LayoutUnit& margin_end) const;
 
   LayoutBoxRareData& EnsureRareData() {
+    CheckIsNotDestroyed();
     if (!rare_data_)
       rare_data_ = MakeGarbageCollected<LayoutBoxRareData>();
     return *rare_data_.Get();
@@ -1998,6 +2228,7 @@
   RasterEffectOutset VisualRectOutsetForRasterEffects() const override;
 
   inline bool CanSkipComputeScrollbars() const {
+    CheckIsNotDestroyed();
     return (StyleRef().IsOverflowVisibleAlongBothAxes() ||
             !HasNonVisibleOverflow() ||
             (GetScrollableArea() &&
@@ -2015,12 +2246,14 @@
       LayoutUnit position,
       LayoutUnit width,
       const LayoutBox* box_for_flipping) const final {
+    CheckIsNotDestroyed();
     DCHECK(!box_for_flipping || box_for_flipping == this);
     return FlipForWritingMode(position, width);
   }
 
   PhysicalOffset PhysicalLocationInternal(
       const LayoutBox* container_box) const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(container_box, LocationContainer());
     if (LIKELY(!container_box || !container_box->HasFlippedBlocksWritingMode()))
       return PhysicalOffset(Location());
@@ -2064,6 +2297,7 @@
  private:
   LogicalToPhysicalSetter<LayoutUnit, LayoutBox> LogicalMarginToPhysicalSetter(
       const ComputedStyle* override_style) {
+    CheckIsNotDestroyed();
     const auto& style = override_style ? *override_style : StyleRef();
     return LogicalToPhysicalSetter<LayoutUnit, LayoutBox>(
         style.GetWritingMode(), style.Direction(), *this,
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 67f1e80..644c59d 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
@@ -86,6 +86,7 @@
 }
 
 void LayoutBoxModelObject::ContentChanged(ContentChangeType change_type) {
+  CheckIsNotDestroyed();
   if (!HasLayer())
     return;
 
@@ -96,6 +97,7 @@
     : LayoutObject(node) {}
 
 bool LayoutBoxModelObject::UsesCompositedScrolling() const {
+  CheckIsNotDestroyed();
   return IsScrollContainer() && HasLayer() &&
          Layer()->GetScrollableArea()->UsesCompositedScrolling();
 }
@@ -112,6 +114,7 @@
 
 BackgroundPaintLocation
 LayoutBoxModelObject::ComputeBackgroundPaintLocationIfComposited() const {
+  CheckIsNotDestroyed();
   bool may_have_scrolling_layers_without_scrolling = IsA<LayoutView>(this);
   const auto* scrollable_area = GetScrollableArea();
   bool scrolls_overflow = scrollable_area && scrollable_area->ScrollsOverflow();
@@ -204,6 +207,7 @@
 }
 
 void LayoutBoxModelObject::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   // A continuation of this LayoutObject should be destroyed at subclasses.
   DCHECK(!Continuation());
 
@@ -231,6 +235,7 @@
 
 void LayoutBoxModelObject::StyleWillChange(StyleDifference diff,
                                            const ComputedStyle& new_style) {
+  CheckIsNotDestroyed();
   // SPv1:
   // This object's layer may begin or cease to be stacked or stacking context,
   // in which case the paint invalidation container of this object and
@@ -267,6 +272,7 @@
 DISABLE_CFI_PERF
 void LayoutBoxModelObject::StyleDidChange(StyleDifference diff,
                                           const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   bool had_transform_related_property = HasTransformRelatedProperty();
   bool had_filter_inducing_property = HasFilterInducingProperty();
   bool had_non_initial_backdrop_filter = HasNonInitialBackdropFilter();
@@ -515,6 +521,7 @@
 }
 
 void LayoutBoxModelObject::InvalidateStickyConstraints() {
+  CheckIsNotDestroyed();
   PaintLayer* enclosing = EnclosingLayer();
 
   if (PaintLayerScrollableArea* scrollable_area =
@@ -539,6 +546,7 @@
 }
 
 void LayoutBoxModelObject::CreateLayerAfterStyleChange() {
+  CheckIsNotDestroyed();
   DCHECK(!HasLayer() && !Layer());
   GetMutableForPainting().FirstFragment().SetLayer(
       std::make_unique<PaintLayer>(*this));
@@ -552,6 +560,7 @@
 }
 
 void LayoutBoxModelObject::DestroyLayer() {
+  CheckIsNotDestroyed();
   DCHECK(HasLayer() && Layer());
   SetHasLayer(false);
   GetMutableForPainting().FirstFragment().SetLayer(nullptr);
@@ -562,10 +571,12 @@
 }
 
 bool LayoutBoxModelObject::HasSelfPaintingLayer() const {
+  CheckIsNotDestroyed();
   return Layer() && Layer()->IsSelfPaintingLayer();
 }
 
 PaintLayerScrollableArea* LayoutBoxModelObject::GetScrollableArea() const {
+  CheckIsNotDestroyed();
   return Layer() ? Layer()->GetScrollableArea() : nullptr;
 }
 
@@ -573,6 +584,7 @@
     Vector<PhysicalRect>& rects,
     const PhysicalOffset& additional_offset,
     NGOutlineType include_block_overflows) const {
+  CheckIsNotDestroyed();
   for (LayoutObject* child = SlowFirstChild(); child;
        child = child->NextSibling()) {
     // Outlines of out-of-flow positioned descendants are handled in
@@ -598,6 +610,7 @@
     Vector<PhysicalRect>& rects,
     const PhysicalOffset& additional_offset,
     NGOutlineType include_block_overflows) const {
+  CheckIsNotDestroyed();
   if (descendant.IsText() || descendant.IsListMarkerForNormalContent())
     return;
 
@@ -637,11 +650,13 @@
 void LayoutBoxModelObject::AbsoluteQuadsForSelf(
     Vector<FloatQuad>& quads,
     MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   NOTREACHED();
 }
 
 void LayoutBoxModelObject::AbsoluteQuads(Vector<FloatQuad>& quads,
                                          MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   AbsoluteQuadsForSelf(quads, mode);
 
   // Iterate over continuations, avoiding recursion in case there are
@@ -659,6 +674,7 @@
 }
 
 void LayoutBoxModelObject::UpdateFromStyle() {
+  CheckIsNotDestroyed();
   const ComputedStyle& style_to_use = StyleRef();
   SetHasBoxDecorationBackground(style_to_use.HasBoxDecorationBackground());
   SetInline(style_to_use.IsDisplayInlineType());
@@ -669,6 +685,7 @@
 
 LayoutBlock* LayoutBoxModelObject::ContainingBlockForAutoHeightDetection(
     const Length& logical_height) const {
+  CheckIsNotDestroyed();
   // For percentage heights: The percentage is calculated with respect to the
   // height of the generated box's containing block. If the height of the
   // containing block is not specified explicitly (i.e., it depends on content
@@ -703,6 +720,7 @@
 
 bool LayoutBoxModelObject::HasAutoHeightOrContainingBlockWithAutoHeight(
     RegisterPercentageDescendant register_percentage_descendant) const {
+  CheckIsNotDestroyed();
   // TODO(rego): Check if we can somehow reuse LayoutBlock::
   // availableLogicalHeightForPercentageComputation() (see crbug.com/635655).
   const LayoutBox* this_box = IsBox() ? ToLayoutBox(this) : nullptr;
@@ -769,6 +787,7 @@
 }
 
 PhysicalOffset LayoutBoxModelObject::RelativePositionOffset() const {
+  CheckIsNotDestroyed();
   DCHECK(IsRelPositioned());
   LayoutBlock* containing_block = ContainingBlock();
 
@@ -898,6 +917,7 @@
 }
 
 void LayoutBoxModelObject::UpdateStickyPositionConstraints() const {
+  CheckIsNotDestroyed();
   DCHECK(StyleRef().HasStickyConstrainedPosition());
 
   const PhysicalSize constraining_size = ComputeStickyConstrainingRect().size;
@@ -1076,6 +1096,7 @@
 }
 
 bool LayoutBoxModelObject::IsSlowRepaintConstrainedObject() const {
+  CheckIsNotDestroyed();
   if (!HasLayer() || (StyleRef().GetPosition() != EPosition::kFixed &&
                       StyleRef().GetPosition() != EPosition::kSticky)) {
     return false;
@@ -1101,6 +1122,7 @@
 }
 
 PhysicalRect LayoutBoxModelObject::ComputeStickyConstrainingRect() const {
+  CheckIsNotDestroyed();
   LayoutBox* enclosing_clipping_box =
       Layer()->AncestorOverflowLayer()->GetLayoutBox();
   DCHECK(enclosing_clipping_box);
@@ -1122,6 +1144,7 @@
 }
 
 PhysicalOffset LayoutBoxModelObject::StickyPositionOffset() const {
+  CheckIsNotDestroyed();
   // TODO(chrishtr): StickyPositionOffset depends on compositing at present,
   // but there are callsites within Layout for it.
 
@@ -1150,6 +1173,7 @@
 PhysicalOffset LayoutBoxModelObject::AdjustedPositionRelativeTo(
     const PhysicalOffset& start_point,
     const Element* offset_parent) const {
+  CheckIsNotDestroyed();
   // If the element is the HTML body element or doesn't have a parent
   // return 0 and stop this algorithm.
   if (IsBody() || !Parent())
@@ -1216,6 +1240,7 @@
 }
 
 PhysicalOffset LayoutBoxModelObject::OffsetForInFlowPosition() const {
+  CheckIsNotDestroyed();
   if (IsRelPositioned())
     return RelativePositionOffset();
 
@@ -1226,28 +1251,33 @@
 }
 
 LayoutUnit LayoutBoxModelObject::OffsetLeft(const Element* parent) const {
+  CheckIsNotDestroyed();
   // Note that LayoutInline and LayoutBox override this to pass a different
   // startPoint to adjustedPositionRelativeTo.
   return AdjustedPositionRelativeTo(PhysicalOffset(), parent).left;
 }
 
 LayoutUnit LayoutBoxModelObject::OffsetTop(const Element* parent) const {
+  CheckIsNotDestroyed();
   // Note that LayoutInline and LayoutBox override this to pass a different
   // startPoint to adjustedPositionRelativeTo.
   return AdjustedPositionRelativeTo(PhysicalOffset(), parent).top;
 }
 
 int LayoutBoxModelObject::PixelSnappedOffsetWidth(const Element* parent) const {
+  CheckIsNotDestroyed();
   return SnapSizeToPixel(OffsetWidth(), OffsetLeft(parent));
 }
 
 int LayoutBoxModelObject::PixelSnappedOffsetHeight(
     const Element* parent) const {
+  CheckIsNotDestroyed();
   return SnapSizeToPixel(OffsetHeight(), OffsetTop(parent));
 }
 
 LayoutUnit LayoutBoxModelObject::ComputedCSSPadding(
     const Length& padding) const {
+  CheckIsNotDestroyed();
   LayoutUnit w;
   if (padding.IsPercentOrCalc())
     w = ContainingBlockLogicalWidthForContent();
@@ -1255,14 +1285,17 @@
 }
 
 LayoutUnit LayoutBoxModelObject::ContainingBlockLogicalWidthForContent() const {
+  CheckIsNotDestroyed();
   return ContainingBlock()->AvailableLogicalWidth();
 }
 
 LayoutBoxModelObject* LayoutBoxModelObject::Continuation() const {
+  CheckIsNotDestroyed();
   return GetContinuationMap().at(this);
 }
 
 void LayoutBoxModelObject::SetContinuation(LayoutBoxModelObject* continuation) {
+  CheckIsNotDestroyed();
   if (continuation) {
     DCHECK(continuation->IsLayoutInline() || continuation->IsLayoutBlockFlow());
     GetContinuationMap().Set(this, continuation);
@@ -1274,6 +1307,7 @@
 LayoutRect LayoutBoxModelObject::LocalCaretRectForEmptyElement(
     LayoutUnit width,
     LayoutUnit text_indent_offset) const {
+  CheckIsNotDestroyed();
   DCHECK(!SlowFirstChild() || SlowFirstChild()->IsPseudoElement());
 
   // FIXME: This does not take into account either :first-line or :first-letter
@@ -1355,6 +1389,7 @@
 const LayoutObject* LayoutBoxModelObject::PushMappingToContainer(
     const LayoutBoxModelObject* ancestor_to_stop_at,
     LayoutGeometryMap& geometry_map) const {
+  CheckIsNotDestroyed();
   DCHECK_NE(ancestor_to_stop_at, this);
 
   AncestorSkipInfo skip_info(ancestor_to_stop_at);
@@ -1426,6 +1461,7 @@
     LayoutObject* child,
     LayoutObject* before_child,
     bool full_remove_insert) {
+  CheckIsNotDestroyed();
   // We assume that callers have cleared their positioned objects list for child
   // moves (!fullRemoveInsert) so the positioned layoutObject maps don't become
   // stale. It would be too slow to do the map lookup on each call.
@@ -1471,6 +1507,7 @@
     LayoutObject* end_child,
     LayoutObject* before_child,
     bool full_remove_insert) {
+  CheckIsNotDestroyed();
   // This condition is rarely hit since this function is usually called on
   // anonymous blocks which can no longer carry positioned objects (see r120761)
   // or when fullRemoveInsert is false.
@@ -1494,6 +1531,7 @@
 
 bool LayoutBoxModelObject::BackgroundTransfersToView(
     const ComputedStyle* document_element_style) const {
+  CheckIsNotDestroyed();
   // In our painter implementation, ViewPainter instead of the painter of the
   // layout object of the document element paints the view background.
   if (IsDocumentElement())
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.h b/third_party/blink/renderer/core/layout/layout_box_model_object.h
index ad1c091..fdd3d6e 100644
--- a/third_party/blink/renderer/core/layout/layout_box_model_object.h
+++ b/third_party/blink/renderer/core/layout/layout_box_model_object.h
@@ -135,6 +135,7 @@
 
   PhysicalOffset RelativePositionOffset() const;
   LayoutSize RelativePositionLogicalOffset() const {
+    CheckIsNotDestroyed();
     // TODO(layout-dev): This seems incorrect in flipped blocks writing mode,
     // but seems for legacy layout only.
     auto offset = RelativePositionOffset().ToLayoutSize();
@@ -161,16 +162,21 @@
   virtual LayoutUnit OffsetHeight() const = 0;
 
   int PixelSnappedOffsetLeft(const Element* parent) const {
+    CheckIsNotDestroyed();
     return RoundToInt(OffsetLeft(parent));
   }
   int PixelSnappedOffsetTop(const Element* parent) const {
+    CheckIsNotDestroyed();
     return RoundToInt(OffsetTop(parent));
   }
   virtual int PixelSnappedOffsetWidth(const Element*) const;
   virtual int PixelSnappedOffsetHeight(const Element*) const;
 
   bool HasSelfPaintingLayer() const;
-  PaintLayer* Layer() const { return FirstFragment().Layer(); }
+  PaintLayer* Layer() const {
+    CheckIsNotDestroyed();
+    return FirstFragment().Layer();
+  }
   // The type of PaintLayer to instantiate. Any value returned from this
   // function other than NoPaintLayer will lead to a PaintLayer being created.
   virtual PaintLayerType LayerTypeRequired() const = 0;
@@ -192,33 +198,43 @@
 
   // These return the CSS computed padding values.
   LayoutUnit ComputedCSSPaddingTop() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPadding(StyleRef().PaddingTop());
   }
   LayoutUnit ComputedCSSPaddingBottom() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPadding(StyleRef().PaddingBottom());
   }
   LayoutUnit ComputedCSSPaddingLeft() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPadding(StyleRef().PaddingLeft());
   }
   LayoutUnit ComputedCSSPaddingRight() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPadding(StyleRef().PaddingRight());
   }
   LayoutUnit ComputedCSSPaddingBefore() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPadding(StyleRef().PaddingBefore());
   }
   LayoutUnit ComputedCSSPaddingAfter() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPadding(StyleRef().PaddingAfter());
   }
   LayoutUnit ComputedCSSPaddingStart() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPadding(StyleRef().PaddingStart());
   }
   LayoutUnit ComputedCSSPaddingEnd() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPadding(StyleRef().PaddingEnd());
   }
   LayoutUnit ComputedCSSPaddingOver() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPadding(StyleRef().PaddingOver());
   }
   LayoutUnit ComputedCSSPaddingUnder() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPadding(StyleRef().PaddingUnder());
   }
 
@@ -226,117 +242,190 @@
   // - Table cells override them to include the intrinsic padding (see
   //   explanations in LayoutTableCell).
   // - Table override them to exclude padding with collapsing borders.
-  virtual LayoutUnit PaddingTop() const { return ComputedCSSPaddingTop(); }
+  virtual LayoutUnit PaddingTop() const {
+    CheckIsNotDestroyed();
+    return ComputedCSSPaddingTop();
+  }
   virtual LayoutUnit PaddingBottom() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPaddingBottom();
   }
-  virtual LayoutUnit PaddingLeft() const { return ComputedCSSPaddingLeft(); }
-  virtual LayoutUnit PaddingRight() const { return ComputedCSSPaddingRight(); }
+  virtual LayoutUnit PaddingLeft() const {
+    CheckIsNotDestroyed();
+    return ComputedCSSPaddingLeft();
+  }
+  virtual LayoutUnit PaddingRight() const {
+    CheckIsNotDestroyed();
+    return ComputedCSSPaddingRight();
+  }
 
   LayoutUnit PaddingBefore() const {
+    CheckIsNotDestroyed();
     return PhysicalPaddingToLogical().Before();
   }
-  LayoutUnit PaddingAfter() const { return PhysicalPaddingToLogical().After(); }
-  LayoutUnit PaddingStart() const { return PhysicalPaddingToLogical().Start(); }
-  LayoutUnit PaddingEnd() const { return PhysicalPaddingToLogical().End(); }
-  LayoutUnit PaddingOver() const { return PhysicalPaddingToLogical().Over(); }
-  LayoutUnit PaddingUnder() const { return PhysicalPaddingToLogical().Under(); }
+  LayoutUnit PaddingAfter() const {
+    CheckIsNotDestroyed();
+    return PhysicalPaddingToLogical().After();
+  }
+  LayoutUnit PaddingStart() const {
+    CheckIsNotDestroyed();
+    return PhysicalPaddingToLogical().Start();
+  }
+  LayoutUnit PaddingEnd() const {
+    CheckIsNotDestroyed();
+    return PhysicalPaddingToLogical().End();
+  }
+  LayoutUnit PaddingOver() const {
+    CheckIsNotDestroyed();
+    return PhysicalPaddingToLogical().Over();
+  }
+  LayoutUnit PaddingUnder() const {
+    CheckIsNotDestroyed();
+    return PhysicalPaddingToLogical().Under();
+  }
 
   virtual LayoutUnit BorderTop() const {
+    CheckIsNotDestroyed();
     return LayoutUnit(StyleRef().BorderTopWidth());
   }
   virtual LayoutUnit BorderBottom() const {
+    CheckIsNotDestroyed();
     return LayoutUnit(StyleRef().BorderBottomWidth());
   }
   virtual LayoutUnit BorderLeft() const {
+    CheckIsNotDestroyed();
     return LayoutUnit(StyleRef().BorderLeftWidth());
   }
   virtual LayoutUnit BorderRight() const {
+    CheckIsNotDestroyed();
     return LayoutUnit(StyleRef().BorderRightWidth());
   }
 
-  LayoutUnit BorderBefore() const { return PhysicalBorderToLogical().Before(); }
-  LayoutUnit BorderAfter() const { return PhysicalBorderToLogical().After(); }
-  LayoutUnit BorderStart() const { return PhysicalBorderToLogical().Start(); }
-  LayoutUnit BorderEnd() const { return PhysicalBorderToLogical().End(); }
-  LayoutUnit BorderOver() const { return PhysicalBorderToLogical().Over(); }
-  LayoutUnit BorderUnder() const { return PhysicalBorderToLogical().Under(); }
+  LayoutUnit BorderBefore() const {
+    CheckIsNotDestroyed();
+    return PhysicalBorderToLogical().Before();
+  }
+  LayoutUnit BorderAfter() const {
+    CheckIsNotDestroyed();
+    return PhysicalBorderToLogical().After();
+  }
+  LayoutUnit BorderStart() const {
+    CheckIsNotDestroyed();
+    return PhysicalBorderToLogical().Start();
+  }
+  LayoutUnit BorderEnd() const {
+    CheckIsNotDestroyed();
+    return PhysicalBorderToLogical().End();
+  }
+  LayoutUnit BorderOver() const {
+    CheckIsNotDestroyed();
+    return PhysicalBorderToLogical().Over();
+  }
+  LayoutUnit BorderUnder() const {
+    CheckIsNotDestroyed();
+    return PhysicalBorderToLogical().Under();
+  }
 
-  LayoutUnit BorderWidth() const { return BorderLeft() + BorderRight(); }
-  LayoutUnit BorderHeight() const { return BorderTop() + BorderBottom(); }
+  LayoutUnit BorderWidth() const {
+    CheckIsNotDestroyed();
+    return BorderLeft() + BorderRight();
+  }
+  LayoutUnit BorderHeight() const {
+    CheckIsNotDestroyed();
+    return BorderTop() + BorderBottom();
+  }
 
   LayoutRectOutsets BorderBoxOutsets() const {
+    CheckIsNotDestroyed();
     return LayoutRectOutsets(BorderTop(), BorderRight(), BorderBottom(),
                              BorderLeft());
   }
 
   LayoutRectOutsets PaddingOutsets() const {
+    CheckIsNotDestroyed();
     return LayoutRectOutsets(PaddingTop(), PaddingRight(), PaddingBottom(),
                              PaddingLeft());
   }
 
   // Insets from the border box to the inside of the border.
   LayoutRectOutsets BorderInsets() const {
+    CheckIsNotDestroyed();
     return LayoutRectOutsets(-BorderTop(), -BorderRight(), -BorderBottom(),
                              -BorderLeft());
   }
 
   LayoutUnit BorderAndPaddingStart() const {
+    CheckIsNotDestroyed();
     return BorderStart() + PaddingStart();
   }
   DISABLE_CFI_PERF LayoutUnit BorderAndPaddingBefore() const {
+    CheckIsNotDestroyed();
     return BorderBefore() + PaddingBefore();
   }
   DISABLE_CFI_PERF LayoutUnit BorderAndPaddingAfter() const {
+    CheckIsNotDestroyed();
     return BorderAfter() + PaddingAfter();
   }
   LayoutUnit BorderAndPaddingOver() const {
+    CheckIsNotDestroyed();
     return BorderOver() + PaddingOver();
   }
   LayoutUnit BorderAndPaddingUnder() const {
+    CheckIsNotDestroyed();
     return BorderUnder() + PaddingUnder();
   }
 
   DISABLE_CFI_PERF LayoutUnit BorderAndPaddingHeight() const {
+    CheckIsNotDestroyed();
     return BorderTop() + BorderBottom() + PaddingTop() + PaddingBottom();
   }
   DISABLE_CFI_PERF LayoutUnit BorderAndPaddingWidth() const {
+    CheckIsNotDestroyed();
     return BorderLeft() + BorderRight() + PaddingLeft() + PaddingRight();
   }
   DISABLE_CFI_PERF LayoutUnit BorderAndPaddingLogicalHeight() const {
+    CheckIsNotDestroyed();
     return (StyleRef().HasBorder() || StyleRef().MayHavePadding())
                ? BorderAndPaddingBefore() + BorderAndPaddingAfter()
                : LayoutUnit();
   }
   DISABLE_CFI_PERF LayoutUnit BorderAndPaddingLogicalWidth() const {
+    CheckIsNotDestroyed();
     return BorderStart() + BorderEnd() + PaddingStart() + PaddingEnd();
   }
   DISABLE_CFI_PERF LayoutUnit BorderAndPaddingLogicalLeft() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsHorizontalWritingMode() ? BorderLeft() + PaddingLeft()
                                                 : BorderTop() + PaddingTop();
   }
 
   LayoutUnit BorderLogicalLeft() const {
+    CheckIsNotDestroyed();
     return LayoutUnit(StyleRef().IsHorizontalWritingMode() ? BorderLeft()
                                                            : BorderTop());
   }
   LayoutUnit BorderLogicalRight() const {
+    CheckIsNotDestroyed();
     return LayoutUnit(StyleRef().IsHorizontalWritingMode() ? BorderRight()
                                                            : BorderBottom());
   }
 
   LayoutUnit PaddingLogicalWidth() const {
+    CheckIsNotDestroyed();
     return PaddingStart() + PaddingEnd();
   }
   LayoutUnit PaddingLogicalHeight() const {
+    CheckIsNotDestroyed();
     return PaddingBefore() + PaddingAfter();
   }
 
   LayoutUnit CollapsedBorderAndCSSPaddingLogicalWidth() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPaddingStart() + ComputedCSSPaddingEnd() + BorderStart() +
            BorderEnd();
   }
   LayoutUnit CollapsedBorderAndCSSPaddingLogicalHeight() const {
+    CheckIsNotDestroyed();
     return ComputedCSSPaddingBefore() + ComputedCSSPaddingAfter() +
            BorderBefore() + BorderAfter();
   }
@@ -347,53 +436,69 @@
   virtual LayoutUnit MarginRight() const = 0;
 
   LayoutUnit MarginBefore(const ComputedStyle* other_style = nullptr) const {
+    CheckIsNotDestroyed();
     return PhysicalMarginToLogical(other_style).Before();
   }
   LayoutUnit MarginAfter(const ComputedStyle* other_style = nullptr) const {
+    CheckIsNotDestroyed();
     return PhysicalMarginToLogical(other_style).After();
   }
   LayoutUnit MarginStart(const ComputedStyle* other_style = nullptr) const {
+    CheckIsNotDestroyed();
     return PhysicalMarginToLogical(other_style).Start();
   }
   LayoutUnit MarginEnd(const ComputedStyle* other_style = nullptr) const {
+    CheckIsNotDestroyed();
     return PhysicalMarginToLogical(other_style).End();
   }
   LayoutUnit MarginLineLeft() const {
+    CheckIsNotDestroyed();
     return PhysicalMarginToLogical(nullptr).LineLeft();
   }
   LayoutUnit MarginLineRight() const {
+    CheckIsNotDestroyed();
     return PhysicalMarginToLogical(nullptr).LineRight();
   }
   LayoutUnit MarginOver() const {
+    CheckIsNotDestroyed();
     return PhysicalMarginToLogical(nullptr).Over();
   }
   LayoutUnit MarginUnder() const {
+    CheckIsNotDestroyed();
     return PhysicalMarginToLogical(nullptr).Under();
   }
 
   DISABLE_CFI_PERF LayoutUnit MarginHeight() const {
+    CheckIsNotDestroyed();
     return MarginTop() + MarginBottom();
   }
   DISABLE_CFI_PERF LayoutUnit MarginWidth() const {
+    CheckIsNotDestroyed();
     return MarginLeft() + MarginRight();
   }
   DISABLE_CFI_PERF LayoutUnit MarginLogicalHeight() const {
+    CheckIsNotDestroyed();
     return MarginBefore() + MarginAfter();
   }
   DISABLE_CFI_PERF LayoutUnit MarginLogicalWidth() const {
+    CheckIsNotDestroyed();
     return MarginStart() + MarginEnd();
   }
 
   bool HasInlineDirectionBordersPaddingOrMargin() const {
+    CheckIsNotDestroyed();
     return HasInlineDirectionBordersOrPadding() || MarginStart() || MarginEnd();
   }
   bool HasInlineDirectionBordersOrPadding() const {
+    CheckIsNotDestroyed();
     return BorderStart() || BorderEnd() || PaddingStart() || PaddingEnd();
   }
 
   virtual LayoutUnit ContainingBlockLogicalWidthForContent() const;
 
-  virtual void ChildBecameNonInline(LayoutObject* /*child*/) {}
+  virtual void ChildBecameNonInline(LayoutObject* /*child*/) {
+    CheckIsNotDestroyed();
+  }
 
   // Overridden by subclasses to determine line height and baseline position.
   virtual LayoutUnit LineHeight(
@@ -415,11 +520,15 @@
   // Returns true if the background is painted opaque in the given rect.
   // The query rect is given in local coordinate system.
   virtual bool BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const {
+    CheckIsNotDestroyed();
     return false;
   }
   // Returns true if all text in the paint-order subtree will be painted on
   // opaque background.
-  virtual bool TextIsKnownToBeOnOpaqueBackground() const { return false; }
+  virtual bool TextIsKnownToBeOnOpaqueBackground() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   // This object's background is transferred to its LayoutView if:
   // 1. it's the document element, or
@@ -436,15 +545,23 @@
                      MapCoordinatesFlags mode = 0) const override;
 
   virtual LayoutUnit OverrideContainingBlockContentWidth() const {
+    CheckIsNotDestroyed();
     NOTREACHED();
     return LayoutUnit(-1);
   }
   virtual LayoutUnit OverrideContainingBlockContentHeight() const {
+    CheckIsNotDestroyed();
     NOTREACHED();
     return LayoutUnit(-1);
   }
-  virtual bool HasOverrideContainingBlockContentWidth() const { return false; }
-  virtual bool HasOverrideContainingBlockContentHeight() const { return false; }
+  virtual bool HasOverrideContainingBlockContentWidth() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
+  virtual bool HasOverrideContainingBlockContentHeight() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   // Returns the continuation associated with |this|.
   // Returns nullptr if no continuation is associated with |this|.
@@ -475,6 +592,7 @@
   void SetContinuation(LayoutBoxModelObject*);
 
   virtual PhysicalOffset AccumulateRelativePositionOffsets() const {
+    CheckIsNotDestroyed();
     return PhysicalOffset();
   }
 
@@ -517,15 +635,18 @@
   void MoveChildTo(LayoutBoxModelObject* to_box_model_object,
                    LayoutObject* child,
                    bool full_remove_insert = false) {
+    CheckIsNotDestroyed();
     MoveChildTo(to_box_model_object, child, nullptr, full_remove_insert);
   }
   void MoveAllChildrenTo(LayoutBoxModelObject* to_box_model_object,
                          bool full_remove_insert = false) {
+    CheckIsNotDestroyed();
     MoveAllChildrenTo(to_box_model_object, nullptr, full_remove_insert);
   }
   void MoveAllChildrenTo(LayoutBoxModelObject* to_box_model_object,
                          LayoutObject* before_child,
                          bool full_remove_insert = false) {
+    CheckIsNotDestroyed();
     MoveChildrenTo(to_box_model_object, SlowFirstChild(), nullptr, before_child,
                    full_remove_insert);
   }
@@ -536,6 +657,7 @@
                       LayoutObject* start_child,
                       LayoutObject* end_child,
                       bool full_remove_insert = false) {
+    CheckIsNotDestroyed();
     MoveChildrenTo(to_box_model_object, start_child, end_child, nullptr,
                    full_remove_insert);
   }
@@ -549,10 +671,14 @@
   void CreateLayerAfterStyleChange();
 
   LayoutUnit ComputedCSSPadding(const Length&) const;
-  bool IsBoxModelObject() const final { return true; }
+  bool IsBoxModelObject() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject>
   PhysicalPaddingToLogical() const {
+    CheckIsNotDestroyed();
     return PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject>(
         StyleRef().GetWritingMode(), StyleRef().Direction(), *this,
         &LayoutBoxModelObject::PaddingTop, &LayoutBoxModelObject::PaddingRight,
@@ -562,6 +688,7 @@
 
   PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject>
   PhysicalMarginToLogical(const ComputedStyle* other_style) const {
+    CheckIsNotDestroyed();
     const auto& style = other_style ? *other_style : StyleRef();
     return PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject>(
         style.GetWritingMode(), style.Direction(), *this,
@@ -571,6 +698,7 @@
 
   PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject>
   PhysicalBorderToLogical() const {
+    CheckIsNotDestroyed();
     return PhysicalToLogicalGetter<LayoutUnit, LayoutBoxModelObject>(
         StyleRef().GetWritingMode(), StyleRef().Direction(), *this,
         &LayoutBoxModelObject::BorderTop, &LayoutBoxModelObject::BorderRight,
diff --git a/third_party/blink/renderer/core/layout/layout_br.cc b/third_party/blink/renderer/core/layout/layout_br.cc
index c96e4cd..7c5ad63 100644
--- a/third_party/blink/renderer/core/layout/layout_br.cc
+++ b/third_party/blink/renderer/core/layout/layout_br.cc
@@ -38,6 +38,7 @@
 LayoutBR::~LayoutBR() = default;
 
 int LayoutBR::LineHeight(bool first_line) const {
+  CheckIsNotDestroyed();
   const ComputedStyle& style = StyleRef(
       first_line && GetDocument().GetStyleEngine().UsesFirstLineRules());
   return style.ComputedLineHeight();
@@ -45,22 +46,27 @@
 
 void LayoutBR::StyleDidChange(StyleDifference diff,
                               const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutText::StyleDidChange(diff, old_style);
 }
 
 int LayoutBR::CaretMinOffset() const {
+  CheckIsNotDestroyed();
   return 0;
 }
 
 int LayoutBR::CaretMaxOffset() const {
+  CheckIsNotDestroyed();
   return 1;
 }
 
 PositionWithAffinity LayoutBR::PositionForPoint(const PhysicalOffset&) const {
+  CheckIsNotDestroyed();
   return CreatePositionWithAffinity(0);
 }
 
 Position LayoutBR::PositionForCaretOffset(unsigned offset) const {
+  CheckIsNotDestroyed();
   DCHECK_LE(offset, 1u);
   DCHECK(GetNode());
   return offset ? Position::AfterNode(*GetNode())
@@ -69,6 +75,7 @@
 
 base::Optional<unsigned> LayoutBR::CaretOffsetForPosition(
     const Position& position) const {
+  CheckIsNotDestroyed();
   if (position.IsNull() || position.AnchorNode() != GetNode())
     return base::nullopt;
   DCHECK(position.IsBeforeAnchor() || position.IsAfterAnchor()) << position;
diff --git a/third_party/blink/renderer/core/layout/layout_br.h b/third_party/blink/renderer/core/layout/layout_br.h
index 1cf6f774..d32435bc 100644
--- a/third_party/blink/renderer/core/layout/layout_br.h
+++ b/third_party/blink/renderer/core/layout/layout_br.h
@@ -32,7 +32,10 @@
   explicit LayoutBR(Node*);
   ~LayoutBR() override;
 
-  const char* GetName() const override { return "LayoutBR"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutBR";
+  }
 
   // Although line breaks contain no actual text, if we're selected we need
   // to return a rect that includes space to illustrate a newline.
@@ -46,6 +49,7 @@
               HashSet<const SimpleFontData*>* = nullptr /* fallbackFonts */,
               FloatRect* /* glyphBounds */ = nullptr,
               float /* expansion */ = false) const override {
+    CheckIsNotDestroyed();
     return 0;
   }
   float Width(unsigned /* from */,
@@ -56,12 +60,14 @@
               HashSet<const SimpleFontData*>* = nullptr /* fallbackFonts */,
               FloatRect* /* glyphBounds */ = nullptr,
               float /* expansion */ = false) const override {
+    CheckIsNotDestroyed();
     return 0;
   }
 
   int LineHeight(bool first_line) const;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectBr || LayoutText::IsOfType(type);
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_button.cc b/third_party/blink/renderer/core/layout/layout_button.cc
index ca18ad9a..73fbdc1 100644
--- a/third_party/blink/renderer/core/layout/layout_button.cc
+++ b/third_party/blink/renderer/core/layout/layout_button.cc
@@ -31,6 +31,7 @@
 
 void LayoutButton::AddChild(LayoutObject* new_child,
                             LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   if (!inner_) {
     // Create an anonymous block.
     DCHECK(!FirstChild());
@@ -42,6 +43,7 @@
 }
 
 void LayoutButton::RemoveChild(LayoutObject* old_child) {
+  CheckIsNotDestroyed();
   if (old_child == inner_ || !inner_) {
     LayoutFlexibleBox::RemoveChild(old_child);
     inner_ = nullptr;
@@ -86,12 +88,14 @@
     bool first_line,
     LineDirectionMode direction,
     LinePositionMode line_position_mode) const {
+  CheckIsNotDestroyed();
   DCHECK_EQ(line_position_mode, kPositionOnContainingLine);
   // We want to call the LayoutBlock version of firstLineBoxBaseline to
   // avoid LayoutFlexibleBox synthesizing a baseline that we don't want.
   // We use this check as a proxy for "are there any line boxes in this button"
   if (!HasLineIfEmpty() && !ShouldApplyLayoutContainment() &&
       LayoutBlock::FirstLineBoxBaseline() == -1) {
+    CheckIsNotDestroyed();
     // To ensure that we have a consistent baseline when we have no children,
     // even when we have the anonymous LayoutBlock child, we calculate the
     // baseline for the empty case manually here.
diff --git a/third_party/blink/renderer/core/layout/layout_button.h b/third_party/blink/renderer/core/layout/layout_button.h
index 543281a4..b865a37 100644
--- a/third_party/blink/renderer/core/layout/layout_button.h
+++ b/third_party/blink/renderer/core/layout/layout_button.h
@@ -36,8 +36,12 @@
   explicit LayoutButton(Element*);
   ~LayoutButton() override;
 
-  const char* GetName() const override { return "LayoutButton"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutButton";
+  }
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectLayoutButton ||
            LayoutFlexibleBox::IsOfType(type);
   }
@@ -45,8 +49,13 @@
   void AddChild(LayoutObject* new_child,
                 LayoutObject* before_child = nullptr) override;
   void RemoveChild(LayoutObject*) override;
-  void RemoveLeftoverAnonymousBlock(LayoutBlock*) override {}
-  bool CreatesAnonymousWrapper() const override { return true; }
+  void RemoveLeftoverAnonymousBlock(LayoutBlock*) override {
+    CheckIsNotDestroyed();
+  }
+  bool CreatesAnonymousWrapper() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   LayoutUnit BaselinePosition(FontBaseline,
                               bool first_line,
diff --git a/third_party/blink/renderer/core/layout/layout_counter.cc b/third_party/blink/renderer/core/layout/layout_counter.cc
index ff735e7..3cde0f71 100644
--- a/third_party/blink/renderer/core/layout/layout_counter.cc
+++ b/third_party/blink/renderer/core/layout/layout_counter.cc
@@ -495,6 +495,7 @@
 LayoutCounter::~LayoutCounter() = default;
 
 void LayoutCounter::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   if (counter_node_) {
     counter_node_->RemoveLayoutObject(this);
     DCHECK(!counter_node_);
@@ -505,6 +506,7 @@
 }
 
 scoped_refptr<StringImpl> LayoutCounter::OriginalText() const {
+  CheckIsNotDestroyed();
   // Child will be the base of our text that we report. First, we need to find
   // an appropriate child.
   CounterNode* child = nullptr;
@@ -605,10 +607,12 @@
 }
 
 void LayoutCounter::UpdateCounter() {
+  CheckIsNotDestroyed();
   SetTextIfNeeded(OriginalText());
 }
 
 void LayoutCounter::Invalidate() {
+  CheckIsNotDestroyed();
   counter_node_->RemoveLayoutObject(this);
   DCHECK(!counter_node_);
   if (DocumentBeingDestroyed())
diff --git a/third_party/blink/renderer/core/layout/layout_counter.h b/third_party/blink/renderer/core/layout/layout_counter.h
index 41f35c7..bde58c9 100644
--- a/third_party/blink/renderer/core/layout/layout_counter.h
+++ b/third_party/blink/renderer/core/layout/layout_counter.h
@@ -71,13 +71,17 @@
 
   void UpdateCounter();
 
-  const char* GetName() const override { return "LayoutCounter"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutCounter";
+  }
 
  protected:
   void WillBeDestroyed() override;
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectCounter || LayoutText::IsOfType(type);
   }
   scoped_refptr<StringImpl> OriginalText() const override;
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 705ce2db..f93151c8 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
@@ -96,6 +96,7 @@
 int LayoutCustomScrollbarPart::ComputeSize(SizeType size_type,
                                            const Length& length,
                                            int container_size) const {
+  CheckIsNotDestroyed();
   if (!length.IsIntrinsicOrAuto() || (size_type == kMinSize && length.IsAuto()))
     return MinimumValueForLength(length, LayoutUnit(container_size)).ToInt();
   return CustomScrollbarTheme::GetCustomScrollbarTheme()->ScrollbarThickness(
@@ -103,6 +104,7 @@
 }
 
 int LayoutCustomScrollbarPart::ComputeWidth(int container_width) const {
+  CheckIsNotDestroyed();
   if (StyleRef().Display() == EDisplay::kNone)
     return 0;
 
@@ -117,6 +119,7 @@
 }
 
 int LayoutCustomScrollbarPart::ComputeHeight(int container_height) const {
+  CheckIsNotDestroyed();
   if (StyleRef().Display() == EDisplay::kNone)
     return 0;
 
@@ -132,6 +135,7 @@
 }
 
 int LayoutCustomScrollbarPart::ComputeThickness() const {
+  CheckIsNotDestroyed();
   DCHECK_EQ(kScrollbarBGPart, part_);
 
   // Use 0 for container width/height, so percentage size will be ignored.
@@ -142,6 +146,7 @@
 }
 
 int LayoutCustomScrollbarPart::ComputeLength() const {
+  CheckIsNotDestroyed();
   DCHECK_NE(kScrollbarBGPart, part_);
 
   IntRect visible_content_rect =
@@ -158,30 +163,35 @@
 }
 
 LayoutUnit LayoutCustomScrollbarPart::MarginTop() const {
+  CheckIsNotDestroyed();
   if (scrollbar_->Orientation() == kHorizontalScrollbar)
     return LayoutUnit();
   return ComputeMargin(StyleRef().MarginTop());
 }
 
 LayoutUnit LayoutCustomScrollbarPart::MarginBottom() const {
+  CheckIsNotDestroyed();
   if (scrollbar_->Orientation() == kHorizontalScrollbar)
     return LayoutUnit();
   return ComputeMargin(StyleRef().MarginBottom());
 }
 
 LayoutUnit LayoutCustomScrollbarPart::MarginLeft() const {
+  CheckIsNotDestroyed();
   if (scrollbar_->Orientation() == kVerticalScrollbar)
     return LayoutUnit();
   return ComputeMargin(StyleRef().MarginLeft());
 }
 
 LayoutUnit LayoutCustomScrollbarPart::MarginRight() const {
+  CheckIsNotDestroyed();
   if (scrollbar_->Orientation() == kVerticalScrollbar)
     return LayoutUnit();
   return ComputeMargin(StyleRef().MarginRight());
 }
 
 void LayoutCustomScrollbarPart::UpdateFromStyle() {
+  CheckIsNotDestroyed();
   LayoutReplaced::UpdateFromStyle();
   SetInline(false);
   ClearPositionedState();
@@ -190,6 +200,7 @@
 
 void LayoutCustomScrollbarPart::StyleDidChange(StyleDifference diff,
                                                const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutReplaced::StyleDidChange(diff, old_style);
   if (old_style && (diff.NeedsPaintInvalidation() || diff.NeedsLayout()))
     SetNeedsPaintInvalidation();
@@ -197,6 +208,7 @@
 }
 
 void LayoutCustomScrollbarPart::RecordPercentLengthStats() const {
+  CheckIsNotDestroyed();
   if (!scrollbar_)
     return;
 
@@ -222,11 +234,13 @@
 
 void LayoutCustomScrollbarPart::ImageChanged(WrappedImagePtr image,
                                              CanDeferInvalidation defer) {
+  CheckIsNotDestroyed();
   SetNeedsPaintInvalidation();
   LayoutReplaced::ImageChanged(image, defer);
 }
 
 void LayoutCustomScrollbarPart::SetNeedsPaintInvalidation() {
+  CheckIsNotDestroyed();
   if (scrollbar_) {
     scrollbar_->SetNeedsPaintInvalidation(kAllParts);
     return;
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 68915e2e0..e5280d7a 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
@@ -41,9 +41,15 @@
                                                     CustomScrollbar* = nullptr,
                                                     ScrollbarPart = kNoPart);
 
-  const char* GetName() const override { return "LayoutCustomScrollbarPart"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutCustomScrollbarPart";
+  }
 
-  PaintLayerType LayerTypeRequired() const override { return kNoPaintLayer; }
+  PaintLayerType LayerTypeRequired() const override {
+    CheckIsNotDestroyed();
+    return kNoPaintLayer;
+  }
 
   // Computes thickness of the scrollbar (which defines thickness of all parts).
   // For kScrollbarBGPart only. This can be called during style update.
@@ -64,10 +70,14 @@
   LayoutUnit MarginRight() const override;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectLayoutCustomScrollbarPart ||
            LayoutReplaced::IsOfType(type);
   }
-  ScrollableArea* GetScrollableArea() const { return scrollable_area_; }
+  ScrollableArea* GetScrollableArea() const {
+    CheckIsNotDestroyed();
+    return scrollable_area_;
+  }
 
  private:
   LayoutCustomScrollbarPart(ScrollableArea*, CustomScrollbar*, ScrollbarPart);
@@ -79,22 +89,40 @@
   // A scrollbar part's Location() and PhysicalLocation() are relative to the
   // scrollbar (instead of relative to any LayoutBox ancestor), and both are
   // in physical coordinates.
-  LayoutBox* LocationContainer() const override { return nullptr; }
+  LayoutBox* LocationContainer() const override {
+    CheckIsNotDestroyed();
+    return nullptr;
+  }
 
   // A scrollbar part is not in the layout tree and is not laid out like other
   // layout objects. CustomScrollbar will call scrollbar parts' SetFrameRect()
   // from its SetFrameRect() when needed.
-  void UpdateLayout() override { NOTREACHED(); }
+  void UpdateLayout() override {
+    CheckIsNotDestroyed();
+    NOTREACHED();
+  }
 
   // Have all padding getters return 0. The important point here is to avoid
   // resolving percents against the containing block, since scroll bar corners
   // don't always have one (so it would crash). Scroll bar corners are not
   // actually laid out, and they don't have child content, so what we return
   // here doesn't really matter.
-  LayoutUnit PaddingTop() const override { return LayoutUnit(); }
-  LayoutUnit PaddingBottom() const override { return LayoutUnit(); }
-  LayoutUnit PaddingLeft() const override { return LayoutUnit(); }
-  LayoutUnit PaddingRight() const override { return LayoutUnit(); }
+  LayoutUnit PaddingTop() const override {
+    CheckIsNotDestroyed();
+    return LayoutUnit();
+  }
+  LayoutUnit PaddingBottom() const override {
+    CheckIsNotDestroyed();
+    return LayoutUnit();
+  }
+  LayoutUnit PaddingLeft() const override {
+    CheckIsNotDestroyed();
+    return LayoutUnit();
+  }
+  LayoutUnit PaddingRight() const override {
+    CheckIsNotDestroyed();
+    return LayoutUnit();
+  }
 
   void SetNeedsPaintInvalidation();
 
diff --git a/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc
index 495e406..ab00f1f5 100644
--- a/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc
@@ -188,6 +188,7 @@
 }
 
 MinMaxSizes LayoutDeprecatedFlexibleBox::ComputeIntrinsicLogicalWidths() const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes;
   for (LayoutBox* child = FirstChildBox(); child;
        child = child->NextSiblingBox()) {
@@ -207,6 +208,7 @@
 }
 
 void LayoutDeprecatedFlexibleBox::UpdateBlockLayout(bool relayout_children) {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   DCHECK_EQ(StyleRef().BoxOrient(), EBoxOrient::kVertical);
   DCHECK(StyleRef().HasLineClamp());
@@ -250,6 +252,7 @@
 }
 
 void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
+  CheckIsNotDestroyed();
   LayoutUnit to_add =
       BorderBottom() + PaddingBottom() + ComputeScrollbars().bottom;
 
@@ -338,6 +341,7 @@
 }
 
 void LayoutDeprecatedFlexibleBox::ApplyLineClamp(bool relayout_children) {
+  CheckIsNotDestroyed();
   int max_line_count = 0;
   for (LayoutBox* child = FirstChildBox(); child;
        child = child->NextSiblingBox()) {
diff --git a/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h b/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h
index 78bf29f3..86313f01 100644
--- a/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h
+++ b/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h
@@ -34,13 +34,22 @@
   LayoutDeprecatedFlexibleBox(Element* element);
   ~LayoutDeprecatedFlexibleBox() override;
 
-  const char* GetName() const override { return "LayoutDeprecatedFlexibleBox"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutDeprecatedFlexibleBox";
+  }
 
   void UpdateBlockLayout(bool relayout_children) override;
   void LayoutVerticalBox(bool relayout_children);
 
-  bool IsDeprecatedFlexibleBox() const override { return true; }
-  bool IsFlexibleBoxIncludingDeprecatedAndNG() const override { return true; }
+  bool IsDeprecatedFlexibleBox() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
+  bool IsFlexibleBoxIncludingDeprecatedAndNG() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
  private:
   MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
diff --git a/third_party/blink/renderer/core/layout/layout_details_marker.cc b/third_party/blink/renderer/core/layout/layout_details_marker.cc
index 37ffb3e..86d0efa 100644
--- a/third_party/blink/renderer/core/layout/layout_details_marker.cc
+++ b/third_party/blink/renderer/core/layout/layout_details_marker.cc
@@ -32,6 +32,7 @@
     : LayoutBlockFlow(element) {}
 
 LayoutDetailsMarker::Orientation LayoutDetailsMarker::GetOrientation() const {
+  CheckIsNotDestroyed();
   // TODO(layout-dev): Sideways-lr and sideways-rl are not yet supported.
   const auto mode = StyleRef().GetWritingMode();
   DCHECK(mode != WritingMode::kSidewaysRl && mode != WritingMode::kSidewaysLr);
@@ -47,10 +48,12 @@
 }
 
 void LayoutDetailsMarker::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   DetailsMarkerPainter(*this).Paint(paint_info);
 }
 
 bool LayoutDetailsMarker::IsOpen() const {
+  CheckIsNotDestroyed();
   for (LayoutObject* layout_object = Parent(); layout_object;
        layout_object = layout_object->Parent()) {
     const auto* node = layout_object->GetNode();
diff --git a/third_party/blink/renderer/core/layout/layout_details_marker.h b/third_party/blink/renderer/core/layout/layout_details_marker.h
index e39df8ed..26ffbe0 100644
--- a/third_party/blink/renderer/core/layout/layout_details_marker.h
+++ b/third_party/blink/renderer/core/layout/layout_details_marker.h
@@ -33,12 +33,19 @@
 
   Orientation GetOrientation() const;
 
-  bool CreatesNewFormattingContext() const override { return true; }
+  bool CreatesNewFormattingContext() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
-  const char* GetName() const override { return "LayoutDetailsMarker"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutDetailsMarker";
+  }
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectDetailsMarker ||
            LayoutBlockFlow::IsOfType(type);
   }
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 0c39d67e..1251e02 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_content.cc
+++ b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
@@ -54,11 +54,13 @@
 }
 
 void LayoutEmbeddedContent::Release() {
+  CheckIsNotDestroyed();
   if (--ref_count_ <= 0)
     delete this;
 }
 
 void LayoutEmbeddedContent::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) {
     cache->ChildrenChanged(Parent());
     cache->Remove(this);
@@ -71,6 +73,7 @@
 }
 
 void LayoutEmbeddedContent::DeleteThis() {
+  CheckIsNotDestroyed();
   // 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
@@ -90,10 +93,12 @@
 }
 
 FrameView* LayoutEmbeddedContent::ChildFrameView() const {
+  CheckIsNotDestroyed();
   return DynamicTo<FrameView>(GetEmbeddedContentView());
 }
 
 LayoutView* LayoutEmbeddedContent::ChildLayoutView() const {
+  CheckIsNotDestroyed();
   if (HTMLFrameOwnerElement* owner_element = GetFrameOwnerElement()) {
     if (Document* content_document = owner_element->contentDocument())
       return content_document->GetLayoutView();
@@ -102,6 +107,7 @@
 }
 
 WebPluginContainerImpl* LayoutEmbeddedContent::Plugin() const {
+  CheckIsNotDestroyed();
   EmbeddedContentView* embedded_content_view = GetEmbeddedContentView();
   if (embedded_content_view && embedded_content_view->IsPluginView())
     return To<WebPluginContainerImpl>(embedded_content_view);
@@ -109,12 +115,14 @@
 }
 
 EmbeddedContentView* LayoutEmbeddedContent::GetEmbeddedContentView() const {
+  CheckIsNotDestroyed();
   if (auto* frame_owner = GetFrameOwnerElement())
     return frame_owner->OwnedEmbeddedContentView();
   return nullptr;
 }
 
 PaintLayerType LayoutEmbeddedContent::LayerTypeRequired() const {
+  CheckIsNotDestroyed();
   if (AdditionalCompositingReasons())
     return kNormalPaintLayer;
 
@@ -135,6 +143,7 @@
 }
 
 bool LayoutEmbeddedContent::ContentDocumentIsCompositing() const {
+  CheckIsNotDestroyed();
   if (PaintLayerCompositor* inner_compositor =
           PaintLayerCompositor::FrameContentsCompositor(*this)) {
     return inner_compositor->StaleInCompositingMode();
@@ -147,6 +156,7 @@
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& accumulated_offset,
     HitTestAction action) {
+  CheckIsNotDestroyed();
   bool had_result = result.InnerNode();
   bool inside = LayoutReplaced::NodeAtPoint(result, hit_test_location,
                                             accumulated_offset, action);
@@ -166,6 +176,7 @@
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& accumulated_offset,
     HitTestAction action) {
+  CheckIsNotDestroyed();
   auto* local_frame_view = DynamicTo<LocalFrameView>(ChildFrameView());
   bool skip_contents = (result.GetHitTestRequest().GetStopNode() == this ||
                         !result.GetHitTestRequest().AllowsChildFrameContent());
@@ -248,6 +259,7 @@
 }
 
 CompositingReasons LayoutEmbeddedContent::AdditionalCompositingReasons() const {
+  CheckIsNotDestroyed();
   WebPluginContainerImpl* plugin_view = Plugin();
   if (plugin_view && plugin_view->CcLayer())
     return CompositingReason::kPlugin;
@@ -262,6 +274,7 @@
 
 void LayoutEmbeddedContent::StyleDidChange(StyleDifference diff,
                                            const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutReplaced::StyleDidChange(diff, old_style);
 
   if (EmbeddedContentView* embedded_content_view = GetEmbeddedContentView()) {
@@ -289,6 +302,7 @@
 }
 
 void LayoutEmbeddedContent::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
   UpdateAfterLayout();
@@ -298,6 +312,7 @@
 void LayoutEmbeddedContent::PaintReplaced(
     const PaintInfo& paint_info,
     const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   if (ChildPaintBlockedByDisplayLock())
     return;
   EmbeddedContentPainter(*this).PaintReplaced(paint_info, paint_offset);
@@ -305,6 +320,7 @@
 
 void LayoutEmbeddedContent::InvalidatePaint(
     const PaintInvalidatorContext& context) const {
+  CheckIsNotDestroyed();
   LayoutReplaced::InvalidatePaint(context);
   if (auto* plugin = Plugin())
     plugin->InvalidatePaint();
@@ -312,6 +328,7 @@
 
 CursorDirective LayoutEmbeddedContent::GetCursor(const PhysicalOffset& point,
                                                  ui::Cursor& cursor) const {
+  CheckIsNotDestroyed();
   if (Plugin()) {
     // A plugin is responsible for setting the cursor when the pointer is over
     // it.
@@ -321,6 +338,7 @@
 }
 
 PhysicalRect LayoutEmbeddedContent::ReplacedContentRect() const {
+  CheckIsNotDestroyed();
   PhysicalRect content_rect = PhysicalContentBoxRect();
   // IFrames set as the root scroller should get their size from their parent.
   if (ChildFrameView() && View() && IsEffectiveRootScroller()) {
@@ -336,6 +354,7 @@
 }
 
 void LayoutEmbeddedContent::UpdateOnEmbeddedContentViewChange() {
+  CheckIsNotDestroyed();
   if (!Style())
     return;
 
@@ -365,6 +384,7 @@
 
 void LayoutEmbeddedContent::UpdateGeometry(
     EmbeddedContentView& embedded_content_view) {
+  CheckIsNotDestroyed();
   // TODO(wangxianzhu): We reset subpixel accumulation at some boundaries, so
   // the following code is incorrect when some ancestors are such boundaries.
   // What about multicol? Need a LayoutBox function to query sub-pixel
@@ -415,6 +435,7 @@
 }
 
 bool LayoutEmbeddedContent::IsThrottledFrameView() const {
+  CheckIsNotDestroyed();
   if (auto* local_frame_view = DynamicTo<LocalFrameView>(ChildFrameView()))
     return local_frame_view->ShouldThrottleRendering();
   return false;
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 816c02b..78c82ed 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_content.h
+++ b/third_party/blink/renderer/core/layout/layout_embedded_content.h
@@ -51,7 +51,10 @@
                    const PhysicalOffset& accumulated_offset,
                    HitTestAction) override;
 
-  void AddRef() { ++ref_count_; }
+  void AddRef() {
+    CheckIsNotDestroyed();
+    ++ref_count_;
+  }
   void Release();
 
   // LayoutEmbeddedContent::ChildFrameView returns the LocalFrameView associated
@@ -68,7 +71,10 @@
   void UpdateOnEmbeddedContentViewChange();
   void UpdateGeometry(EmbeddedContentView&);
 
-  bool IsLayoutEmbeddedContent() const final { return true; }
+  bool IsLayoutEmbeddedContent() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   bool IsThrottledFrameView() const;
 
@@ -82,14 +88,21 @@
   void InvalidatePaint(const PaintInvalidatorContext&) const final;
   CursorDirective GetCursor(const PhysicalOffset&, ui::Cursor&) const final;
 
-  bool CanBeSelectionLeafInternal() const final { return true; }
+  bool CanBeSelectionLeafInternal() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   HTMLFrameOwnerElement* GetFrameOwnerElement() const {
+    CheckIsNotDestroyed();
     return To<HTMLFrameOwnerElement>(GetNode());
   }
 
  private:
-  bool CanHaveAdditionalCompositingReasons() const override { return true; }
+  bool CanHaveAdditionalCompositingReasons() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
   CompositingReasons AdditionalCompositingReasons() const override;
 
   void WillBeDestroyed() final;
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_object.cc b/third_party/blink/renderer/core/layout/layout_embedded_object.cc
index 913e462..ffab276 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_embedded_object.cc
@@ -68,6 +68,7 @@
 
 void LayoutEmbeddedObject::SetPluginAvailability(
     PluginAvailability availability) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(kPluginAvailable, plugin_availability_);
   plugin_availability_ = availability;
 
@@ -80,16 +81,19 @@
 }
 
 bool LayoutEmbeddedObject::ShowsUnavailablePluginIndicator() const {
+  CheckIsNotDestroyed();
   return plugin_availability_ != kPluginAvailable;
 }
 
 void LayoutEmbeddedObject::PaintReplaced(
     const PaintInfo& paint_info,
     const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   EmbeddedObjectPainter(*this).PaintReplaced(paint_info, paint_offset);
 }
 
 void LayoutEmbeddedObject::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
 
@@ -109,6 +113,7 @@
 
 void LayoutEmbeddedObject::ComputeIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  CheckIsNotDestroyed();
   DCHECK(!ShouldApplySizeContainment());
   FrameView* frame_view = ChildFrameView();
   if (frame_view && frame_view->GetIntrinsicSizingInfo(intrinsic_sizing_info)) {
@@ -132,6 +137,7 @@
 }
 
 bool LayoutEmbeddedObject::NeedsPreferredWidthsRecalculation() const {
+  CheckIsNotDestroyed();
   if (LayoutEmbeddedContent::NeedsPreferredWidthsRecalculation())
     return true;
   FrameView* frame_view = ChildFrameView();
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_object.h b/third_party/blink/renderer/core/layout/layout_embedded_object.h
index 8cc0293e..0eeedc6 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_object.h
+++ b/third_party/blink/renderer/core/layout/layout_embedded_object.h
@@ -43,9 +43,13 @@
   void SetPluginAvailability(PluginAvailability);
   bool ShowsUnavailablePluginIndicator() const;
 
-  const char* GetName() const override { return "LayoutEmbeddedObject"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutEmbeddedObject";
+  }
 
   const String& UnavailablePluginReplacementText() const {
+    CheckIsNotDestroyed();
     return unavailable_plugin_replacement_text_;
   }
 
@@ -56,6 +60,7 @@
   void UpdateLayout() final;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectEmbeddedObject ||
            LayoutEmbeddedContent::IsOfType(type);
   }
diff --git a/third_party/blink/renderer/core/layout/layout_fieldset.cc b/third_party/blink/renderer/core/layout/layout_fieldset.cc
index 5c5afa1..7ce8759 100644
--- a/third_party/blink/renderer/core/layout/layout_fieldset.cc
+++ b/third_party/blink/renderer/core/layout/layout_fieldset.cc
@@ -33,6 +33,7 @@
 LayoutFieldset::LayoutFieldset(Element* element) : LayoutBlockFlow(element) {}
 
 MinMaxSizes LayoutFieldset::PreferredLogicalWidths() const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes = LayoutBlockFlow::PreferredLogicalWidths();
   // Size-contained elements don't consider their contents for preferred sizing.
   if (ShouldApplySizeContainment())
@@ -59,6 +60,7 @@
 
 LayoutObject* LayoutFieldset::LayoutSpecialExcludedChild(bool relayout_children,
                                                          SubtreeLayoutScope&) {
+  CheckIsNotDestroyed();
   LayoutBox* legend = FindInFlowLegend();
   if (legend) {
     LayoutRect old_legend_frame_rect = legend->FrameRect();
@@ -194,16 +196,19 @@
 void LayoutFieldset::PaintBoxDecorationBackground(
     const PaintInfo& paint_info,
     const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   FieldsetPainter(*this).PaintBoxDecorationBackground(paint_info, paint_offset);
 }
 
 void LayoutFieldset::PaintMask(const PaintInfo& paint_info,
                                const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   FieldsetPainter(*this).PaintMask(paint_info, paint_offset);
 }
 
 bool LayoutFieldset::BackgroundIsKnownToBeOpaqueInRect(
     const PhysicalRect& local_rect) const {
+  CheckIsNotDestroyed();
   // If the field set has a legend, then it probably does not completely fill
   // its background.
   if (FindInFlowLegend())
diff --git a/third_party/blink/renderer/core/layout/layout_fieldset.h b/third_party/blink/renderer/core/layout/layout_fieldset.h
index 48a366ec..0d3062e 100644
--- a/third_party/blink/renderer/core/layout/layout_fieldset.h
+++ b/third_party/blink/renderer/core/layout/layout_fieldset.h
@@ -33,19 +33,29 @@
   explicit LayoutFieldset(Element*);
 
   static LayoutBox* FindInFlowLegend(const LayoutBlock& fieldset);
-  LayoutBox* FindInFlowLegend() const { return FindInFlowLegend(*this); }
+  LayoutBox* FindInFlowLegend() const {
+    CheckIsNotDestroyed();
+    return FindInFlowLegend(*this);
+  }
 
   static LayoutBlock* FindLegendContainingBlock(const LayoutBox& legend,
                                                 AncestorSkipInfo* = nullptr);
 
-  const char* GetName() const override { return "LayoutFieldset"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutFieldset";
+  }
 
-  bool CreatesNewFormattingContext() const final { return true; }
+  bool CreatesNewFormattingContext() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   bool BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const override;
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectFieldset || LayoutBlockFlow::IsOfType(type);
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_file_upload_control.cc b/third_party/blink/renderer/core/layout/layout_file_upload_control.cc
index 589ba9e..81d160b5 100644
--- a/third_party/blink/renderer/core/layout/layout_file_upload_control.cc
+++ b/third_party/blink/renderer/core/layout/layout_file_upload_control.cc
@@ -44,6 +44,7 @@
 
 bool LayoutFileUploadControl::IsChildAllowed(LayoutObject* child,
                                              const ComputedStyle& style) const {
+  CheckIsNotDestroyed();
   const Node* child_node = child->GetNode();
   // Reject shadow nodes other than UploadButton.
   if (child_node && child_node->OwnerShadowHost() == GetNode() &&
@@ -53,6 +54,7 @@
 }
 
 int LayoutFileUploadControl::MaxFilenameWidth() const {
+  CheckIsNotDestroyed();
   int upload_button_width =
       (UploadButton() && UploadButton()->GetLayoutBox())
           ? UploadButton()->GetLayoutBox()->PixelSnappedWidth()
@@ -64,14 +66,17 @@
 void LayoutFileUploadControl::PaintObject(
     const PaintInfo& paint_info,
     const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   FileUploadControlPainter(*this).PaintObject(paint_info, paint_offset);
 }
 
 HTMLInputElement* LayoutFileUploadControl::UploadButton() const {
+  CheckIsNotDestroyed();
   return To<HTMLInputElement>(GetNode())->UploadButton();
 }
 
 String LayoutFileUploadControl::FileTextValue() const {
+  CheckIsNotDestroyed();
   int width = MaxFilenameWidth();
   if (width <= 0)
     return String();
@@ -88,6 +93,7 @@
 PhysicalRect LayoutFileUploadControl::OverflowClipRect(
     const PhysicalOffset& additional_offset,
     OverlayScrollbarClipBehavior) const {
+  CheckIsNotDestroyed();
   PhysicalRect rect(additional_offset, Size());
   rect.Expand(BorderInsets());
   rect.offset.top -= LayoutUnit(kButtonShadowHeight);
diff --git a/third_party/blink/renderer/core/layout/layout_file_upload_control.h b/third_party/blink/renderer/core/layout/layout_file_upload_control.h
index a9869961..c58dfe51 100644
--- a/third_party/blink/renderer/core/layout/layout_file_upload_control.h
+++ b/third_party/blink/renderer/core/layout/layout_file_upload_control.h
@@ -38,6 +38,7 @@
   ~LayoutFileUploadControl() override;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectFileUploadControl ||
            LayoutBlockFlow::IsOfType(type);
   }
@@ -51,7 +52,10 @@
 
   static const int kAfterButtonSpacing = 4;
 
-  const char* GetName() const override { return "LayoutFileUploadControl"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutFileUploadControl";
+  }
 
  private:
   bool IsChildAllowed(LayoutObject* child,
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 379f1920..cd0739dc 100644
--- a/third_party/blink/renderer/core/layout/layout_flexible_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
@@ -74,6 +74,7 @@
 
 bool LayoutFlexibleBox::IsChildAllowed(LayoutObject* object,
                                        const ComputedStyle& style) const {
+  CheckIsNotDestroyed();
   const auto* select = DynamicTo<HTMLSelectElement>(GetNode());
   if (UNLIKELY(select && select->UsesMenuList())) {
     // For a size=1 <select>, we only render the active option label through the
@@ -85,6 +86,7 @@
 }
 
 MinMaxSizes LayoutFlexibleBox::ComputeIntrinsicLogicalWidths() const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes;
   sizes +=
       BorderAndPaddingLogicalWidth() + ComputeLogicalScrollbars().InlineSum();
@@ -178,6 +180,7 @@
     LayoutUnit max_preferred_logical_width,
     LayoutBox* child,
     float previous_max_content_flex_fraction) const {
+  CheckIsNotDestroyed();
   // Determine whether the new version of the intrinsic size algorithm of the
   // flexbox spec would produce a different result than our above algorithm.
   // The algorithm produces a different result iff the max-content flex
@@ -214,6 +217,7 @@
                                                bool,
                                                LineDirectionMode direction,
                                                LinePositionMode mode) const {
+  CheckIsNotDestroyed();
   DCHECK_EQ(mode, kPositionOnContainingLine);
   // TODO(crbug.com/1040826): input[type=range] should not use
   // LayoutFlexibleBox. We should move out this code.
@@ -233,6 +237,7 @@
 }
 
 LayoutUnit LayoutFlexibleBox::FirstLineBoxBaseline() const {
+  CheckIsNotDestroyed();
   if (IsWritingModeRoot() || number_of_in_flow_children_on_first_line_ <= 0 ||
       ShouldApplyLayoutContainment())
     return LayoutUnit(-1);
@@ -285,10 +290,12 @@
 
 LayoutUnit LayoutFlexibleBox::InlineBlockBaseline(
     LineDirectionMode direction) const {
+  CheckIsNotDestroyed();
   return FirstLineBoxBaseline();
 }
 
 bool LayoutFlexibleBox::HasTopOverflow() const {
+  CheckIsNotDestroyed();
   if (IsHorizontalWritingMode())
     return StyleRef().ResolvedIsColumnReverseFlexDirection();
   return !StyleRef().IsLeftToRightDirection() ^
@@ -296,6 +303,7 @@
 }
 
 bool LayoutFlexibleBox::HasLeftOverflow() const {
+  CheckIsNotDestroyed();
   if (IsHorizontalWritingMode()) {
     return !StyleRef().IsLeftToRightDirection() ^
            StyleRef().ResolvedIsRowReverseFlexDirection();
@@ -304,6 +312,7 @@
 }
 
 void LayoutFlexibleBox::MergeAnonymousFlexItems(LayoutObject* remove_child) {
+  CheckIsNotDestroyed();
   // When we remove a flex item, and the previous and next siblings of the item
   // are text nodes wrapped in anonymous flex items, the adjacent text nodes
   // need to be merged into the same flex item.
@@ -320,6 +329,7 @@
 }
 
 void LayoutFlexibleBox::RemoveChild(LayoutObject* child) {
+  CheckIsNotDestroyed();
   if (!DocumentBeingDestroyed() &&
       !StyleRef().IsDeprecatedFlexboxUsingFlexLayout()) {
     MergeAnonymousFlexItems(child);
@@ -334,6 +344,7 @@
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& accumulated_offset,
     HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   if (hit_test_action != kHitTestForeground)
     return false;
 
@@ -361,6 +372,7 @@
 
 void LayoutFlexibleBox::StyleDidChange(StyleDifference diff,
                                        const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutBlock::StyleDidChange(diff, old_style);
 
   if (old_style &&
@@ -388,6 +400,7 @@
 }
 
 void LayoutFlexibleBox::UpdateBlockLayout(bool relayout_children) {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
 
   if (!relayout_children && SimplifiedLayout())
@@ -450,12 +463,14 @@
 
 void LayoutFlexibleBox::PaintChildren(const PaintInfo& paint_info,
                                       const PhysicalOffset&) const {
+  CheckIsNotDestroyed();
   BlockPainter(*this).PaintChildrenAtomically(this->GetOrderIterator(),
                                               paint_info);
 }
 
 void LayoutFlexibleBox::RepositionLogicalHeightDependentFlexItems(
     FlexLayoutAlgorithm& algorithm) {
+  CheckIsNotDestroyed();
   Vector<FlexLine>& line_contexts = algorithm.FlexLines();
   LayoutUnit cross_axis_start_edge = line_contexts.IsEmpty()
                                          ? LayoutUnit()
@@ -487,6 +502,7 @@
 
 DISABLE_CFI_PERF
 LayoutUnit LayoutFlexibleBox::ClientLogicalBottomAfterRepositioning() {
+  CheckIsNotDestroyed();
   LayoutUnit max_child_logical_bottom;
   for (LayoutBox* child = FirstChildBox(); child;
        child = child->NextSiblingBox()) {
@@ -503,6 +519,7 @@
 }
 
 bool LayoutFlexibleBox::MainAxisIsInlineAxis(const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   // If we have a horizontal flow, that means the main size is the width.
   // That's the inline size for horizontal writing modes, and the block
   // size in vertical writing modes. For a vertical flow, main size is the
@@ -513,16 +530,19 @@
 }
 
 bool LayoutFlexibleBox::IsColumnFlow() const {
+  CheckIsNotDestroyed();
   return StyleRef().ResolvedIsColumnFlexDirection();
 }
 
 bool LayoutFlexibleBox::IsHorizontalFlow() const {
+  CheckIsNotDestroyed();
   if (IsHorizontalWritingMode())
     return !IsColumnFlow();
   return IsColumnFlow();
 }
 
 bool LayoutFlexibleBox::IsLeftToRightFlow() const {
+  CheckIsNotDestroyed();
   if (IsColumnFlow()) {
     return blink::IsHorizontalWritingMode(StyleRef().GetWritingMode()) ||
            IsFlippedLinesWritingMode(StyleRef().GetWritingMode());
@@ -532,10 +552,12 @@
 }
 
 bool LayoutFlexibleBox::IsMultiline() const {
+  CheckIsNotDestroyed();
   return StyleRef().FlexWrap() != EFlexWrap::kNowrap;
 }
 
 Length LayoutFlexibleBox::FlexBasisForChild(const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   Length flex_length = child.StyleRef().FlexBasis();
   if (flex_length.IsAuto()) {
     flex_length = IsHorizontalFlow() ? child.StyleRef().Width()
@@ -546,11 +568,13 @@
 
 LayoutUnit LayoutFlexibleBox::CrossAxisExtentForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   return IsHorizontalFlow() ? child.Size().Height() : child.Size().Width();
 }
 
 LayoutUnit LayoutFlexibleBox::ChildUnstretchedLogicalHeight(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   // This should only be called if the logical height is the cross size
   DCHECK(MainAxisIsInlineAxis(child));
   if (NeedToStretchChildLogicalHeight(child)) {
@@ -581,6 +605,7 @@
 DISABLE_CFI_PERF
 LayoutUnit LayoutFlexibleBox::ChildUnstretchedLogicalWidth(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   // This should only be called if the logical width is the cross size
   DCHECK(!MainAxisIsInlineAxis(child));
 
@@ -601,37 +626,44 @@
 
 LayoutUnit LayoutFlexibleBox::CrossAxisUnstretchedExtentForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   return MainAxisIsInlineAxis(child) ? ChildUnstretchedLogicalHeight(child)
                                      : ChildUnstretchedLogicalWidth(child);
 }
 
 LayoutUnit LayoutFlexibleBox::MainAxisExtentForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   return IsHorizontalFlow() ? child.Size().Width() : child.Size().Height();
 }
 
 LayoutUnit LayoutFlexibleBox::MainAxisContentExtentForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   return IsHorizontalFlow() ? child.ContentWidth() : child.ContentHeight();
 }
 
 LayoutUnit LayoutFlexibleBox::MainAxisContentExtentForChildIncludingScrollbar(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   return IsHorizontalFlow()
              ? child.ContentWidth() + child.ComputeScrollbars().HorizontalSum()
              : child.ContentHeight() + child.ComputeScrollbars().VerticalSum();
 }
 
 LayoutUnit LayoutFlexibleBox::CrossAxisExtent() const {
+  CheckIsNotDestroyed();
   return IsHorizontalFlow() ? Size().Height() : Size().Width();
 }
 
 LayoutUnit LayoutFlexibleBox::CrossAxisContentExtent() const {
+  CheckIsNotDestroyed();
   return IsHorizontalFlow() ? ContentHeight() : ContentWidth();
 }
 
 LayoutUnit LayoutFlexibleBox::MainAxisContentExtent(
     LayoutUnit content_logical_height) {
+  CheckIsNotDestroyed();
   if (IsColumnFlow()) {
     LogicalExtentComputedValues computed_values;
     LayoutUnit border_padding_and_scrollbar =
@@ -653,6 +685,7 @@
     SizeType size_type,
     const Length& size,
     LayoutUnit border_and_padding) const {
+  CheckIsNotDestroyed();
   if (!MainAxisIsInlineAxis(child)) {
     // We don't have to check for "auto" here - computeContentLogicalHeight
     // will just return -1 for that case anyway. It's safe to access
@@ -682,26 +715,31 @@
 }
 
 LayoutUnit LayoutFlexibleBox::ContentInsetRight() const {
+  CheckIsNotDestroyed();
   return BorderRight() + PaddingRight() + ComputeScrollbars().right;
 }
 
 LayoutUnit LayoutFlexibleBox::ContentInsetBottom() const {
+  CheckIsNotDestroyed();
   return BorderBottom() + PaddingBottom() + ComputeScrollbars().bottom;
 }
 
 LayoutUnit LayoutFlexibleBox::FlowAwareContentInsetStart() const {
+  CheckIsNotDestroyed();
   if (IsHorizontalFlow())
     return IsLeftToRightFlow() ? ContentLeft() : ContentInsetRight();
   return IsLeftToRightFlow() ? ContentTop() : ContentInsetBottom();
 }
 
 LayoutUnit LayoutFlexibleBox::FlowAwareContentInsetEnd() const {
+  CheckIsNotDestroyed();
   if (IsHorizontalFlow())
     return IsLeftToRightFlow() ? ContentInsetRight() : ContentLeft();
   return IsLeftToRightFlow() ? ContentInsetBottom() : ContentTop();
 }
 
 LayoutUnit LayoutFlexibleBox::FlowAwareContentInsetBefore() const {
+  CheckIsNotDestroyed();
   switch (FlexLayoutAlgorithm::GetTransformedWritingMode(StyleRef())) {
     case TransformedWritingMode::kTopToBottomWritingMode:
       return ContentTop();
@@ -717,6 +755,7 @@
 
 DISABLE_CFI_PERF
 LayoutUnit LayoutFlexibleBox::FlowAwareContentInsetAfter() const {
+  CheckIsNotDestroyed();
   switch (FlexLayoutAlgorithm::GetTransformedWritingMode(StyleRef())) {
     case TransformedWritingMode::kTopToBottomWritingMode:
       return ContentInsetBottom();
@@ -731,23 +770,27 @@
 }
 
 LayoutUnit LayoutFlexibleBox::CrossAxisScrollbarExtent() const {
+  CheckIsNotDestroyed();
   return IsHorizontalFlow() ? ComputeScrollbars().HorizontalSum()
                             : ComputeScrollbars().VerticalSum();
 }
 
 LayoutUnit LayoutFlexibleBox::CrossAxisScrollbarExtentForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   return IsHorizontalFlow() ? child.ComputeScrollbars().HorizontalSum()
                             : child.ComputeScrollbars().VerticalSum();
 }
 
 LayoutPoint LayoutFlexibleBox::FlowAwareLocationForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   return IsHorizontalFlow() ? child.Location()
                             : child.Location().TransposedPoint();
 }
 
 bool LayoutFlexibleBox::UseChildAspectRatio(const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   if (!HasAspectRatio(child))
     return false;
   if (!child.StyleRef().AspectRatio() && child.IntrinsicSize().Height() == 0) {
@@ -762,6 +805,7 @@
 LayoutUnit LayoutFlexibleBox::ComputeMainSizeFromAspectRatioUsing(
     const LayoutBox& child,
     const Length& cross_size_length) const {
+  CheckIsNotDestroyed();
   DCHECK(HasAspectRatio(child));
 
   LayoutUnit cross_size;
@@ -792,6 +836,7 @@
 void LayoutFlexibleBox::SetFlowAwareLocationForChild(
     LayoutBox& child,
     const LayoutPoint& location) {
+  CheckIsNotDestroyed();
   if (IsHorizontalFlow())
     child.SetLocationAndUpdateOverflowControlsIfNeeded(location);
   else
@@ -802,6 +847,7 @@
 bool LayoutFlexibleBox::MainAxisLengthIsDefinite(const LayoutBox& child,
                                                  const Length& flex_basis,
                                                  bool add_to_cb) const {
+  CheckIsNotDestroyed();
   if (flex_basis.IsAuto())
     return false;
   if (IsColumnFlow() && flex_basis.IsIntrinsic())
@@ -838,6 +884,7 @@
 
 bool LayoutFlexibleBox::CrossAxisLengthIsDefinite(const LayoutBox& child,
                                                   const Length& length) const {
+  CheckIsNotDestroyed();
   if (length.IsAuto())
     return false;
   if (length.IsPercentOrCalc()) {
@@ -858,6 +905,7 @@
 }
 
 void LayoutFlexibleBox::CacheChildMainSize(const LayoutBox& child) {
+  CheckIsNotDestroyed();
   DCHECK(!child.SelfNeedsLayout());
   DCHECK(!child.NeedsLayout() || child.ChildLayoutBlockedByDisplayLock());
   LayoutUnit main_size;
@@ -878,10 +926,12 @@
 }
 
 void LayoutFlexibleBox::ClearCachedMainSizeForChild(const LayoutBox& child) {
+  CheckIsNotDestroyed();
   intrinsic_size_along_main_axis_.erase(&child);
 }
 
 bool LayoutFlexibleBox::CanAvoidLayoutForNGChild(const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   if (!child.IsLayoutNGMixin())
     return false;
 
@@ -915,6 +965,7 @@
     LayoutBox& child,
     LayoutUnit main_axis_border_and_padding,
     ChildLayoutType child_layout_type) {
+  CheckIsNotDestroyed();
   if (child.IsImage() || IsA<LayoutVideo>(child) || child.IsCanvas())
     UseCounter::Count(GetDocument(), WebFeature::kAspectRatioFlexItem);
 
@@ -974,6 +1025,7 @@
 
 void LayoutFlexibleBox::LayoutFlexItems(bool relayout_children,
                                         SubtreeLayoutScope& layout_scope) {
+  CheckIsNotDestroyed();
   PaintLayerScrollableArea::PreventRelayoutScope prevent_relayout_scope(
       layout_scope);
 
@@ -1052,6 +1104,7 @@
 
 bool LayoutFlexibleBox::HasAutoMarginsInCrossAxis(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   if (IsHorizontalFlow()) {
     return child.StyleRef().MarginTop().IsAuto() ||
            child.StyleRef().MarginBottom().IsAuto();
@@ -1061,6 +1114,7 @@
 }
 
 LayoutUnit LayoutFlexibleBox::ComputeChildMarginValue(const Length& margin) {
+  CheckIsNotDestroyed();
   // When resolving the margins, we use the content size for resolving percent
   // and calc (for percents in calc expressions) margins. Fortunately, percent
   // margins are always computed with respect to the block's width, even for
@@ -1070,6 +1124,7 @@
 }
 
 void LayoutFlexibleBox::PrepareOrderIteratorAndMargins() {
+  CheckIsNotDestroyed();
   OrderIteratorPopulator populator(order_iterator_);
 
   for (LayoutBox* child = FirstChildBox(); child;
@@ -1093,6 +1148,7 @@
     const FlexLayoutAlgorithm& algorithm,
     const LayoutBox& child,
     LayoutUnit border_and_padding) const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes{LayoutUnit(), LayoutUnit::Max()};
 
   const Length& max = IsHorizontalFlow() ? child.StyleRef().MaxWidth()
@@ -1159,6 +1215,7 @@
 
 bool LayoutFlexibleBox::CrossSizeIsDefiniteForPercentageResolution(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   DCHECK(MainAxisIsInlineAxis(child));
   if (FlexLayoutAlgorithm::AlignmentForChild(StyleRef(), child.StyleRef()) !=
       ItemPosition::kStretch)
@@ -1179,6 +1236,7 @@
 
 bool LayoutFlexibleBox::MainSizeIsDefiniteForPercentageResolution(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   DCHECK(!MainAxisIsInlineAxis(child));
   // This function implements section 9.8. Definite and Indefinite Sizes, case
   // 2) of the flexbox spec.
@@ -1192,6 +1250,7 @@
 
 bool LayoutFlexibleBox::UseOverrideLogicalHeightForPerentageResolution(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   if (MainAxisIsInlineAxis(child))
     return CrossSizeIsDefiniteForPercentageResolution(child);
   return MainSizeIsDefiniteForPercentageResolution(child);
@@ -1200,6 +1259,7 @@
 LayoutUnit LayoutFlexibleBox::AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
     const LayoutBox& child,
     LayoutUnit child_size) const {
+  CheckIsNotDestroyed();
   const Length& cross_min = IsHorizontalFlow() ? child.StyleRef().MinHeight()
                                                : child.StyleRef().MinWidth();
   const Length& cross_max = IsHorizontalFlow() ? child.StyleRef().MaxHeight()
@@ -1225,6 +1285,7 @@
     FlexLayoutAlgorithm* algorithm,
     LayoutBox& child,
     ChildLayoutType layout_type) {
+  CheckIsNotDestroyed();
   if (layout_type != kNeverLayout &&
       ChildHasIntrinsicMainAxisSize(*algorithm, child)) {
     // If this condition is true, then ComputeMainAxisExtentForChild will call
@@ -1277,6 +1338,7 @@
 }
 
 void LayoutFlexibleBox::SetOverrideMainAxisContentSizeForChild(FlexItem& item) {
+  CheckIsNotDestroyed();
   if (MainAxisIsInlineAxis(*item.box)) {
     item.box->SetOverrideLogicalWidth(item.FlexedBorderBoxSize());
   } else {
@@ -1378,6 +1440,7 @@
 
 LayoutUnit LayoutFlexibleBox::StaticMainAxisPositionForPositionedChild(
     const LayoutBox& child) {
+  CheckIsNotDestroyed();
   const LayoutUnit available_space =
       MainAxisContentExtent(ContentLogicalHeight()) -
       MainAxisExtentForChild(child);
@@ -1387,6 +1450,7 @@
 
 LayoutUnit LayoutFlexibleBox::StaticCrossAxisPositionForPositionedChild(
     const LayoutBox& child) {
+  CheckIsNotDestroyed();
   LayoutUnit available_space =
       CrossAxisContentExtent() - CrossAxisExtentForChild(child);
   return CrossAxisStaticPositionCommon(child, this, available_space);
@@ -1394,6 +1458,7 @@
 
 LayoutUnit LayoutFlexibleBox::StaticInlinePositionForPositionedChild(
     const LayoutBox& child) {
+  CheckIsNotDestroyed();
   const LayoutUnit start_offset = StartOffsetForContent();
   if (StyleRef().IsDeprecatedWebkitBox())
     return start_offset;
@@ -1404,12 +1469,14 @@
 
 LayoutUnit LayoutFlexibleBox::StaticBlockPositionForPositionedChild(
     const LayoutBox& child) {
+  CheckIsNotDestroyed();
   return BorderAndPaddingBefore() +
          (IsColumnFlow() ? StaticMainAxisPositionForPositionedChild(child)
                          : StaticCrossAxisPositionForPositionedChild(child));
 }
 
 bool LayoutFlexibleBox::SetStaticPositionForPositionedLayout(LayoutBox& child) {
+  CheckIsNotDestroyed();
   bool position_changed = false;
   PaintLayer* child_layer = child.Layer();
   if (child.StyleRef().HasStaticInlinePosition(
@@ -1432,6 +1499,7 @@
 }
 
 void LayoutFlexibleBox::PrepareChildForPositionedLayout(LayoutBox& child) {
+  CheckIsNotDestroyed();
   DCHECK(child.IsOutOfFlowPositioned());
   child.ContainingBlock()->InsertPositionedObject(&child);
   PaintLayer* child_layer = child.Layer();
@@ -1454,6 +1522,7 @@
 
 void LayoutFlexibleBox::ResetAutoMarginsAndLogicalTopInCrossAxis(
     LayoutBox& child) {
+  CheckIsNotDestroyed();
   if (HasAutoMarginsInCrossAxis(child)) {
     child.UpdateLogicalHeight();
     if (IsHorizontalFlow()) {
@@ -1472,6 +1541,7 @@
 
 bool LayoutFlexibleBox::NeedToStretchChildLogicalHeight(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   // This function is a little bit magical. It relies on the fact that blocks
   // intrinsically "stretch" themselves in their inline axis, i.e. a <div> has
   // an implicit width: 100%. So the child will automatically stretch if our
@@ -1492,6 +1562,7 @@
 bool LayoutFlexibleBox::ChildHasIntrinsicMainAxisSize(
     const FlexLayoutAlgorithm& algorithm,
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   bool result = false;
   if (!MainAxisIsInlineAxis(child) && !child.ShouldApplySizeContainment()) {
     Length child_flex_basis = FlexBasisForChild(child);
@@ -1513,6 +1584,7 @@
 
 EOverflow LayoutFlexibleBox::CrossAxisOverflowForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   if (IsHorizontalFlow())
     return child.StyleRef().OverflowY();
   return child.StyleRef().OverflowX();
@@ -1522,6 +1594,7 @@
 void LayoutFlexibleBox::LayoutLineItems(FlexLine* current_line,
                                         bool relayout_children,
                                         SubtreeLayoutScope& layout_scope) {
+  CheckIsNotDestroyed();
   for (wtf_size_t i = 0; i < current_line->line_items.size(); ++i) {
     FlexItem& flex_item = current_line->line_items[i];
     LayoutBox* child = flex_item.box;
@@ -1586,6 +1659,7 @@
 }
 
 void LayoutFlexibleBox::ApplyLineItemsPosition(FlexLine* current_line) {
+  CheckIsNotDestroyed();
   bool is_paginated = View()->GetLayoutState()->IsPaginated();
   for (wtf_size_t i = 0; i < current_line->line_items.size(); ++i) {
     const FlexItem& flex_item = current_line->line_items[i];
@@ -1621,6 +1695,7 @@
 void LayoutFlexibleBox::LayoutColumnReverse(FlexItemVectorView& children,
                                             LayoutUnit cross_axis_offset,
                                             LayoutUnit available_free_space) {
+  CheckIsNotDestroyed();
   const StyleContentAlignmentData justify_content =
       FlexLayoutAlgorithm::ResolvedJustifyContent(StyleRef());
 
@@ -1653,6 +1728,7 @@
 }
 
 void LayoutFlexibleBox::AlignFlexLines(FlexLayoutAlgorithm& algorithm) {
+  CheckIsNotDestroyed();
   Vector<FlexLine>& line_contexts = algorithm.FlexLines();
   const StyleContentAlignmentData align_content =
       FlexLayoutAlgorithm::ResolvedAlignContent(StyleRef());
@@ -1679,11 +1755,13 @@
 void LayoutFlexibleBox::ResetAlignmentForChild(
     LayoutBox& child,
     LayoutUnit new_cross_axis_position) {
+  CheckIsNotDestroyed();
   SetFlowAwareLocationForChild(
       child, {FlowAwareLocationForChild(child).X(), new_cross_axis_position});
 }
 
 void LayoutFlexibleBox::AlignChildren(FlexLayoutAlgorithm& algorithm) {
+  CheckIsNotDestroyed();
   Vector<FlexLine>& line_contexts = algorithm.FlexLines();
 
   algorithm.AlignChildren();
@@ -1703,6 +1781,7 @@
 }
 
 void LayoutFlexibleBox::ApplyStretchAlignmentToChild(FlexItem& flex_item) {
+  CheckIsNotDestroyed();
   LayoutBox& child = *flex_item.box;
   if (flex_item.MainAxisIsInlineAxis() &&
       child.StyleRef().LogicalHeight().IsAuto()) {
@@ -1734,6 +1813,7 @@
 
 void LayoutFlexibleBox::FlipForRightToLeftColumn(
     const Vector<FlexLine>& line_contexts) {
+  CheckIsNotDestroyed();
   if (StyleRef().IsLeftToRightDirection() || !IsColumnFlow())
     return;
 
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 493d739..fbed085c 100644
--- a/third_party/blink/renderer/core/layout/layout_flexible_box.h
+++ b/third_party/blink/renderer/core/layout/layout_flexible_box.h
@@ -48,11 +48,23 @@
   explicit LayoutFlexibleBox(Element*);
   ~LayoutFlexibleBox() override;
 
-  const char* GetName() const override { return "LayoutFlexibleBox"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutFlexibleBox";
+  }
 
-  bool IsFlexibleBox() const final { return true; }
-  bool IsFlexibleBoxIncludingNG() const final { return true; }
-  bool IsFlexibleBoxIncludingDeprecatedAndNG() const final { return true; }
+  bool IsFlexibleBox() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
+  bool IsFlexibleBoxIncludingNG() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
+  bool IsFlexibleBoxIncludingDeprecatedAndNG() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
   void UpdateBlockLayout(bool relayout_children) final;
 
   bool IsChildAllowed(LayoutObject* object,
@@ -76,7 +88,10 @@
 
   bool IsHorizontalFlow() const;
 
-  const OrderIterator& GetOrderIterator() const { return order_iterator_; }
+  const OrderIterator& GetOrderIterator() const {
+    CheckIsNotDestroyed();
+    return order_iterator_;
+  }
 
   // These three functions are used when resolving percentages against a
   // flex item's logical height. In flexbox, sometimes a logical height
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 890492c..cd2e19b7 100644
--- a/third_party/blink/renderer/core/layout/layout_flow_thread.cc
+++ b/third_party/blink/renderer/core/layout/layout_flow_thread.cc
@@ -96,6 +96,7 @@
 
 void LayoutFlowThread::RemoveColumnSetFromThread(
     LayoutMultiColumnSet* column_set) {
+  CheckIsNotDestroyed();
   DCHECK(column_set);
   multi_column_set_list_.erase(column_set);
   InvalidateColumnSets();
@@ -109,6 +110,7 @@
 }
 
 void LayoutFlowThread::ValidateColumnSets() {
+  CheckIsNotDestroyed();
   column_sets_invalidated_ = false;
   // Called to get the maximum logical width for the columnSet.
   UpdateLogicalWidth();
@@ -119,6 +121,7 @@
     const LayoutBoxModelObject* ancestor,
     TransformState& transform_state,
     VisualRectFlags visual_rect_flags) const {
+  CheckIsNotDestroyed();
   // A flow thread should never be an invalidation container.
   DCHECK_NE(ancestor, this);
   transform_state.Flatten();
@@ -130,12 +133,14 @@
 }
 
 void LayoutFlowThread::UpdateLayout() {
+  CheckIsNotDestroyed();
   page_logical_size_changed_ = column_sets_invalidated_ && EverHadLayout();
   LayoutBlockFlow::UpdateLayout();
   page_logical_size_changed_ = false;
 }
 
 PaintLayerType LayoutFlowThread::LayerTypeRequired() const {
+  CheckIsNotDestroyed();
   if (!needs_paint_layer_)
     return kNoPaintLayer;
   // Always create a Layer for the LayoutFlowThread so that we can easily avoid
@@ -148,6 +153,7 @@
     LayoutUnit,
     LayoutUnit logical_top,
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   computed_values.position_ = logical_top;
   computed_values.extent_ = LayoutUnit();
 
@@ -162,6 +168,7 @@
 void LayoutFlowThread::AbsoluteQuadsForDescendant(const LayoutBox& descendant,
                                                   Vector<FloatQuad>& quads,
                                                   MapCoordinatesFlags mode) {
+  CheckIsNotDestroyed();
   LayoutPoint offset_from_flow_thread;
   for (const LayoutObject* object = &descendant; object != this;) {
     const LayoutObject* container = object->Container();
@@ -191,6 +198,7 @@
     Vector<PhysicalRect>& rects,
     const PhysicalOffset& additional_offset,
     NGOutlineType include_block_overflows) const {
+  CheckIsNotDestroyed();
   Vector<PhysicalRect> rects_in_flowthread;
   LayoutBlockFlow::AddOutlineRects(rects_in_flowthread, additional_offset,
                                    include_block_overflows);
@@ -211,6 +219,7 @@
                                    const HitTestLocation& hit_test_location,
                                    const PhysicalOffset& accumulated_offset,
                                    HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   if (hit_test_action == kHitTestBlockBackground)
     return false;
   return LayoutBlockFlow::NodeAtPoint(result, hit_test_location,
@@ -219,6 +228,7 @@
 
 LayoutUnit LayoutFlowThread::PageLogicalHeightForOffset(
     LayoutUnit offset) const {
+  CheckIsNotDestroyed();
   DCHECK(IsPageLogicalHeightKnown());
   LayoutMultiColumnSet* column_set =
       ColumnSetAtBlockOffset(offset, kAssociateWithLatterPage);
@@ -231,6 +241,7 @@
 LayoutUnit LayoutFlowThread::PageRemainingLogicalHeightForOffset(
     LayoutUnit offset,
     PageBoundaryRule page_boundary_rule) const {
+  CheckIsNotDestroyed();
   DCHECK(IsPageLogicalHeightKnown());
   LayoutMultiColumnSet* column_set =
       ColumnSetAtBlockOffset(offset, page_boundary_rule);
@@ -242,6 +253,7 @@
 }
 
 void LayoutFlowThread::GenerateColumnSetIntervalTree() {
+  CheckIsNotDestroyed();
   // FIXME: Optimize not to clear the interval all the time. This implies
   // manually managing the tree nodes lifecycle.
   multi_column_set_interval_tree_.Clear();
@@ -256,6 +268,7 @@
 LayoutUnit LayoutFlowThread::NextLogicalTopForUnbreakableContent(
     LayoutUnit flow_thread_offset,
     LayoutUnit content_logical_height) const {
+  CheckIsNotDestroyed();
   LayoutMultiColumnSet* column_set =
       ColumnSetAtBlockOffset(flow_thread_offset, kAssociateWithLatterPage);
   if (!column_set)
@@ -266,6 +279,7 @@
 
 LayoutRect LayoutFlowThread::FragmentsBoundingBox(
     const LayoutRect& layer_bounding_box) const {
+  CheckIsNotDestroyed();
   DCHECK(!column_sets_invalidated_);
 
   LayoutRect result;
@@ -278,6 +292,7 @@
 void LayoutFlowThread::FlowThreadToContainingCoordinateSpace(
     LayoutUnit& block_position,
     LayoutUnit& inline_position) const {
+  CheckIsNotDestroyed();
   LayoutPoint position(inline_position, block_position);
   // First we have to make |position| physical, because that's what offsetLeft()
   // expects and returns.
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 3ffeb29..6947effd 100644
--- a/third_party/blink/renderer/core/layout/layout_flow_thread.h
+++ b/third_party/blink/renderer/core/layout/layout_flow_thread.h
@@ -68,10 +68,17 @@
   explicit LayoutFlowThread(bool needs_paint_layer);
   ~LayoutFlowThread() override = default;
 
-  bool IsLayoutFlowThread() const final { return true; }
-  virtual bool IsLayoutMultiColumnFlowThread() const { return false; }
+  bool IsLayoutFlowThread() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
+  virtual bool IsLayoutMultiColumnFlowThread() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   bool CreatesNewFormattingContext() const final {
+    CheckIsNotDestroyed();
     // The spec requires multicol containers to establish new formatting
     // contexts. Blink uses an anonymous flow thread child of the multicol
     // container to actually perform layout inside. Therefore we need to
@@ -103,18 +110,29 @@
 
   PaintLayerType LayerTypeRequired() const final;
 
-  bool NeedsPreferredWidthsRecalculation() const final { return true; }
+  bool NeedsPreferredWidthsRecalculation() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
-  virtual void FlowThreadDescendantWasInserted(LayoutObject*) {}
-  virtual void FlowThreadDescendantWillBeRemoved(LayoutObject*) {}
+  virtual void FlowThreadDescendantWasInserted(LayoutObject*) {
+    CheckIsNotDestroyed();
+  }
+  virtual void FlowThreadDescendantWillBeRemoved(LayoutObject*) {
+    CheckIsNotDestroyed();
+  }
   virtual void FlowThreadDescendantStyleWillChange(
       LayoutBox*,
       StyleDifference,
-      const ComputedStyle& new_style) {}
+      const ComputedStyle& new_style) {
+    CheckIsNotDestroyed();
+  }
   virtual void FlowThreadDescendantStyleDidChange(
       LayoutBox*,
       StyleDifference,
-      const ComputedStyle& old_style) {}
+      const ComputedStyle& old_style) {
+    CheckIsNotDestroyed();
+  }
 
   void AbsoluteQuadsForDescendant(const LayoutBox& descendant,
                                   Vector<FloatQuad>&,
@@ -136,11 +154,18 @@
                             LayoutUnit logical_top,
                             LogicalExtentComputedValues&) const override;
 
-  bool HasColumnSets() const { return multi_column_set_list_.size(); }
+  bool HasColumnSets() const {
+    CheckIsNotDestroyed();
+    return multi_column_set_list_.size();
+  }
 
   void ValidateColumnSets();
-  void InvalidateColumnSets() { column_sets_invalidated_ = true; }
+  void InvalidateColumnSets() {
+    CheckIsNotDestroyed();
+    column_sets_invalidated_ = true;
+  }
   bool HasValidColumnSetInfo() const {
+    CheckIsNotDestroyed();
     return !column_sets_invalidated_ && !multi_column_set_list_.IsEmpty();
   }
 
@@ -171,9 +196,15 @@
       LayoutUnit flow_thread_offset,
       LayoutUnit content_logical_height) const;
 
-  virtual bool IsPageLogicalHeightKnown() const { return true; }
+  virtual bool IsPageLogicalHeightKnown() const {
+    CheckIsNotDestroyed();
+    return true;
+  }
   virtual bool MayHaveNonUniformPageLogicalHeight() const = 0;
-  bool PageLogicalSizeChanged() const { return page_logical_size_changed_; }
+  bool PageLogicalSizeChanged() const {
+    CheckIsNotDestroyed();
+    return page_logical_size_changed_;
+  }
 
   // Return the visual bounding box based on the supplied flow-thread bounding
   // box. Both rectangles are completely physical in terms of writing mode.
diff --git a/third_party/blink/renderer/core/layout/layout_frame.cc b/third_party/blink/renderer/core/layout/layout_frame.cc
index 350e48e..6b6f080 100644
--- a/third_party/blink/renderer/core/layout/layout_frame.cc
+++ b/third_party/blink/renderer/core/layout/layout_frame.cc
@@ -37,11 +37,13 @@
 }
 
 FrameEdgeInfo LayoutFrame::EdgeInfo() const {
+  CheckIsNotDestroyed();
   auto* element = To<HTMLFrameElement>(GetNode());
   return FrameEdgeInfo(element->NoResize(), element->HasFrameBorder());
 }
 
 void LayoutFrame::ImageChanged(WrappedImagePtr image, CanDeferInvalidation) {
+  CheckIsNotDestroyed();
   if (const CursorList* cursors = StyleRef().Cursors()) {
     for (const CursorData& cursor : *cursors) {
       if (cursor.GetImage() && cursor.GetImage()->CachedImage() == image) {
@@ -58,6 +60,7 @@
 }
 
 void LayoutFrame::UpdateFromElement() {
+  CheckIsNotDestroyed();
   if (Parent() && Parent()->IsFrameSet())
     ToLayoutFrameSet(Parent())->NotifyFrameEdgeInfoChanged();
 }
diff --git a/third_party/blink/renderer/core/layout/layout_frame.h b/third_party/blink/renderer/core/layout/layout_frame.h
index f8c70f9..709f241d 100644
--- a/third_party/blink/renderer/core/layout/layout_frame.h
+++ b/third_party/blink/renderer/core/layout/layout_frame.h
@@ -38,10 +38,14 @@
 
   void ImageChanged(WrappedImagePtr, CanDeferInvalidation) override;
 
-  const char* GetName() const override { return "LayoutFrame"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutFrame";
+  }
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectFrame || LayoutEmbeddedContent::IsOfType(type);
   }
 
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 fc00cf0c..f7bb93f0 100644
--- a/third_party/blink/renderer/core/layout/layout_frame_set.cc
+++ b/third_party/blink/renderer/core/layout/layout_frame_set.cc
@@ -58,10 +58,12 @@
 LayoutFrameSet::GridAxis::GridAxis() : split_being_resized_(kNoSplit) {}
 
 HTMLFrameSetElement* LayoutFrameSet::FrameSet() const {
+  CheckIsNotDestroyed();
   return To<HTMLFrameSetElement>(GetNode());
 }
 
 void LayoutFrameSet::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   FrameSetPainter(*this).Paint(paint_info);
 }
 
@@ -82,6 +84,7 @@
 void LayoutFrameSet::LayOutAxis(GridAxis& axis,
                                 const Vector<HTMLDimension>& grid,
                                 int available_len) {
+  CheckIsNotDestroyed();
   available_len = max(available_len, 0);
 
   int* grid_layout = axis.sizes_.data();
@@ -285,6 +288,7 @@
 }
 
 void LayoutFrameSet::NotifyFrameEdgeInfoChanged() {
+  CheckIsNotDestroyed();
   if (NeedsLayout())
     return;
   // FIXME: We should only recompute the edge info with respect to the frame
@@ -296,6 +300,7 @@
 void LayoutFrameSet::FillFromEdgeInfo(const FrameEdgeInfo& edge_info,
                                       int r,
                                       int c) {
+  CheckIsNotDestroyed();
   if (edge_info.AllowBorder(kLeftFrameEdge))
     cols_.allow_border_[c] = true;
   if (edge_info.AllowBorder(kRightFrameEdge))
@@ -316,6 +321,7 @@
 }
 
 void LayoutFrameSet::ComputeEdgeInfo() {
+  CheckIsNotDestroyed();
   rows_.prevent_resize_.Fill(FrameSet()->NoResize());
   rows_.allow_border_.Fill(false);
   cols_.prevent_resize_.Fill(FrameSet()->NoResize());
@@ -343,6 +349,7 @@
 }
 
 FrameEdgeInfo LayoutFrameSet::EdgeInfo() const {
+  CheckIsNotDestroyed();
   FrameEdgeInfo result(FrameSet()->NoResize(), true);
 
   int rows = FrameSet()->TotalRows();
@@ -362,6 +369,7 @@
 }
 
 void LayoutFrameSet::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
 
   if (!Parent()->IsFrameSet() && !GetDocument().Printing()) {
@@ -404,6 +412,7 @@
 }
 
 void LayoutFrameSet::PositionFrames() {
+  CheckIsNotDestroyed();
   LayoutBox* child = FirstChildBox();
   if (!child)
     return;
@@ -447,6 +456,7 @@
 }
 
 void LayoutFrameSet::StartResizing(GridAxis& axis, int position) {
+  CheckIsNotDestroyed();
   int split = HitTestSplit(axis, position);
   if (split == kNoSplit || axis.prevent_resize_[split]) {
     axis.split_being_resized_ = kNoSplit;
@@ -457,6 +467,7 @@
 }
 
 void LayoutFrameSet::ContinueResizing(GridAxis& axis, int position) {
+  CheckIsNotDestroyed();
   if (NeedsLayout())
     return;
   if (axis.split_being_resized_ == kNoSplit)
@@ -472,6 +483,7 @@
 }
 
 bool LayoutFrameSet::UserResize(const MouseEvent& evt) {
+  CheckIsNotDestroyed();
   if (!is_resizing_) {
     if (NeedsLayout())
       return false;
@@ -510,6 +522,7 @@
 }
 
 void LayoutFrameSet::SetIsResizing(bool is_resizing) {
+  CheckIsNotDestroyed();
   is_resizing_ = is_resizing;
   if (LocalFrame* frame = GetFrame()) {
     frame->GetEventHandler().SetResizingFrameSet(is_resizing ? FrameSet()
@@ -518,16 +531,19 @@
 }
 
 bool LayoutFrameSet::CanResizeRow(const IntPoint& p) const {
+  CheckIsNotDestroyed();
   int r = HitTestSplit(rows_, p.Y());
   return r != kNoSplit && !rows_.prevent_resize_[r];
 }
 
 bool LayoutFrameSet::CanResizeColumn(const IntPoint& p) const {
+  CheckIsNotDestroyed();
   int c = HitTestSplit(cols_, p.X());
   return c != kNoSplit && !cols_.prevent_resize_[c];
 }
 
 int LayoutFrameSet::SplitPosition(const GridAxis& axis, int split) const {
+  CheckIsNotDestroyed();
   if (NeedsLayout())
     return 0;
 
@@ -544,6 +560,7 @@
 }
 
 int LayoutFrameSet::HitTestSplit(const GridAxis& axis, int position) const {
+  CheckIsNotDestroyed();
   if (NeedsLayout())
     return kNoSplit;
 
@@ -567,11 +584,13 @@
 
 bool LayoutFrameSet::IsChildAllowed(LayoutObject* child,
                                     const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   return child->IsFrame() || child->IsFrameSet();
 }
 
 CursorDirective LayoutFrameSet::GetCursor(const PhysicalOffset& point,
                                           ui::Cursor& cursor) const {
+  CheckIsNotDestroyed();
   IntPoint rounded_point = RoundedIntPoint(point);
   if (CanResizeRow(rounded_point)) {
     cursor = RowResizeCursor();
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 e25859a8..ec9df3f0 100644
--- a/third_party/blink/renderer/core/layout/layout_frame_set.h
+++ b/third_party/blink/renderer/core/layout/layout_frame_set.h
@@ -69,10 +69,12 @@
   ~LayoutFrameSet() override;
 
   LayoutObject* FirstChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->FirstChild();
   }
   LayoutObject* LastChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->LastChild();
   }
@@ -81,8 +83,14 @@
   void SlowFirstChild() const = delete;
   void SlowLastChild() const = delete;
 
-  const LayoutObjectChildList* Children() const { return &children_; }
-  LayoutObjectChildList* Children() { return &children_; }
+  const LayoutObjectChildList* Children() const {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
+  LayoutObjectChildList* Children() {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
 
   FrameEdgeInfo EdgeInfo() const;
 
@@ -111,28 +119,46 @@
     int split_resize_offset_;
   };
 
-  const GridAxis& Rows() const { return rows_; }
-  const GridAxis& Columns() const { return cols_; }
+  const GridAxis& Rows() const {
+    CheckIsNotDestroyed();
+    return rows_;
+  }
+  const GridAxis& Columns() const {
+    CheckIsNotDestroyed();
+    return cols_;
+  }
 
-  const char* GetName() const override { return "LayoutFrameSet"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutFrameSet";
+  }
 
  private:
   static const int kNoSplit = -1;
 
-  LayoutObjectChildList* VirtualChildren() override { return Children(); }
+  LayoutObjectChildList* VirtualChildren() override {
+    CheckIsNotDestroyed();
+    return Children();
+  }
   const LayoutObjectChildList* VirtualChildren() const override {
+    CheckIsNotDestroyed();
     return Children();
   }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectFrameSet || LayoutBox::IsOfType(type);
   }
 
   void UpdateLayout() override;
   void Paint(const PaintInfo&) const override;
 
-  MinMaxSizes PreferredLogicalWidths() const override { return MinMaxSizes(); }
+  MinMaxSizes PreferredLogicalWidths() const override {
+    CheckIsNotDestroyed();
+    return MinMaxSizes();
+  }
   MinMaxSizes ComputeIntrinsicLogicalWidths() const final {
+    CheckIsNotDestroyed();
     return MinMaxSizes();
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_grid.cc b/third_party/blink/renderer/core/layout/layout_grid.cc
index ab63ad9..693bcd1 100644
--- a/third_party/blink/renderer/core/layout/layout_grid.cc
+++ b/third_party/blink/renderer/core/layout/layout_grid.cc
@@ -61,6 +61,7 @@
 }
 
 void LayoutGrid::AddChild(LayoutObject* new_child, LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   LayoutBlock::AddChild(new_child, before_child);
 
   // Positioned grid items do not take up space or otherwise participate in the
@@ -75,6 +76,7 @@
 }
 
 void LayoutGrid::RemoveChild(LayoutObject* child) {
+  CheckIsNotDestroyed();
   LayoutBlock::RemoveChild(child);
 
   // Positioned grid items do not take up space or otherwise participate in the
@@ -92,6 +94,7 @@
     GridAxis axis,
     const LayoutBox& child,
     const ComputedStyle* style) const {
+  CheckIsNotDestroyed();
   return axis == kGridRowAxis ? JustifySelfForChild(child, style)
                               : AlignSelfForChild(child, style);
 }
@@ -99,6 +102,7 @@
 StyleSelfAlignmentData LayoutGrid::DefaultAlignment(
     GridAxis axis,
     const ComputedStyle& style) const {
+  CheckIsNotDestroyed();
   return axis == kGridRowAxis
              ? style.ResolvedJustifyItems(ItemPosition::kNormal)
              : style.ResolvedAlignItems(ItemPosition::kNormal);
@@ -107,6 +111,7 @@
 bool LayoutGrid::DefaultAlignmentIsStretchOrNormal(
     GridAxis axis,
     const ComputedStyle& style) const {
+  CheckIsNotDestroyed();
   ItemPosition alignment = DefaultAlignment(axis, style).GetPosition();
   return alignment == ItemPosition::kStretch ||
          alignment == ItemPosition::kNormal;
@@ -116,6 +121,7 @@
                                           const ComputedStyle& old_style,
                                           const ComputedStyle& new_style,
                                           const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   return SelfAlignmentForChild(axis, child, &old_style).GetPosition() ==
                  ItemPosition::kStretch
              ? SelfAlignmentForChild(axis, child, &new_style).GetPosition() !=
@@ -128,6 +134,7 @@
     GridAxis axis,
     const ComputedStyle& old_style,
     const ComputedStyle& new_style) const {
+  CheckIsNotDestroyed();
   return DefaultAlignmentIsStretchOrNormal(axis, old_style)
              ? DefaultAlignment(axis, old_style).GetPosition() !=
                    DefaultAlignment(axis, new_style).GetPosition()
@@ -136,6 +143,7 @@
 
 void LayoutGrid::StyleDidChange(StyleDifference diff,
                                 const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutBlock::StyleDidChange(diff, old_style);
   if (!old_style)
     return;
@@ -178,6 +186,7 @@
 }
 
 bool LayoutGrid::ExplicitGridDidResize(const ComputedStyle& old_style) const {
+  CheckIsNotDestroyed();
   return old_style.GridTemplateColumns().LegacyTrackList().size() !=
              StyleRef().GridTemplateColumns().LegacyTrackList().size() ||
          old_style.GridTemplateRows().LegacyTrackList().size() !=
@@ -194,6 +203,7 @@
 
 bool LayoutGrid::NamedGridLinesDefinitionDidChange(
     const ComputedStyle& old_style) const {
+  CheckIsNotDestroyed();
   return old_style.NamedGridRowLines() != StyleRef().NamedGridRowLines() ||
          old_style.NamedGridColumnLines() !=
              StyleRef().NamedGridColumnLines() ||
@@ -206,6 +216,7 @@
 void LayoutGrid::ComputeTrackSizesForDefiniteSize(
     GridTrackSizingDirection direction,
     LayoutUnit available_space) {
+  CheckIsNotDestroyed();
   track_sizing_algorithm_.Setup(direction, NumTracks(direction, *grid_),
                                 available_space);
   track_sizing_algorithm_.Run();
@@ -218,6 +229,7 @@
 void LayoutGrid::RepeatTracksSizingIfNeeded(
     LayoutUnit available_space_for_columns,
     LayoutUnit available_space_for_rows) {
+  CheckIsNotDestroyed();
   // In orthogonal flow cases column track's size is determined by using the
   // computed row track's size, which it was estimated during the first cycle of
   // the sizing algorithm.
@@ -250,6 +262,7 @@
 }
 
 void LayoutGrid::UpdateBlockLayout(bool relayout_children) {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
 
   // We cannot perform a |SimplifiedLayout()| with a dirty grid.
@@ -408,6 +421,7 @@
 LayoutUnit LayoutGrid::GridGap(
     GridTrackSizingDirection direction,
     base::Optional<LayoutUnit> available_size) const {
+  CheckIsNotDestroyed();
   const base::Optional<Length>& gap =
       direction == kForColumns ? StyleRef().ColumnGap() : StyleRef().RowGap();
   if (!gap)
@@ -417,6 +431,7 @@
 }
 
 LayoutUnit LayoutGrid::GridGap(GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   LayoutUnit available_size;
   bool is_row_axis = direction == kForColumns;
 
@@ -441,6 +456,7 @@
     size_t start_line,
     size_t span,
     base::Optional<LayoutUnit> available_size) const {
+  CheckIsNotDestroyed();
   if (span <= 1)
     return LayoutUnit();
 
@@ -517,6 +533,7 @@
 }
 
 MinMaxSizes LayoutGrid::ComputeIntrinsicLogicalWidths() const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes;
   sizes +=
       BorderAndPaddingLogicalWidth() + ComputeLogicalScrollbars().InlineSum();
@@ -557,6 +574,7 @@
 void LayoutGrid::ComputeTrackSizesForIndefiniteSize(
     GridTrackSizingAlgorithm& algo,
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   const Grid& grid = algo.GetGrid();
   algo.Setup(direction, NumTracks(direction, grid), base::nullopt);
   algo.Run();
@@ -568,6 +586,7 @@
 
 base::Optional<LayoutUnit> LayoutGrid::OverrideIntrinsicContentLogicalSize(
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   if (direction == kForColumns && HasOverrideIntrinsicContentLogicalWidth())
     return OverrideIntrinsicContentLogicalWidth();
   if (direction == kForRows && HasOverrideIntrinsicContentLogicalHeight())
@@ -594,6 +613,7 @@
 size_t LayoutGrid::ComputeAutoRepeatTracksCount(
     GridTrackSizingDirection direction,
     base::Optional<LayoutUnit> available_size) const {
+  CheckIsNotDestroyed();
   DCHECK(!available_size || available_size.value() != -1);
   bool is_row_axis = direction == kForColumns;
   // Since auto-fit collapses empty tracks, and contain: size dictates that
@@ -757,6 +777,7 @@
 LayoutGrid::ComputeEmptyTracksForAutoRepeat(
     Grid& grid,
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   bool is_row_axis = direction == kForColumns;
   if ((is_row_axis &&
        StyleRef().GridAutoRepeatColumnsType() != AutoRepeatType::kAutoFit) ||
@@ -794,6 +815,7 @@
 
 size_t LayoutGrid::ClampAutoRepeatTracks(GridTrackSizingDirection direction,
                                          size_t auto_repeat_tracks) const {
+  CheckIsNotDestroyed();
   if (!auto_repeat_tracks)
     return 0;
 
@@ -820,6 +842,7 @@
 void LayoutGrid::PlaceItemsOnGrid(
     GridTrackSizingAlgorithm& algorithm,
     base::Optional<LayoutUnit> available_logical_width) const {
+  CheckIsNotDestroyed();
   Grid& grid = algorithm.GetMutableGrid();
   size_t auto_repeat_rows = ComputeAutoRepeatTracksCount(
       kForRows, ConvertLayoutUnitToOptional(
@@ -931,6 +954,7 @@
 
 void LayoutGrid::PerformGridItemsPreLayout(
     const GridTrackSizingAlgorithm& algorithm) const {
+  CheckIsNotDestroyed();
   DCHECK(!algorithm.GetGrid().NeedsItemsPlacement());
   if (!GetDocument().View()->IsInPerformLayout())
     return;
@@ -968,6 +992,7 @@
 }
 
 void LayoutGrid::PopulateExplicitGridAndOrderIterator(Grid& grid) const {
+  CheckIsNotDestroyed();
   OrderIteratorPopulator populator(grid.GetOrderIterator());
   size_t explicit_row_start = 0;
   size_t explicit_column_start = 0;
@@ -1032,6 +1057,7 @@
     const LayoutBox& grid_item,
     GridTrackSizingDirection specified_direction,
     const GridSpan& specified_positions) const {
+  CheckIsNotDestroyed();
   GridTrackSizingDirection cross_direction =
       specified_direction == kForColumns ? kForRows : kForColumns;
   const size_t end_of_cross_direction = grid.NumTracks(cross_direction);
@@ -1051,6 +1077,7 @@
 void LayoutGrid::PlaceSpecifiedMajorAxisItemsOnGrid(
     Grid& grid,
     const Vector<LayoutBox*>& auto_grid_items) const {
+  CheckIsNotDestroyed();
   bool is_for_columns = AutoPlacementMajorAxisDirection() == kForColumns;
   bool is_grid_auto_flow_dense = StyleRef().IsGridAutoFlowAlgorithmDense();
 
@@ -1096,6 +1123,7 @@
 void LayoutGrid::PlaceAutoMajorAxisItemsOnGrid(
     Grid& grid,
     const Vector<LayoutBox*>& auto_grid_items) const {
+  CheckIsNotDestroyed();
   std::pair<size_t, size_t> auto_placement_cursor = std::make_pair(0, 0);
   bool is_grid_auto_flow_dense = StyleRef().IsGridAutoFlowAlgorithmDense();
 
@@ -1114,6 +1142,7 @@
     Grid& grid,
     LayoutBox& grid_item,
     std::pair<size_t, size_t>& auto_placement_cursor) const {
+  CheckIsNotDestroyed();
   GridSpan minor_axis_positions =
       grid.GridItemSpan(grid_item, AutoPlacementMinorAxisDirection());
   DCHECK(!grid.GridItemSpan(grid_item, AutoPlacementMajorAxisDirection())
@@ -1202,14 +1231,17 @@
 }
 
 GridTrackSizingDirection LayoutGrid::AutoPlacementMajorAxisDirection() const {
+  CheckIsNotDestroyed();
   return StyleRef().IsGridAutoFlowDirectionColumn() ? kForColumns : kForRows;
 }
 
 GridTrackSizingDirection LayoutGrid::AutoPlacementMinorAxisDirection() const {
+  CheckIsNotDestroyed();
   return StyleRef().IsGridAutoFlowDirectionColumn() ? kForRows : kForColumns;
 }
 
 void LayoutGrid::DirtyGrid() {
+  CheckIsNotDestroyed();
   if (grid_->NeedsItemsPlacement())
     return;
 
@@ -1218,6 +1250,7 @@
 
 Vector<LayoutUnit> LayoutGrid::TrackSizesForComputedStyle(
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   bool is_row_axis = direction == kForColumns;
   auto& positions = is_row_axis ? column_positions_ : row_positions_;
   size_t num_positions = positions.size();
@@ -1291,6 +1324,7 @@
 void LayoutGrid::UpdateGridAreaLogicalSize(
     LayoutBox& child,
     LayoutSize grid_area_logical_size) const {
+  CheckIsNotDestroyed();
   // Because the grid area cannot be styled, we don't need to adjust
   // the grid breadth to account for 'box-sizing'.
   bool grid_area_width_changed =
@@ -1309,6 +1343,7 @@
 }
 
 void LayoutGrid::LayoutGridItems() {
+  CheckIsNotDestroyed();
   if (ChildLayoutBlockedByDisplayLock())
     return;
 
@@ -1369,6 +1404,7 @@
 }
 
 void LayoutGrid::PrepareChildForPositionedLayout(LayoutBox& child) {
+  CheckIsNotDestroyed();
   DCHECK(child.IsOutOfFlowPositioned());
   child.ContainingBlock()->InsertPositionedObject(&child);
 
@@ -1382,6 +1418,7 @@
 bool LayoutGrid::HasStaticPositionForChild(
     const LayoutBox& child,
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   return direction == kForColumns ? child.StyleRef().HasStaticInlinePosition(
                                         IsHorizontalWritingMode())
                                   : child.StyleRef().HasStaticBlockPosition(
@@ -1390,6 +1427,7 @@
 
 void LayoutGrid::LayoutPositionedObjects(bool relayout_children,
                                          PositionedLayoutBehavior info) {
+  CheckIsNotDestroyed();
   if (ChildLayoutBlockedByDisplayLock())
     return;
 
@@ -1424,6 +1462,7 @@
 LayoutUnit LayoutGrid::GridAreaBreadthForChildIncludingAlignmentOffsets(
     const LayoutBox& child,
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   // We need the cached value when available because Content Distribution
   // alignment properties may have some influence in the final grid area
   // breadth.
@@ -1442,6 +1481,7 @@
 
 void LayoutGrid::PopulateGridPositionsForDirection(
     GridTrackSizingDirection direction) {
+  CheckIsNotDestroyed();
   // Since we add alignment offsets and track gutters, grid lines are not always
   // adjacent. Hence we will have to assume from now on that we just store
   // positions of the initial grid lines of each track, except the last one,
@@ -1543,6 +1583,7 @@
 LayoutUnit LayoutGrid::AvailableAlignmentSpaceForChildBeforeStretching(
     LayoutUnit grid_area_breadth_for_child,
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   // Because we want to avoid multiple layouts, stretching logic might be
   // performed before children are laid out, so we can't use the child cached
   // values. Hence, we may need to compute margins in order to determine the
@@ -1554,6 +1595,7 @@
 StyleSelfAlignmentData LayoutGrid::AlignSelfForChild(
     const LayoutBox& child,
     const ComputedStyle* style) const {
+  CheckIsNotDestroyed();
   if (!style)
     style = Style();
   return child.StyleRef().ResolvedAlignSelf(SelfAlignmentNormalBehavior(&child),
@@ -1563,6 +1605,7 @@
 StyleSelfAlignmentData LayoutGrid::JustifySelfForChild(
     const LayoutBox& child,
     const ComputedStyle* style) const {
+  CheckIsNotDestroyed();
   if (!style)
     style = Style();
   return child.StyleRef().ResolvedJustifySelf(
@@ -1572,6 +1615,7 @@
 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to
 // LayoutBox.
 void LayoutGrid::ApplyStretchAlignmentToChildIfNeeded(LayoutBox& child) {
+  CheckIsNotDestroyed();
   GridTrackSizingDirection child_block_direction =
       GridLayoutUtils::FlowAwareDirectionForChild(*this, child, kForRows);
   bool block_flow_is_column_axis = child_block_direction == kForRows;
@@ -1599,6 +1643,7 @@
 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be
 // moved to LayoutBox.
 bool LayoutGrid::HasAutoMarginsInColumnAxis(const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   if (IsHorizontalWritingMode())
     return child.StyleRef().MarginTop().IsAuto() ||
            child.StyleRef().MarginBottom().IsAuto();
@@ -1609,6 +1654,7 @@
 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be
 // moved to LayoutBox.
 bool LayoutGrid::HasAutoMarginsInRowAxis(const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   if (IsHorizontalWritingMode())
     return child.StyleRef().MarginLeft().IsAuto() ||
            child.StyleRef().MarginRight().IsAuto();
@@ -1620,6 +1666,7 @@
 // moved to LayoutBox.
 DISABLE_CFI_PERF
 void LayoutGrid::UpdateAutoMarginsInRowAxisIfNeeded(LayoutBox& child) {
+  CheckIsNotDestroyed();
   DCHECK(!child.IsOutOfFlowPositioned());
 
   const Length& margin_start = child.StyleRef().MarginStartUsing(StyleRef());
@@ -1652,6 +1699,7 @@
 // moved to LayoutBox.
 DISABLE_CFI_PERF
 void LayoutGrid::UpdateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child) {
+  CheckIsNotDestroyed();
   DCHECK(!child.IsOutOfFlowPositioned());
 
   const Length& margin_before = child.StyleRef().MarginBeforeUsing(StyleRef());
@@ -1693,6 +1741,7 @@
                                         bool,
                                         LineDirectionMode direction,
                                         LinePositionMode mode) const {
+  CheckIsNotDestroyed();
   DCHECK_EQ(mode, kPositionOnContainingLine);
   LayoutUnit baseline = FirstLineBoxBaseline();
   // We take border-box's bottom if no valid baseline.
@@ -1705,6 +1754,7 @@
 }
 
 LayoutUnit LayoutGrid::FirstLineBoxBaseline() const {
+  CheckIsNotDestroyed();
   if (IsWritingModeRoot() || !grid_->HasGridItems() ||
       ShouldApplyLayoutContainment())
     return LayoutUnit(-1);
@@ -1761,16 +1811,19 @@
 }
 
 LayoutUnit LayoutGrid::InlineBlockBaseline(LineDirectionMode direction) const {
+  CheckIsNotDestroyed();
   return FirstLineBoxBaseline();
 }
 
 bool LayoutGrid::IsBaselineAlignmentForChild(const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   return IsBaselineAlignmentForChild(child, kGridRowAxis) ||
          IsBaselineAlignmentForChild(child, kGridColumnAxis);
 }
 
 bool LayoutGrid::IsBaselineAlignmentForChild(const LayoutBox& child,
                                              GridAxis baseline_axis) const {
+  CheckIsNotDestroyed();
   if (child.IsOutOfFlowPositioned())
     return false;
   ItemPosition align =
@@ -1783,16 +1836,19 @@
 
 LayoutUnit LayoutGrid::ColumnAxisBaselineOffsetForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   return track_sizing_algorithm_.BaselineOffsetForChild(child, kGridColumnAxis);
 }
 
 LayoutUnit LayoutGrid::RowAxisBaselineOffsetForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   return track_sizing_algorithm_.BaselineOffsetForChild(child, kGridRowAxis);
 }
 
 GridAxisPosition LayoutGrid::ColumnAxisPositionForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   bool has_same_writing_mode =
       child.StyleRef().GetWritingMode() == StyleRef().GetWritingMode();
   bool child_is_ltr = child.StyleRef().IsLeftToRightDirection();
@@ -1868,6 +1924,7 @@
 
 GridAxisPosition LayoutGrid::RowAxisPositionForChild(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   bool has_same_direction =
       child.StyleRef().Direction() == StyleRef().Direction();
   bool grid_is_ltr = StyleRef().IsLeftToRightDirection();
@@ -1948,6 +2005,7 @@
 }
 
 LayoutUnit LayoutGrid::ColumnAxisOffsetForChild(const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   LayoutUnit start_of_row;
   LayoutUnit end_of_row;
   GridAreaPositionForChild(child, kForRows, start_of_row, end_of_row);
@@ -1978,6 +2036,7 @@
 }
 
 LayoutUnit LayoutGrid::RowAxisOffsetForChild(const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   LayoutUnit start_of_column;
   LayoutUnit end_of_column;
   GridAreaPositionForChild(child, kForColumns, start_of_column, end_of_column);
@@ -2009,6 +2068,7 @@
 
 LayoutUnit LayoutGrid::ResolveAutoStartGridPosition(
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   if (direction == kForRows || StyleRef().IsLeftToRightDirection())
     return LayoutUnit();
 
@@ -2027,6 +2087,7 @@
 
 LayoutUnit LayoutGrid::ResolveAutoEndGridPosition(
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   if (direction == kForRows)
     return ClientLogicalHeight();
   if (StyleRef().IsLeftToRightDirection())
@@ -2050,6 +2111,7 @@
 LayoutUnit LayoutGrid::GridAreaBreadthForOutOfFlowChild(
     const LayoutBox& child,
     GridTrackSizingDirection direction) {
+  CheckIsNotDestroyed();
   DCHECK(child.IsOutOfFlowPositioned());
   bool is_row_axis = direction == kForColumns;
   GridSpan span = GridPositionsResolver::ResolveGridPositionsFromStyle(
@@ -2116,6 +2178,7 @@
     const LayoutBox& child,
     GridTrackSizingDirection direction,
     LayoutUnit track_breadth) const {
+  CheckIsNotDestroyed();
   DCHECK(child.IsOutOfFlowPositioned());
   if (HasStaticPositionForChild(child, direction))
     return LayoutUnit();
@@ -2144,6 +2207,7 @@
     GridTrackSizingDirection direction,
     LayoutUnit& start,
     LayoutUnit& end) const {
+  CheckIsNotDestroyed();
   DCHECK(child.IsOutOfFlowPositioned());
   DCHECK(GridLayoutUtils::HasOverrideContainingBlockContentSizeForChild(
       child, direction));
@@ -2167,6 +2231,7 @@
     GridTrackSizingDirection direction,
     LayoutUnit& start,
     LayoutUnit& end) const {
+  CheckIsNotDestroyed();
   DCHECK(!child.IsOutOfFlowPositioned());
   const Grid& grid = track_sizing_algorithm_.GetGrid();
   const GridSpan& span = grid.GridItemSpan(child, direction);
@@ -2191,6 +2256,7 @@
                                           GridTrackSizingDirection direction,
                                           LayoutUnit& start,
                                           LayoutUnit& end) const {
+  CheckIsNotDestroyed();
   if (child.IsOutOfFlowPositioned())
     GridAreaPositionForOutOfFlowChild(child, direction, start, end);
   else
@@ -2265,6 +2331,7 @@
 
 StyleContentAlignmentData LayoutGrid::ContentAlignment(
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   return direction == kForColumns ? StyleRef().ResolvedJustifyContent(
                                         ContentAlignmentNormalBehavior())
                                   : StyleRef().ResolvedAlignContent(
@@ -2275,6 +2342,7 @@
     GridTrackSizingDirection direction,
     const LayoutUnit& available_free_space,
     unsigned number_of_grid_tracks) {
+  CheckIsNotDestroyed();
   auto& offset =
       direction == kForColumns ? offset_between_columns_ : offset_between_rows_;
   StyleContentAlignmentData content_alignment_data =
@@ -2363,6 +2431,7 @@
 LayoutUnit LayoutGrid::TranslateOutOfFlowRTLCoordinate(
     const LayoutBox& child,
     LayoutUnit coordinate) const {
+  CheckIsNotDestroyed();
   DCHECK(child.IsOutOfFlowPositioned());
   DCHECK(!StyleRef().IsLeftToRightDirection());
 
@@ -2374,6 +2443,7 @@
 }
 
 LayoutUnit LayoutGrid::TranslateRTLCoordinate(LayoutUnit coordinate) const {
+  CheckIsNotDestroyed();
   DCHECK(!StyleRef().IsLeftToRightDirection());
 
   LayoutUnit alignment_offset = column_positions_[0];
@@ -2385,6 +2455,7 @@
 // TODO: SetLogicalPositionForChild has only one caller, consider its
 // refactoring in the future.
 void LayoutGrid::SetLogicalPositionForChild(LayoutBox& child) const {
+  CheckIsNotDestroyed();
   // "In the positioning phase [...] calculations are performed according to the
   // writing mode of the containing block of the box establishing the orthogonal
   // flow." However, 'setLogicalPosition' will only take into account the
@@ -2399,6 +2470,7 @@
 void LayoutGrid::SetLogicalOffsetForChild(
     LayoutBox& child,
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   if (!child.IsGridItem() && HasStaticPositionForChild(child, direction))
     return;
   // 'SetLogicalLeft' and 'SetLogicalTop' only take into account the child's
@@ -2413,6 +2485,7 @@
 LayoutUnit LayoutGrid::LogicalOffsetForChild(
     const LayoutBox& child,
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   if (direction == kForRows) {
     return ColumnAxisOffsetForChild(child);
   }
@@ -2433,6 +2506,7 @@
 }
 
 LayoutPoint LayoutGrid::GridAreaLogicalPosition(const GridArea& area) const {
+  CheckIsNotDestroyed();
   LayoutUnit column_axis_offset = row_positions_[area.rows.StartLine()];
   LayoutUnit row_axis_offset = column_positions_[area.columns.StartLine()];
 
@@ -2446,6 +2520,7 @@
 
 void LayoutGrid::PaintChildren(const PaintInfo& paint_info,
                                const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   DCHECK(!grid_->NeedsItemsPlacement());
   if (grid_->HasGridItems()) {
     BlockPainter(*this).PaintChildrenAtomically(grid_->GetOrderIterator(),
@@ -2454,12 +2529,14 @@
 }
 
 bool LayoutGrid::CachedHasDefiniteLogicalHeight() const {
+  CheckIsNotDestroyed();
   SECURITY_DCHECK(has_definite_logical_height_);
   return has_definite_logical_height_.value();
 }
 
 size_t LayoutGrid::NonCollapsedTracks(
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   auto& tracks = track_sizing_algorithm_.Tracks(direction);
   size_t number_of_tracks = tracks.size();
   bool has_collapsed_tracks = grid_->HasAutoRepeatEmptyTracks(direction);
@@ -2471,6 +2548,7 @@
 
 size_t LayoutGrid::NumTracks(GridTrackSizingDirection direction,
                              const Grid& grid) const {
+  CheckIsNotDestroyed();
   // Due to limitations in our internal representation, we cannot know the
   // number of columns from m_grid *if* there is no row (because m_grid would be
   // empty). That's why in that case we need to get it from the style. Note that
@@ -2489,6 +2567,7 @@
 
 size_t LayoutGrid::ExplicitGridEndForDirection(
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   size_t leading = ExplicitGridStartForDirection(direction);
 
   if (direction == kForRows) {
@@ -2502,6 +2581,7 @@
 
 LayoutUnit LayoutGrid::GridItemOffset(
     GridTrackSizingDirection direction) const {
+  CheckIsNotDestroyed();
   return direction == kForRows ? offset_between_rows_.distribution_offset
                                : offset_between_columns_.distribution_offset;
 }
diff --git a/third_party/blink/renderer/core/layout/layout_grid.h b/third_party/blink/renderer/core/layout/layout_grid.h
index c127832..359150b 100644
--- a/third_party/blink/renderer/core/layout/layout_grid.h
+++ b/third_party/blink/renderer/core/layout/layout_grid.h
@@ -58,7 +58,10 @@
   ~LayoutGrid() override;
 
   static LayoutGrid* CreateAnonymous(Document*);
-  const char* GetName() const override { return "LayoutGrid"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutGrid";
+  }
 
   void UpdateBlockLayout(bool relayout_children) override;
 
@@ -67,11 +70,13 @@
   Vector<LayoutUnit> TrackSizesForComputedStyle(GridTrackSizingDirection) const;
 
   const Vector<LayoutUnit>& ColumnPositions() const {
+    CheckIsNotDestroyed();
     DCHECK(!grid_->NeedsItemsPlacement());
     return column_positions_;
   }
 
   const Vector<LayoutUnit>& RowPositions() const {
+    CheckIsNotDestroyed();
     DCHECK(!grid_->NeedsItemsPlacement());
     return row_positions_;
   }
@@ -79,6 +84,7 @@
   // TODO(svillar): rename this method as this does not return a
   // GridCell but its contents.
   const GridItemList& GetGridCell(int row, int column) const {
+    CheckIsNotDestroyed();
     SECURITY_DCHECK(!grid_->NeedsItemsPlacement());
     return grid_->Cell(row, column);
   }
@@ -123,11 +129,15 @@
   size_t ExplicitGridEndForDirection(GridTrackSizingDirection) const;
 
   // Exposed for testing *ONLY*.
-  Grid* InternalGrid() const { return grid_.get(); }
+  Grid* InternalGrid() const {
+    CheckIsNotDestroyed();
+    return grid_.get();
+  }
 
  protected:
   ItemPosition SelfAlignmentNormalBehavior(
       const LayoutBox* child = nullptr) const override {
+    CheckIsNotDestroyed();
     DCHECK(child);
     return child->IsLayoutReplaced() ? ItemPosition::kStart
                                      : ItemPosition::kStretch;
@@ -135,6 +145,7 @@
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectLayoutGrid || LayoutBlock::IsOfType(type);
   }
   MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
@@ -260,18 +271,22 @@
   bool DefaultAlignmentIsStretchOrNormal(GridAxis, const ComputedStyle&) const;
   void ApplyStretchAlignmentToChildIfNeeded(LayoutBox&);
   bool HasAutoSizeInColumnAxis(const LayoutBox& child) const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? child.StyleRef().Height().IsAuto()
                                      : child.StyleRef().Width().IsAuto();
   }
   bool HasAutoSizeInRowAxis(const LayoutBox& child) const {
+    CheckIsNotDestroyed();
     return IsHorizontalWritingMode() ? child.StyleRef().Width().IsAuto()
                                      : child.StyleRef().Height().IsAuto();
   }
   bool AllowedToStretchChildAlongColumnAxis(const LayoutBox& child) const {
+    CheckIsNotDestroyed();
     return AlignSelfForChild(child).GetPosition() == ItemPosition::kStretch &&
            HasAutoSizeInColumnAxis(child) && !HasAutoMarginsInColumnAxis(child);
   }
   bool AllowedToStretchChildAlongRowAxis(const LayoutBox& child) const {
+    CheckIsNotDestroyed();
     return JustifySelfForChild(child).GetPosition() == ItemPosition::kStretch &&
            HasAutoSizeInRowAxis(child) && !HasAutoMarginsInRowAxis(child);
   }
diff --git a/third_party/blink/renderer/core/layout/layout_html_canvas.cc b/third_party/blink/renderer/core/layout/layout_html_canvas.cc
index 1023bca..9b95193 100644
--- a/third_party/blink/renderer/core/layout/layout_html_canvas.cc
+++ b/third_party/blink/renderer/core/layout/layout_html_canvas.cc
@@ -40,15 +40,18 @@
 }
 
 PaintLayerType LayoutHTMLCanvas::LayerTypeRequired() const {
+  CheckIsNotDestroyed();
   return kNormalPaintLayer;
 }
 
 void LayoutHTMLCanvas::PaintReplaced(const PaintInfo& paint_info,
                                      const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   HTMLCanvasPainter(*this).PaintReplaced(paint_info, paint_offset);
 }
 
 void LayoutHTMLCanvas::CanvasSizeChanged() {
+  CheckIsNotDestroyed();
   IntSize canvas_size = To<HTMLCanvasElement>(GetNode())->Size();
   LayoutSize zoomed_size(canvas_size.Width() * StyleRef().EffectiveZoom(),
                          canvas_size.Height() * StyleRef().EffectiveZoom());
@@ -67,6 +70,7 @@
 
 void LayoutHTMLCanvas::InvalidatePaint(
     const PaintInvalidatorContext& context) const {
+  CheckIsNotDestroyed();
   auto* element = To<HTMLCanvasElement>(GetNode());
   if (element->IsDirty())
     element->DoDeferredPaintInvalidation();
@@ -75,6 +79,7 @@
 }
 
 CompositingReasons LayoutHTMLCanvas::AdditionalCompositingReasons() const {
+  CheckIsNotDestroyed();
   if (To<HTMLCanvasElement>(GetNode())->ShouldBeDirectComposited())
     return CompositingReason::kCanvas;
   return CompositingReason::kNone;
@@ -82,11 +87,13 @@
 
 void LayoutHTMLCanvas::StyleDidChange(StyleDifference diff,
                                       const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutReplaced::StyleDidChange(diff, old_style);
   To<HTMLCanvasElement>(GetNode())->StyleDidChange(old_style, StyleRef());
 }
 
 void LayoutHTMLCanvas::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   LayoutReplaced::WillBeDestroyed();
   To<HTMLCanvasElement>(GetNode())->LayoutObjectDestroyed();
 }
diff --git a/third_party/blink/renderer/core/layout/layout_html_canvas.h b/third_party/blink/renderer/core/layout/layout_html_canvas.h
index d1b8612..3a4e99a3 100644
--- a/third_party/blink/renderer/core/layout/layout_html_canvas.h
+++ b/third_party/blink/renderer/core/layout/layout_html_canvas.h
@@ -37,6 +37,7 @@
   explicit LayoutHTMLCanvas(HTMLCanvasElement*);
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectCanvas || LayoutReplaced::IsOfType(type);
   }
   PaintLayerType LayerTypeRequired() const override;
@@ -47,16 +48,25 @@
 
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
 
-  const char* GetName() const override { return "LayoutHTMLCanvas"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutHTMLCanvas";
+  }
 
   void WillBeDestroyed() override;
 
  private:
   void PaintReplaced(const PaintInfo&,
                      const PhysicalOffset& paint_offset) const override;
-  void IntrinsicSizeChanged() override { CanvasSizeChanged(); }
+  void IntrinsicSizeChanged() override {
+    CheckIsNotDestroyed();
+    CanvasSizeChanged();
+  }
 
-  bool CanHaveAdditionalCompositingReasons() const override { return true; }
+  bool CanHaveAdditionalCompositingReasons() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
   CompositingReasons AdditionalCompositingReasons() const override;
 };
 
diff --git a/third_party/blink/renderer/core/layout/layout_iframe.cc b/third_party/blink/renderer/core/layout/layout_iframe.cc
index bac95e51..66fab723 100644
--- a/third_party/blink/renderer/core/layout/layout_iframe.cc
+++ b/third_party/blink/renderer/core/layout/layout_iframe.cc
@@ -34,20 +34,24 @@
     : LayoutEmbeddedContent(element) {}
 
 bool LayoutIFrame::ShouldComputeSizeAsReplaced() const {
+  CheckIsNotDestroyed();
   return true;
 }
 
 bool LayoutIFrame::IsInlineBlockOrInlineTable() const {
+  CheckIsNotDestroyed();
   return IsInline();
 }
 
 PaintLayerType LayoutIFrame::LayerTypeRequired() const {
+  CheckIsNotDestroyed();
   if (StyleRef().HasResize())
     return kNormalPaintLayer;
   return LayoutEmbeddedContent::LayerTypeRequired();
 }
 
 void LayoutIFrame::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
 
@@ -63,6 +67,7 @@
 
 void LayoutIFrame::StyleWillChange(StyleDifference diff,
                                    const ComputedStyle& new_style) {
+  CheckIsNotDestroyed();
   if (Style() && StyleRef().UsedColorSchemeForInitialColors() !=
                      new_style.UsedColorSchemeForInitialColors()) {
     GetFrameOwnerElement()->SetColorScheme(
diff --git a/third_party/blink/renderer/core/layout/layout_iframe.h b/third_party/blink/renderer/core/layout/layout_iframe.h
index 1cc4793..0bcfa3f5 100644
--- a/third_party/blink/renderer/core/layout/layout_iframe.h
+++ b/third_party/blink/renderer/core/layout/layout_iframe.h
@@ -34,7 +34,10 @@
  public:
   explicit LayoutIFrame(HTMLFrameOwnerElement*);
 
-  const char* GetName() const override { return "LayoutIFrame"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutIFrame";
+  }
 
  private:
   bool ShouldComputeSizeAsReplaced() const override;
@@ -43,6 +46,7 @@
   void UpdateLayout() override;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectLayoutIFrame ||
            LayoutEmbeddedContent::IsOfType(type);
   }
diff --git a/third_party/blink/renderer/core/layout/layout_image.cc b/third_party/blink/renderer/core/layout/layout_image.cc
index 624db750..3fcc4f8 100644
--- a/third_party/blink/renderer/core/layout/layout_image.cc
+++ b/third_party/blink/renderer/core/layout/layout_image.cc
@@ -67,6 +67,7 @@
 LayoutImage::~LayoutImage() = default;
 
 void LayoutImage::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   DCHECK(image_resource_);
   image_resource_->Shutdown();
 
@@ -75,6 +76,7 @@
 
 void LayoutImage::StyleDidChange(StyleDifference diff,
                                  const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutReplaced::StyleDidChange(diff, old_style);
 
   bool old_orientation =
@@ -85,6 +87,7 @@
 }
 
 void LayoutImage::SetImageResource(LayoutImageResource* image_resource) {
+  CheckIsNotDestroyed();
   DCHECK(!image_resource_);
   image_resource_ = image_resource;
   image_resource_->Initialize(this);
@@ -92,6 +95,7 @@
 
 void LayoutImage::ImageChanged(WrappedImagePtr new_image,
                                CanDeferInvalidation defer) {
+  CheckIsNotDestroyed();
   DCHECK(View());
   DCHECK(View()->GetFrameView());
   if (DocumentBeingDestroyed())
@@ -143,12 +147,14 @@
 }
 
 void LayoutImage::UpdateIntrinsicSizeIfNeeded(const LayoutSize& new_size) {
+  CheckIsNotDestroyed();
   if (image_resource_->ErrorOccurred())
     return;
   SetIntrinsicSize(new_size);
 }
 
 bool LayoutImage::NeedsLayoutOnIntrinsicSizeChange() const {
+  CheckIsNotDestroyed();
   // If the actual area occupied by the image has changed and it is not
   // constrained by style then a layout is required.
   bool image_size_is_constrained =
@@ -171,6 +177,7 @@
 
 void LayoutImage::InvalidatePaintAndMarkForLayoutIfNeeded(
     CanDeferInvalidation defer) {
+  CheckIsNotDestroyed();
   LayoutSize old_intrinsic_size = IntrinsicSize();
 
   LayoutSize new_intrinsic_size = RoundedLayoutSize(
@@ -206,6 +213,7 @@
 }
 
 void LayoutImage::ImageNotifyFinished(ImageResourceContent* new_image) {
+  CheckIsNotDestroyed();
   LayoutObject::ImageNotifyFinished(new_image);
   if (!image_resource_)
     return;
@@ -222,16 +230,19 @@
 
 void LayoutImage::PaintReplaced(const PaintInfo& paint_info,
                                 const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   if (ChildPaintBlockedByDisplayLock())
     return;
   ImagePainter(*this).PaintReplaced(paint_info, paint_offset);
 }
 
 void LayoutImage::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   ImagePainter(*this).Paint(paint_info);
 }
 
 void LayoutImage::AreaElementFocusChanged(HTMLAreaElement* area_element) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(area_element->ImageElement(), GetNode());
 
   if (area_element->GetPath(this).IsEmpty())
@@ -243,6 +254,7 @@
 bool LayoutImage::ForegroundIsKnownToBeOpaqueInRect(
     const PhysicalRect& local_rect,
     unsigned) const {
+  CheckIsNotDestroyed();
   if (!image_resource_->HasImage() || image_resource_->ErrorOccurred())
     return false;
   ImageResourceContent* image_content = image_resource_->CachedImage();
@@ -276,6 +288,7 @@
 }
 
 bool LayoutImage::ComputeBackgroundIsKnownToBeObscured() const {
+  CheckIsNotDestroyed();
   if (!StyleRef().HasBackground())
     return false;
 
@@ -286,11 +299,13 @@
 }
 
 LayoutUnit LayoutImage::MinimumReplacedHeight() const {
+  CheckIsNotDestroyed();
   return image_resource_->ErrorOccurred() ? IntrinsicSize().Height()
                                           : LayoutUnit();
 }
 
 HTMLMapElement* LayoutImage::ImageMap() const {
+  CheckIsNotDestroyed();
   auto* i = DynamicTo<HTMLImageElement>(GetNode());
   return i ? i->GetTreeScope().GetImageMap(
                  i->FastGetAttribute(html_names::kUsemapAttr))
@@ -301,6 +316,7 @@
                               const HitTestLocation& hit_test_location,
                               const PhysicalOffset& accumulated_offset,
                               HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   HitTestResult temp_result(result);
   bool inside = LayoutReplaced::NodeAtPoint(
       temp_result, hit_test_location, accumulated_offset, hit_test_action);
@@ -313,6 +329,7 @@
 }
 
 bool LayoutImage::HasOverriddenIntrinsicSize() const {
+  CheckIsNotDestroyed();
   if (!RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled())
     return false;
   auto* image_element = DynamicTo<HTMLImageElement>(GetNode());
@@ -321,6 +338,7 @@
 
 FloatSize LayoutImage::ImageSizeOverriddenByIntrinsicSize(
     float multiplier) const {
+  CheckIsNotDestroyed();
   if (!HasOverriddenIntrinsicSize())
     return image_resource_->ImageSize(multiplier);
 
@@ -338,6 +356,7 @@
 
 bool LayoutImage::OverrideIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  CheckIsNotDestroyed();
   if (!HasOverriddenIntrinsicSize())
     return false;
 
@@ -352,6 +371,7 @@
 
 void LayoutImage::ComputeIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  CheckIsNotDestroyed();
   DCHECK(!ShouldApplySizeContainment());
   if (!OverrideIntrinsicSizingInfo(intrinsic_sizing_info)) {
     if (SVGImage* svg_image = EmbeddedSVGImage()) {
@@ -413,6 +433,7 @@
 }
 
 bool LayoutImage::NeedsPreferredWidthsRecalculation() const {
+  CheckIsNotDestroyed();
   if (LayoutReplaced::NeedsPreferredWidthsRecalculation())
     return true;
   SVGImage* svg_image = EmbeddedSVGImage();
@@ -420,6 +441,7 @@
 }
 
 SVGImage* LayoutImage::EmbeddedSVGImage() const {
+  CheckIsNotDestroyed();
   if (!image_resource_)
     return nullptr;
   ImageResourceContent* cached_image = image_resource_->CachedImage();
@@ -431,6 +453,7 @@
 }
 
 void LayoutImage::UpdateAfterLayout() {
+  CheckIsNotDestroyed();
   LayoutBox::UpdateAfterLayout();
   Node* node = GetNode();
   if (auto* image_element = DynamicTo<HTMLImageElement>(node)) {
diff --git a/third_party/blink/renderer/core/layout/layout_image.h b/third_party/blink/renderer/core/layout/layout_image.h
index 3ed38c1..f25f39a 100644
--- a/third_party/blink/renderer/core/layout/layout_image.h
+++ b/third_party/blink/renderer/core/layout/layout_image.h
@@ -55,11 +55,16 @@
 
   void SetImageResource(LayoutImageResource*);
 
-  LayoutImageResource* ImageResource() { return image_resource_.Get(); }
+  LayoutImageResource* ImageResource() {
+    CheckIsNotDestroyed();
+    return image_resource_.Get();
+  }
   const LayoutImageResource* ImageResource() const {
+    CheckIsNotDestroyed();
     return image_resource_.Get();
   }
   ImageResourceContent* CachedImage() const {
+    CheckIsNotDestroyed();
     return image_resource_ ? image_resource_->CachedImage() : nullptr;
   }
 
@@ -67,17 +72,26 @@
   void AreaElementFocusChanged(HTMLAreaElement*);
 
   void SetIsGeneratedContent(bool generated = true) {
+    CheckIsNotDestroyed();
     is_generated_content_ = generated;
   }
 
-  bool IsGeneratedContent() const { return is_generated_content_; }
+  bool IsGeneratedContent() const {
+    CheckIsNotDestroyed();
+    return is_generated_content_;
+  }
 
   inline void SetImageDevicePixelRatio(float factor) {
+    CheckIsNotDestroyed();
     image_device_pixel_ratio_ = factor;
   }
-  float ImageDevicePixelRatio() const { return image_device_pixel_ratio_; }
+  float ImageDevicePixelRatio() const {
+    CheckIsNotDestroyed();
+    return image_device_pixel_ratio_;
+  }
 
   void IntrinsicSizeChanged() override {
+    CheckIsNotDestroyed();
     // The replaced content transform depends on the intrinsic size (see:
     // FragmentPaintPropertyTreeBuilder::UpdateReplacedContentTransform).
     SetNeedsPaintPropertyUpdate();
@@ -85,7 +99,10 @@
       ImageChanged(image_resource_->ImagePtr(), CanDeferInvalidation::kNo);
   }
 
-  const char* GetName() const override { return "LayoutImage"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutImage";
+  }
 
   void UpdateAfterLayout() override;
 
@@ -99,6 +116,7 @@
   void Paint(const PaintInfo&) const final;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectLayoutImage || LayoutReplaced::IsOfType(type);
   }
 
@@ -106,10 +124,16 @@
 
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
 
-  bool CanBeSelectionLeafInternal() const final { return true; }
+  bool CanBeSelectionLeafInternal() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
  private:
-  bool IsImage() const override { return true; }
+  bool IsImage() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   void PaintReplaced(const PaintInfo&,
                      const PhysicalOffset& paint_offset) const override;
@@ -119,7 +143,10 @@
       unsigned max_depth_to_test) const final;
   bool ComputeBackgroundIsKnownToBeObscured() const final;
 
-  bool BackgroundShouldAlwaysBeClipped() const override { return true; }
+  bool BackgroundShouldAlwaysBeClipped() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   LayoutUnit MinimumReplacedHeight() const override;
 
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc
index e81f0475..2f49349 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.cc
+++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -108,6 +108,7 @@
 }
 
 void LayoutInline::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   // Make sure to destroy anonymous children first while they are still
   // connected to the rest of the tree, so that they will properly dirty line
   // boxes that they are removed from. Effects that do :before/:after only on
@@ -154,23 +155,27 @@
 }
 
 void LayoutInline::DeleteLineBoxes() {
+  CheckIsNotDestroyed();
   if (!IsInLayoutNGInlineFormattingContext())
     MutableLineBoxes()->DeleteLineBoxes();
 }
 
 void LayoutInline::SetFirstInlineFragment(NGPaintFragment* fragment) {
+  CheckIsNotDestroyed();
   CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
   DCHECK(!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
   first_paint_fragment_ = fragment;
 }
 
 void LayoutInline::ClearFirstInlineFragmentItemIndex() {
+  CheckIsNotDestroyed();
   CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
   DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
   first_fragment_item_index_ = 0u;
 }
 
 void LayoutInline::SetFirstInlineFragmentItemIndex(wtf_size_t index) {
+  CheckIsNotDestroyed();
   CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
   DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
   DCHECK_NE(index, 0u);
@@ -178,6 +183,7 @@
 }
 
 bool LayoutInline::HasInlineFragments() const {
+  CheckIsNotDestroyed();
   if (!IsInLayoutNGInlineFormattingContext())
     return FirstLineBox();
   if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
@@ -186,6 +192,7 @@
 }
 
 void LayoutInline::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
       SetFirstInlineFragment(nullptr);
@@ -205,6 +212,7 @@
 }
 
 LayoutInline* LayoutInline::InlineElementContinuation() const {
+  CheckIsNotDestroyed();
   LayoutBoxModelObject* continuation = Continuation();
   if (!continuation || continuation->IsInline())
     return ToLayoutInline(continuation);
@@ -212,6 +220,7 @@
 }
 
 void LayoutInline::UpdateFromStyle() {
+  CheckIsNotDestroyed();
   LayoutBoxModelObject::UpdateFromStyle();
 
   // FIXME: Is this still needed. Was needed for run-ins, since run-in is
@@ -260,6 +269,7 @@
 
 void LayoutInline::StyleDidChange(StyleDifference diff,
                                   const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutBoxModelObject::StyleDidChange(diff, old_style);
 
   // Ensure that all of the split inlines pick up the new style. We only do this
@@ -363,6 +373,7 @@
 }
 
 void LayoutInline::UpdateAlwaysCreateLineBoxes(bool full_layout) {
+  CheckIsNotDestroyed();
   DCHECK(!IsInLayoutNGInlineFormattingContext());
 
   // Once we have been tainted once, just assume it will happen again. This way
@@ -406,6 +417,7 @@
 
 bool LayoutInline::ComputeInitialShouldCreateBoxFragment(
     const ComputedStyle& style) const {
+  CheckIsNotDestroyed();
   if (style.HasBoxDecorationBackground() || style.MayHavePadding() ||
       style.MayHaveMargin())
     return true;
@@ -416,6 +428,7 @@
 }
 
 bool LayoutInline::ComputeInitialShouldCreateBoxFragment() const {
+  CheckIsNotDestroyed();
   const ComputedStyle& style = StyleRef();
   if (HasSelfPaintingLayer() || ComputeInitialShouldCreateBoxFragment(style) ||
       ShouldApplyPaintContainment() || ShouldApplyLayoutContainment())
@@ -430,6 +443,7 @@
 }
 
 void LayoutInline::UpdateShouldCreateBoxFragment() {
+  CheckIsNotDestroyed();
   // Once we have been tainted once, just assume it will happen again. This way
   // effects like hover highlighting that change the background color will only
   // cause a layout on the first rollover.
@@ -452,6 +466,7 @@
     const InlineBox* inline_box,
     int,
     LayoutUnit* extra_width_to_end_of_line) const {
+  CheckIsNotDestroyed();
   if (FirstChild()) {
     // This condition is possible if the LayoutInline is at an editing boundary,
     // i.e. the VisiblePosition is:
@@ -486,6 +501,7 @@
 
 void LayoutInline::AddChild(LayoutObject* new_child,
                             LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   // Any table-part dom child of an inline element has anonymous wrappers in the
   // layout tree so we need to climb up to the enclosing anonymous table wrapper
   // and add the new child before that.
@@ -506,6 +522,7 @@
 
 LayoutBoxModelObject* LayoutInline::ContinuationBefore(
     LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   if (before_child && before_child->Parent() == this)
     return this;
 
@@ -531,6 +548,7 @@
 
 void LayoutInline::AddChildIgnoringContinuation(LayoutObject* new_child,
                                                 LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   // Make sure we don't append things after :after-generated content if we have
   // it.
   if (!before_child && IsAfterContent(LastChild()))
@@ -553,6 +571,7 @@
 }
 
 LayoutInline* LayoutInline::Clone() const {
+  CheckIsNotDestroyed();
   DCHECK(!IsAnonymous());
   LayoutInline* clone_inline = new LayoutInline(GetNode());
   clone_inline->SetStyle(Style());
@@ -563,6 +582,7 @@
 void LayoutInline::MoveChildrenToIgnoringContinuation(
     LayoutInline* to,
     LayoutObject* start_child) {
+  CheckIsNotDestroyed();
   DCHECK(!IsAnonymous());
   DCHECK(!to->IsAnonymous());
   LayoutObject* child = start_child;
@@ -579,6 +599,7 @@
                                 LayoutBlockFlow* middle_block,
                                 LayoutObject* before_child,
                                 LayoutBoxModelObject* old_cont) {
+  CheckIsNotDestroyed();
   DCHECK(IsDescendantOf(from_block));
   DCHECK(!IsAnonymous());
 
@@ -661,6 +682,7 @@
                              LayoutBlockFlow* new_block_box,
                              LayoutObject* new_child,
                              LayoutBoxModelObject* old_cont) {
+  CheckIsNotDestroyed();
   auto* block = To<LayoutBlockFlow>(ContainingBlock());
   LayoutBlockFlow* pre = nullptr;
 
@@ -730,6 +752,7 @@
 }
 
 LayoutBlockFlow* LayoutInline::CreateAnonymousContainerForBlockChildren() {
+  CheckIsNotDestroyed();
   // We are placing a block inside an inline. We have to perform a split of this
   // inline into continuations. This involves creating an anonymous block box to
   // hold |newChild|. We then make that block box a continuation of this
@@ -766,6 +789,7 @@
 
 void LayoutInline::AddChildToContinuation(LayoutObject* new_child,
                                           LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   // A continuation always consists of two potential candidates: an inline or an
   // anonymous block box holding block children.
   LayoutBoxModelObject* flow = ContinuationBefore(before_child);
@@ -810,12 +834,14 @@
 }
 
 void LayoutInline::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   InlinePainter(*this).Paint(paint_info);
 }
 
 template <typename PhysicalRectCollector>
 void LayoutInline::CollectLineBoxRects(
     const PhysicalRectCollector& yield) const {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     const auto* box_fragment = ContainingBlockFlowFragmentOf(*this);
     if (!box_fragment)
@@ -847,6 +873,7 @@
 template <typename PhysicalRectCollector>
 void LayoutInline::CollectCulledLineBoxRects(
     const PhysicalRectCollector& yield) const {
+  CheckIsNotDestroyed();
   DCHECK(!IsInLayoutNGInlineFormattingContext());
   const LayoutBlock* block_for_flipping =
       UNLIKELY(HasFlippedBlocksWritingMode()) ? ContainingBlock() : nullptr;
@@ -885,6 +912,7 @@
 void LayoutInline::CollectCulledLineBoxRectsInFlippedBlocksDirection(
     const FlippedRectCollector& yield,
     const LayoutInline* container) const {
+  CheckIsNotDestroyed();
   if (!CulledInlineFirstLineBox())
     return;
 
@@ -961,6 +989,7 @@
 
 void LayoutInline::AbsoluteQuadsForSelf(Vector<FloatQuad>& quads,
                                         MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   LayoutGeometryMap geometry_map(mode);
   geometry_map.PushMappingsToAncestor(this, nullptr);
   CollectLineBoxRects([&quads, &geometry_map](const PhysicalRect& r) {
@@ -972,6 +1001,7 @@
 
 base::Optional<PhysicalOffset> LayoutInline::FirstLineBoxTopLeftInternal()
     const {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     NGInlineCursor cursor;
     cursor.MoveToIncludingCulledInline(*this);
@@ -991,6 +1021,7 @@
 }
 
 PhysicalOffset LayoutInline::AnchorPhysicalLocation() const {
+  CheckIsNotDestroyed();
   if (const auto& location = FirstLineBoxTopLeftInternal())
     return *location;
   // This object doesn't have fragment/line box, probably because it's an empty
@@ -1013,6 +1044,7 @@
 }
 
 PhysicalRect LayoutInline::AbsoluteBoundingBoxRectHandlingEmptyInline() const {
+  CheckIsNotDestroyed();
   Vector<PhysicalRect> rects = OutlineRects(
       PhysicalOffset(), NGOutlineType::kIncludeBlockVisualOverflow);
   PhysicalRect rect = UnionRect(rects);
@@ -1023,10 +1055,12 @@
 }
 
 LayoutUnit LayoutInline::OffsetLeft(const Element* parent) const {
+  CheckIsNotDestroyed();
   return AdjustedPositionRelativeTo(FirstLineBoxTopLeft(), parent).left;
 }
 
 LayoutUnit LayoutInline::OffsetTop(const Element* parent) const {
+  CheckIsNotDestroyed();
   return AdjustedPositionRelativeTo(FirstLineBoxTopLeft(), parent).top;
 }
 
@@ -1043,18 +1077,22 @@
 }
 
 LayoutUnit LayoutInline::MarginLeft() const {
+  CheckIsNotDestroyed();
   return ComputeMargin(this, StyleRef().MarginLeft());
 }
 
 LayoutUnit LayoutInline::MarginRight() const {
+  CheckIsNotDestroyed();
   return ComputeMargin(this, StyleRef().MarginRight());
 }
 
 LayoutUnit LayoutInline::MarginTop() const {
+  CheckIsNotDestroyed();
   return ComputeMargin(this, StyleRef().MarginTop());
 }
 
 LayoutUnit LayoutInline::MarginBottom() const {
+  CheckIsNotDestroyed();
   return ComputeMargin(this, StyleRef().MarginBottom());
 }
 
@@ -1062,6 +1100,7 @@
                                const HitTestLocation& hit_test_location,
                                const PhysicalOffset& accumulated_offset,
                                HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   if (ContainingNGBlockFlow()) {
     // TODO(crbug.com/965976): We should fix the root cause of the missed
     // layout.
@@ -1113,6 +1152,7 @@
                                        const HitTestLocation& hit_test_location,
                                        const PhysicalOffset& accumulated_offset,
                                        const NGInlineCursor* parent_cursor) {
+  CheckIsNotDestroyed();
   DCHECK(parent_cursor || !AlwaysCreateLineBoxes());
   if (!VisibleToHitTestRequest(result.GetHitTestRequest()))
     return false;
@@ -1155,6 +1195,7 @@
 
 PositionWithAffinity LayoutInline::PositionForPoint(
     const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   // FIXME: Does not deal with relative positioned inlines (should it?)
 
   // If there are continuations, test them first because our containing block
@@ -1185,6 +1226,7 @@
 }
 
 PhysicalRect LayoutInline::PhysicalLinesBoundingBox() const {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     NGInlineCursor cursor;
     cursor.MoveToIncludingCulledInline(*this);
@@ -1239,6 +1281,7 @@
 }
 
 InlineBox* LayoutInline::CulledInlineFirstLineBox() const {
+  CheckIsNotDestroyed();
   for (LayoutObject* curr = FirstChild(); curr; curr = curr->NextSibling()) {
     if (curr->IsFloatingOrOutOfFlowPositioned())
       continue;
@@ -1263,6 +1306,7 @@
 }
 
 InlineBox* LayoutInline::CulledInlineLastLineBox() const {
+  CheckIsNotDestroyed();
   for (LayoutObject* curr = LastChild(); curr; curr = curr->PreviousSibling()) {
     if (curr->IsFloatingOrOutOfFlowPositioned())
       continue;
@@ -1287,6 +1331,7 @@
 }
 
 PhysicalRect LayoutInline::CulledInlineVisualOverflowBoundingBox() const {
+  CheckIsNotDestroyed();
   PhysicalRect result;
   CollectCulledLineBoxRects(
       [&result](const PhysicalRect& r) { result.UniteIfNonZero(r); });
@@ -1333,6 +1378,7 @@
 }
 
 PhysicalRect LayoutInline::LinesVisualOverflowBoundingBox() const {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     PhysicalRect result;
     NGInlineCursor cursor;
@@ -1379,6 +1425,7 @@
 }
 
 PhysicalRect LayoutInline::VisualRectInDocument(VisualRectFlags flags) const {
+  CheckIsNotDestroyed();
   PhysicalRect rect;
   if (!Continuation()) {
     rect = PhysicalVisualOverflowRect();
@@ -1392,6 +1439,7 @@
 }
 
 PhysicalRect LayoutInline::LocalVisualRectIgnoringVisibility() const {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     DCHECK(RuntimeEnabledFeatures::LayoutNGEnabled());
     if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
@@ -1411,6 +1459,7 @@
 }
 
 PhysicalRect LayoutInline::PhysicalVisualOverflowRect() const {
+  CheckIsNotDestroyed();
   PhysicalRect overflow_rect = LinesVisualOverflowBoundingBox();
   LayoutUnit outline_outset(StyleRef().OutlineOutsetExtent());
   if (outline_outset) {
@@ -1441,6 +1490,7 @@
 }
 
 PhysicalRect LayoutInline::ReferenceBoxForClipPath() const {
+  CheckIsNotDestroyed();
   // The spec just says to use the border box as clip-path reference box. It
   // doesn't say what to do if there are multiple lines. Gecko uses the first
   // fragment in that case. We'll do the same here (but correctly with respect
@@ -1461,6 +1511,7 @@
     const LayoutBoxModelObject* ancestor,
     TransformState& transform_state,
     VisualRectFlags visual_rect_flags) const {
+  CheckIsNotDestroyed();
   if (ancestor == this)
     return true;
 
@@ -1499,6 +1550,7 @@
 PhysicalOffset LayoutInline::OffsetFromContainerInternal(
     const LayoutObject* container,
     bool ignore_scroll_offset) const {
+  CheckIsNotDestroyed();
   DCHECK_EQ(container, Container());
 
   PhysicalOffset offset;
@@ -1512,6 +1564,7 @@
 }
 
 PaintLayerType LayoutInline::LayerTypeRequired() const {
+  CheckIsNotDestroyed();
   return IsInFlowPositioned() || CreatesGroup() ||
                  StyleRef().ShouldCompositeForCurrentAnimations() ||
                  ShouldApplyPaintContainment()
@@ -1520,6 +1573,7 @@
 }
 
 void LayoutInline::ChildBecameNonInline(LayoutObject* child) {
+  CheckIsNotDestroyed();
   // We have to split the parent flow.
   LayoutBlockFlow* new_box = CreateAnonymousContainerForBlockChildren();
   LayoutBoxModelObject* old_continuation = Continuation();
@@ -1531,6 +1585,7 @@
 
 void LayoutInline::UpdateHitTestResult(HitTestResult& result,
                                        const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   if (result.InnerNode())
     return;
 
@@ -1554,6 +1609,7 @@
 }
 
 void LayoutInline::DirtyLineBoxes(bool full_layout) {
+  CheckIsNotDestroyed();
   if (full_layout) {
     DeleteLineBoxes();
     return;
@@ -1587,10 +1643,12 @@
 }
 
 InlineFlowBox* LayoutInline::CreateInlineFlowBox() {
+  CheckIsNotDestroyed();
   return new InlineFlowBox(LineLayoutItem(this));
 }
 
 InlineFlowBox* LayoutInline::CreateAndAppendInlineFlowBox() {
+  CheckIsNotDestroyed();
   SetAlwaysCreateLineBoxes();
   InlineFlowBox* flow_box = CreateInlineFlowBox();
   MutableLineBoxes()->AppendLineBox(flow_box);
@@ -1600,6 +1658,7 @@
 void LayoutInline::DirtyLinesFromChangedChild(
     LayoutObject* child,
     MarkingBehavior marking_behavior) {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     if (UNLIKELY(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())) {
       if (const LayoutBlockFlow* container = FragmentItemsContainer()) {
@@ -1634,6 +1693,7 @@
     bool first_line,
     LineDirectionMode direction,
     LinePositionMode line_position_mode) const {
+  CheckIsNotDestroyed();
   DCHECK_EQ(line_position_mode, kPositionOnContainingLine);
   const SimpleFontData* font_data = Style(first_line)->GetFont().PrimaryFont();
   DCHECK(font_data);
@@ -1649,6 +1709,7 @@
 
 PhysicalOffset LayoutInline::OffsetForInFlowPositionedInline(
     const LayoutBox& child) const {
+  CheckIsNotDestroyed();
   // TODO(layout-dev): This function isn't right with mixed writing modes,
   // but LayoutNG has fixed the issue. This function seems to always return
   // zero in LayoutNG. We should probably remove this function for LayoutNG.
@@ -1695,6 +1756,7 @@
 }
 
 void LayoutInline::ImageChanged(WrappedImagePtr, CanDeferInvalidation) {
+  CheckIsNotDestroyed();
   if (!Parent())
     return;
 
@@ -1706,6 +1768,7 @@
     Vector<PhysicalRect>& rects,
     const PhysicalOffset& additional_offset,
     NGOutlineType include_block_overflows) const {
+  CheckIsNotDestroyed();
 #if DCHECK_IS_ON()
   // TODO(crbug.com/987836): enable this DCHECK universally.
   Page* page = GetDocument().GetPage();
@@ -1728,6 +1791,7 @@
     Vector<PhysicalRect>& rects,
     const PhysicalOffset& additional_offset,
     NGOutlineType include_block_overflows) const {
+  CheckIsNotDestroyed();
   AddOutlineRectsForNormalChildren(rects, additional_offset,
                                    include_block_overflows);
   AddOutlineRectsForContinuations(rects, additional_offset,
@@ -1738,6 +1802,7 @@
     Vector<PhysicalRect>& rects,
     const PhysicalOffset& additional_offset,
     NGOutlineType include_block_overflows) const {
+  CheckIsNotDestroyed();
   if (LayoutBoxModelObject* continuation = Continuation()) {
     if (continuation->NeedsLayout()) {
       // TODO(mstensho): Prevent this from happening. Before we can get the
@@ -1761,12 +1826,14 @@
 }
 
 FloatRect LayoutInline::LocalBoundingBoxRectForAccessibility() const {
+  CheckIsNotDestroyed();
   Vector<PhysicalRect> rects = OutlineRects(
       PhysicalOffset(), NGOutlineType::kIncludeBlockVisualOverflow);
   return FloatRect(FlipForWritingMode(UnionRect(rects).ToLayoutRect()));
 }
 
 void LayoutInline::AddAnnotatedRegions(Vector<AnnotatedRegionValue>& regions) {
+  CheckIsNotDestroyed();
   // Convert the style regions to absolute coordinates.
   if (StyleRef().Visibility() != EVisibility::kVisible)
     return;
@@ -1793,6 +1860,7 @@
 
 void LayoutInline::InvalidateDisplayItemClients(
     PaintInvalidationReason invalidation_reason) const {
+  CheckIsNotDestroyed();
   ObjectPaintInvalidator paint_invalidator(*this);
 
   if (IsInLayoutNGInlineFormattingContext()) {
@@ -1826,12 +1894,14 @@
 void LayoutInline::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                                       TransformState& transform_state,
                                       MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   if (CanContainFixedPositionObjects())
     mode &= ~kIsFixed;
   LayoutBoxModelObject::MapLocalToAncestor(ancestor, transform_state, mode);
 }
 
 PhysicalRect LayoutInline::DebugRect() const {
+  CheckIsNotDestroyed();
   return PhysicalRect(EnclosingIntRect(PhysicalLinesBoundingBox()));
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_inline.h b/third_party/blink/renderer/core/layout/layout_inline.h
index 4e1ae54..8dbf225 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.h
+++ b/third_party/blink/renderer/core/layout/layout_inline.h
@@ -122,10 +122,12 @@
   static LayoutInline* CreateAnonymous(Document*);
 
   LayoutObject* FirstChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->FirstChild();
   }
   LayoutObject* LastChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->LastChild();
   }
@@ -138,6 +140,7 @@
                 LayoutObject* before_child = nullptr) override;
 
   Element* GetNode() const {
+    CheckIsNotDestroyed();
     return To<Element>(LayoutBoxModelObject::GetNode());
   }
 
@@ -159,18 +162,27 @@
   // LineBoxes() and FirstInlineFragment() are mutually exclusive,
   // depends on IsInLayoutNGInlineFormattingContext().
   const LineBoxList* LineBoxes() const {
+    CheckIsNotDestroyed();
     return IsInLayoutNGInlineFormattingContext() ? &LineBoxList::Empty()
                                                  : &line_boxes_;
   }
   LineBoxList* MutableLineBoxes();
 
-  InlineFlowBox* FirstLineBox() const { return LineBoxes()->First(); }
-  InlineFlowBox* LastLineBox() const { return LineBoxes()->Last(); }
+  InlineFlowBox* FirstLineBox() const {
+    CheckIsNotDestroyed();
+    return LineBoxes()->First();
+  }
+  InlineFlowBox* LastLineBox() const {
+    CheckIsNotDestroyed();
+    return LineBoxes()->Last();
+  }
   InlineBox* FirstLineBoxIncludingCulling() const {
+    CheckIsNotDestroyed();
     return AlwaysCreateLineBoxes() ? FirstLineBox()
                                    : CulledInlineFirstLineBox();
   }
   InlineBox* LastLineBoxIncludingCulling() const {
+    CheckIsNotDestroyed();
     return AlwaysCreateLineBoxes() ? LastLineBox() : CulledInlineLastLineBox();
   }
 
@@ -182,6 +194,7 @@
   void SetFirstInlineFragmentItemIndex(wtf_size_t) final;
 
   LayoutBoxModelObject* VirtualContinuation() const final {
+    CheckIsNotDestroyed();
     return Continuation();
   }
   LayoutInline* InlineElementContinuation() const;
@@ -205,10 +218,12 @@
   using LayoutBoxModelObject::SetContinuation;
 
   bool AlwaysCreateLineBoxes() const {
+    CheckIsNotDestroyed();
     return AlwaysCreateLineBoxesForLayoutInline() &&
            !IsInLayoutNGInlineFormattingContext();
   }
   void SetAlwaysCreateLineBoxes(bool always_create_line_boxes = true) {
+    CheckIsNotDestroyed();
     DCHECK(!IsInLayoutNGInlineFormattingContext());
     SetAlwaysCreateLineBoxesForLayoutInline(always_create_line_boxes);
   }
@@ -216,10 +231,12 @@
 
   // True if this inline box should force creation of NGPhysicalBoxFragment.
   bool ShouldCreateBoxFragment() const {
+    CheckIsNotDestroyed();
     return AlwaysCreateLineBoxesForLayoutInline() &&
            IsInLayoutNGInlineFormattingContext();
   }
   void SetShouldCreateBoxFragment(bool value = true) {
+    CheckIsNotDestroyed();
     DCHECK(IsInLayoutNGInlineFormattingContext());
     SetAlwaysCreateLineBoxesForLayoutInline(value);
   }
@@ -240,6 +257,7 @@
                            const NGInlineCursor* parent_cursor = nullptr);
 
   PhysicalOffset FirstLineBoxTopLeft() const {
+    CheckIsNotDestroyed();
     return FirstLineBoxTopLeftInternal().value_or(PhysicalOffset());
   }
 
@@ -252,7 +270,10 @@
   PhysicalRect VisualRectInDocument(
       VisualRectFlags = kDefaultVisualRectFlags) const override;
 
-  const char* GetName() const override { return "LayoutInline"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutInline";
+  }
 
   PhysicalRect DebugRect() const override;
 
@@ -275,14 +296,27 @@
       bool ignore_scroll_offset) const final;
 
  private:
-  LayoutObjectChildList* VirtualChildren() final { return Children(); }
-  const LayoutObjectChildList* VirtualChildren() const final {
+  LayoutObjectChildList* VirtualChildren() final {
+    CheckIsNotDestroyed();
     return Children();
   }
-  const LayoutObjectChildList* Children() const { return &children_; }
-  LayoutObjectChildList* Children() { return &children_; }
+  const LayoutObjectChildList* VirtualChildren() const final {
+    CheckIsNotDestroyed();
+    return Children();
+  }
+  const LayoutObjectChildList* Children() const {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
+  LayoutObjectChildList* Children() {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
 
-  bool IsLayoutInline() const final { return true; }
+  bool IsLayoutInline() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   // Compute the initial value of |ShouldCreateBoxFragment()| for this
   // LayoutInline. It maybe flipped to true later for other conditions.
@@ -332,7 +366,10 @@
   // Create an anoymous block for block children of this inline.
   LayoutBlockFlow* CreateAnonymousContainerForBlockChildren();
 
-  void UpdateLayout() final { NOTREACHED(); }  // Do nothing for layout()
+  void UpdateLayout() final {
+    CheckIsNotDestroyed();
+    NOTREACHED();
+  }  // Do nothing for layout()
 
   void Paint(const PaintInfo&) const final;
 
@@ -346,9 +383,11 @@
   LayoutUnit OffsetLeft(const Element*) const final;
   LayoutUnit OffsetTop(const Element*) const final;
   LayoutUnit OffsetWidth() const final {
+    CheckIsNotDestroyed();
     return PhysicalLinesBoundingBox().Width();
   }
   LayoutUnit OffsetHeight() const final {
+    CheckIsNotDestroyed();
     return PhysicalLinesBoundingBox().Height();
   }
 
@@ -366,6 +405,7 @@
   PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
 
   IntRect BorderBoundingBox() const final {
+    CheckIsNotDestroyed();
     IntRect bounding_box = EnclosingIntRect(PhysicalLinesBoundingBox());
     return IntRect(0, 0, bounding_box.Width(), bounding_box.Height());
   }
@@ -395,7 +435,10 @@
   void AddAnnotatedRegions(Vector<AnnotatedRegionValue>&) final;
 
   void UpdateFromStyle() final;
-  bool AnonymousHasStylePropagationOverride() final { return true; }
+  bool AnonymousHasStylePropagationOverride() final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   LayoutInline* Clone() const;
 
diff --git a/third_party/blink/renderer/core/layout/layout_inside_list_marker.h b/third_party/blink/renderer/core/layout/layout_inside_list_marker.h
index b5a8d26..ace9092 100644
--- a/third_party/blink/renderer/core/layout/layout_inside_list_marker.h
+++ b/third_party/blink/renderer/core/layout/layout_inside_list_marker.h
@@ -18,13 +18,23 @@
   explicit LayoutInsideListMarker(Element*);
   ~LayoutInsideListMarker() override;
 
-  const char* GetName() const override { return "LayoutInsideListMarker"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutInsideListMarker";
+  }
 
-  const ListMarker& Marker() const { return list_marker_; }
-  ListMarker& Marker() { return list_marker_; }
+  const ListMarker& Marker() const {
+    CheckIsNotDestroyed();
+    return list_marker_;
+  }
+  ListMarker& Marker() {
+    CheckIsNotDestroyed();
+    return list_marker_;
+  }
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectInsideListMarker ||
            LayoutInline::IsOfType(type);
   }
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 9f7e7ae..9638fee 100644
--- a/third_party/blink/renderer/core/layout/layout_list_item.cc
+++ b/third_party/blink/renderer/core/layout/layout_list_item.cc
@@ -47,6 +47,7 @@
 
 void LayoutListItem::StyleDidChange(StyleDifference diff,
                                     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::StyleDidChange(diff, old_style);
 
   StyleImage* current_image = StyleRef().ListStyleImage();
@@ -80,18 +81,21 @@
 }
 
 void LayoutListItem::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::InsertedIntoTree();
 
   ListItemOrdinal::ItemInsertedOrRemoved(this);
 }
 
 void LayoutListItem::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::WillBeRemovedFromTree();
 
   ListItemOrdinal::ItemInsertedOrRemoved(this);
 }
 
 void LayoutListItem::SubtreeDidChange() {
+  CheckIsNotDestroyed();
   LayoutObject* marker = Marker();
   if (!marker)
     return;
@@ -113,15 +117,18 @@
 }
 
 int LayoutListItem::Value() const {
+  CheckIsNotDestroyed();
   DCHECK(GetNode());
   return ordinal_.Value(*GetNode());
 }
 
 bool LayoutListItem::IsEmpty() const {
+  CheckIsNotDestroyed();
   return LastChild() == Marker();
 }
 
 void LayoutListItem::UpdateMarkerTextIfNeeded() {
+  CheckIsNotDestroyed();
   LayoutObject* marker = Marker();
   if (ListMarker* list_marker = ListMarker::Get(marker))
     list_marker->UpdateMarkerTextIfNeeded(*marker);
@@ -201,6 +208,7 @@
 // marker_container to 0px; else restore it to LogicalHeight of <li>.
 bool LayoutListItem::PrepareForBlockDirectionAlign(
     const LayoutObject* line_box_parent) {
+  CheckIsNotDestroyed();
   LayoutObject* marker = Marker();
   LayoutObject* marker_parent = marker->Parent();
   bool is_inside = marker->IsInsideListMarker();
@@ -264,6 +272,7 @@
 }
 
 bool LayoutListItem::UpdateMarkerLocation() {
+  CheckIsNotDestroyed();
   DCHECK(Marker());
 
   LayoutObject* marker = Marker();
@@ -327,11 +336,13 @@
 }
 
 void LayoutListItem::RecalcVisualOverflow() {
+  CheckIsNotDestroyed();
   RecalcChildVisualOverflow();
   RecalcSelfVisualOverflow();
 }
 
 void LayoutListItem::ComputeVisualOverflow(bool recompute_floats) {
+  CheckIsNotDestroyed();
   LayoutRect previous_visual_overflow_rect = VisualOverflowRect();
   ClearVisualOverflow();
 
@@ -350,6 +361,7 @@
 }
 
 void LayoutListItem::AddLayoutOverflowFromChildren() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::AddLayoutOverflowFromChildren();
   UpdateOverflow();
 }
@@ -357,6 +369,7 @@
 // Align marker_inline_box in block direction according to line_box_root's
 // baseline.
 void LayoutListItem::AlignMarkerInBlockDirection() {
+  CheckIsNotDestroyed();
   // Specify wether need to restore to the original baseline which is the
   // baseline of marker parent. Because we might adjust the position at the last
   // layout pass. So if there's no line box in line_box_parent make sure it
@@ -433,6 +446,7 @@
 }
 
 void LayoutListItem::UpdateOverflow() {
+  CheckIsNotDestroyed();
   LayoutObject* marker_object = Marker();
   if (!marker_object || !marker_object->Parent() ||
       !marker_object->Parent()->IsBox() || marker_object->IsInsideListMarker())
@@ -597,10 +611,12 @@
 }
 
 void LayoutListItem::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   ListItemPainter(*this).Paint(paint_info);
 }
 
 void LayoutListItem::OrdinalValueChanged() {
+  CheckIsNotDestroyed();
   LayoutObject* marker = Marker();
   if (ListMarker* list_marker = ListMarker::Get(marker)) {
     list_marker->OrdinalValueChanged(*marker);
@@ -612,6 +628,7 @@
 }
 
 void LayoutListItem::UpdateLayout() {
+  CheckIsNotDestroyed();
   LayoutObject* marker = Marker();
   if (ListMarker* list_marker = ListMarker::Get(marker))
     list_marker->UpdateMarkerTextIfNeeded(*marker);
diff --git a/third_party/blink/renderer/core/layout/layout_list_item.h b/third_party/blink/renderer/core/layout/layout_list_item.h
index 2442bba..b7de7c2 100644
--- a/third_party/blink/renderer/core/layout/layout_list_item.h
+++ b/third_party/blink/renderer/core/layout/layout_list_item.h
@@ -38,14 +38,21 @@
   bool IsEmpty() const;
 
   LayoutObject* Marker() const {
+    CheckIsNotDestroyed();
     Element* list_item = To<Element>(GetNode());
     return list_item->PseudoElementLayoutObject(kPseudoIdMarker);
   }
 
-  ListItemOrdinal& Ordinal() { return ordinal_; }
+  ListItemOrdinal& Ordinal() {
+    CheckIsNotDestroyed();
+    return ordinal_;
+  }
   void OrdinalValueChanged();
 
-  const char* GetName() const override { return "LayoutListItem"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutListItem";
+  }
 
   void RecalcVisualOverflow() override;
 
@@ -53,6 +60,7 @@
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectListItem || LayoutBlockFlow::IsOfType(type);
   }
 
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 715ade7..4be3a33 100644
--- a/third_party/blink/renderer/core/layout/layout_list_marker.cc
+++ b/third_party/blink/renderer/core/layout/layout_list_marker.cc
@@ -44,12 +44,14 @@
 LayoutListMarker::~LayoutListMarker() = default;
 
 void LayoutListMarker::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   if (image_)
     image_->RemoveClient(this);
   LayoutBox::WillBeDestroyed();
 }
 
 const LayoutListItem* LayoutListMarker::ListItem() const {
+  CheckIsNotDestroyed();
   LayoutObject* list_item = GetNode()->parentNode()->GetLayoutObject();
   DCHECK(list_item);
   DCHECK(list_item->IsListItem());
@@ -57,6 +59,7 @@
 }
 
 LayoutSize LayoutListMarker::ImageBulletSize() const {
+  CheckIsNotDestroyed();
   DCHECK(IsImage());
   const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
   DCHECK(font_data);
@@ -75,6 +78,7 @@
 }
 
 void LayoutListMarker::ListStyleTypeChanged() {
+  CheckIsNotDestroyed();
   if (IsImage())
     return;
   SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
@@ -82,6 +86,7 @@
 }
 
 void LayoutListMarker::UpdateMarkerImageIfNeeded(StyleImage* image) {
+  CheckIsNotDestroyed();
   if (image_ != image) {
     if (image_)
       image_->RemoveClient(this);
@@ -92,20 +97,24 @@
 }
 
 InlineBox* LayoutListMarker::CreateInlineBox() {
+  CheckIsNotDestroyed();
   InlineBox* result = LayoutBox::CreateInlineBox();
   result->SetIsText(IsText());
   return result;
 }
 
 bool LayoutListMarker::IsImage() const {
+  CheckIsNotDestroyed();
   return image_ && !image_->ErrorOccurred();
 }
 
 void LayoutListMarker::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   ListMarkerPainter(*this).Paint(paint_info);
 }
 
 void LayoutListMarker::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
 
@@ -138,6 +147,7 @@
 }
 
 void LayoutListMarker::ImageChanged(WrappedImagePtr o, CanDeferInvalidation) {
+  CheckIsNotDestroyed();
   // A list marker can't have a background or border image, so no need to call
   // the base class method.
   if (!image_ || o != image_->Data())
@@ -153,6 +163,7 @@
 }
 
 void LayoutListMarker::UpdateContent() {
+  CheckIsNotDestroyed();
   DCHECK(IntrinsicLogicalWidthsDirty());
 
   text_ = "";
@@ -178,6 +189,7 @@
 }
 
 String LayoutListMarker::TextAlternative() const {
+  CheckIsNotDestroyed();
   if (GetListStyleCategory() == ListMarker::ListStyleCategory::kStaticString)
     return text_;
   UChar suffix =
@@ -188,6 +200,7 @@
 
 LayoutUnit LayoutListMarker::GetWidthOfText(
     ListMarker::ListStyleCategory category) const {
+  CheckIsNotDestroyed();
   // TODO(crbug.com/1012289): this code doesn't support bidi algorithm.
   if (text_.IsEmpty())
     return LayoutUnit();
@@ -209,6 +222,7 @@
 }
 
 MinMaxSizes LayoutListMarker::ComputeIntrinsicLogicalWidths() const {
+  CheckIsNotDestroyed();
   DCHECK(IntrinsicLogicalWidthsDirty());
   const_cast<LayoutListMarker*>(this)->UpdateContent();
 
@@ -237,10 +251,12 @@
 }
 
 MinMaxSizes LayoutListMarker::PreferredLogicalWidths() const {
+  CheckIsNotDestroyed();
   return IntrinsicLogicalWidths();
 }
 
 void LayoutListMarker::UpdateMargins(LayoutUnit marker_inline_size) {
+  CheckIsNotDestroyed();
   LayoutUnit margin_start;
   LayoutUnit margin_end;
   const ComputedStyle& style = StyleRef();
@@ -258,6 +274,7 @@
 }
 
 void LayoutListMarker::UpdateMargins() {
+  CheckIsNotDestroyed();
   UpdateMargins(PreferredLogicalWidths().min_size);
 }
 
@@ -265,6 +282,7 @@
     bool first_line,
     LineDirectionMode direction,
     LinePositionMode line_position_mode) const {
+  CheckIsNotDestroyed();
   if (!IsImage())
     return ListItem()->LineHeight(first_line, direction,
                                   kPositionOfInteriorLineBoxes);
@@ -276,6 +294,7 @@
     bool first_line,
     LineDirectionMode direction,
     LinePositionMode line_position_mode) const {
+  CheckIsNotDestroyed();
   DCHECK_EQ(line_position_mode, kPositionOnContainingLine);
   if (!IsImage())
     return ListItem()->BaselinePosition(baseline_type, first_line, direction,
@@ -285,10 +304,12 @@
 }
 
 ListMarker::ListStyleCategory LayoutListMarker::GetListStyleCategory() const {
+  CheckIsNotDestroyed();
   return ListMarker::GetListStyleCategory(StyleRef().ListStyleType());
 }
 
 bool LayoutListMarker::IsInside() const {
+  CheckIsNotDestroyed();
   const LayoutListItem* list_item = ListItem();
   const ComputedStyle& parent_style = list_item->StyleRef();
   return parent_style.ListStylePosition() == EListStylePosition::kInside ||
@@ -297,6 +318,7 @@
 }
 
 LayoutRect LayoutListMarker::GetRelativeMarkerRect() const {
+  CheckIsNotDestroyed();
   if (IsImage())
     return LayoutRect(LayoutPoint(), ImageBulletSize());
 
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 27b0d37..b6c3f90 100644
--- a/third_party/blink/renderer/core/layout/layout_list_marker.h
+++ b/third_party/blink/renderer/core/layout/layout_list_marker.h
@@ -42,7 +42,10 @@
   ~LayoutListMarker() override;
 
   // Marker text without suffix, e.g. "1".
-  const String& GetText() const { return text_; }
+  const String& GetText() const {
+    CheckIsNotDestroyed();
+    return text_;
+  }
 
   // Marker text with suffix, e.g. "1. ", for use in accessibility.
   String TextAlternative() const;
@@ -54,13 +57,20 @@
   LayoutRect GetRelativeMarkerRect() const;
 
   bool IsImage() const override;
-  const StyleImage* GetImage() const { return image_.Get(); }
+  const StyleImage* GetImage() const {
+    CheckIsNotDestroyed();
+    return image_.Get();
+  }
   const LayoutListItem* ListItem() const;
   LayoutSize ImageBulletSize() const;
 
-  const char* GetName() const override { return "LayoutListMarker"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutListMarker";
+  }
 
   LayoutUnit ListItemInlineStartOffset() const {
+    CheckIsNotDestroyed();
     return list_item_inline_start_offset_;
   }
 
@@ -72,6 +82,7 @@
   MinMaxSizes PreferredLogicalWidths() const override;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectListMarker || LayoutBox::IsOfType(type);
   }
 
@@ -93,7 +104,10 @@
       LineDirectionMode,
       LinePositionMode = kPositionOnContainingLine) const override;
 
-  bool IsText() const { return !IsImage(); }
+  bool IsText() const {
+    CheckIsNotDestroyed();
+    return !IsImage();
+  }
 
   LayoutUnit GetWidthOfText(ListMarker::ListStyleCategory) const;
   void UpdateMargins(LayoutUnit marker_inline_size);
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 e17dbc4..9bf849bb 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
@@ -21,10 +21,12 @@
 }
 
 bool LayoutListMarkerImage::IsOfType(LayoutObjectType type) const {
+  CheckIsNotDestroyed();
   return type == kLayoutObjectListMarkerImage || LayoutImage::IsOfType(type);
 }
 
 LayoutSize LayoutListMarkerImage::DefaultSize() const {
+  CheckIsNotDestroyed();
   const SimpleFontData* font_data = Style()->GetFont().PrimaryFont();
   DCHECK(font_data);
   if (!font_data)
@@ -39,6 +41,7 @@
 // default object size(ascent/2 x ascent/2).
 void LayoutListMarkerImage::ComputeIntrinsicSizingInfoByDefaultSize(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  CheckIsNotDestroyed();
   FloatSize concrete_size = ImageResource()->ImageSizeWithDefaultSize(
       Style()->EffectiveZoom(), FloatSize(DefaultSize()));
   concrete_size.Scale(ImageDevicePixelRatio());
@@ -52,6 +55,7 @@
 
 void LayoutListMarkerImage::ComputeIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  CheckIsNotDestroyed();
   LayoutImage::ComputeIntrinsicSizingInfo(intrinsic_sizing_info);
 
   // If this is an image without intrinsic width and height, compute the
diff --git a/third_party/blink/renderer/core/layout/layout_list_marker_image.h b/third_party/blink/renderer/core/layout/layout_list_marker_image.h
index 878cde8..1222081 100644
--- a/third_party/blink/renderer/core/layout/layout_list_marker_image.h
+++ b/third_party/blink/renderer/core/layout/layout_list_marker_image.h
@@ -18,6 +18,7 @@
   static LayoutListMarkerImage* CreateAnonymous(Document*);
 
   bool IsLayoutNGObject() const override {
+    CheckIsNotDestroyed();
     return IsLayoutNGObjectForListMarkerImage();
   }
   LayoutSize DefaultSize() const;
diff --git a/third_party/blink/renderer/core/layout/layout_media.cc b/third_party/blink/renderer/core/layout/layout_media.cc
index a59ab695..41171ab 100644
--- a/third_party/blink/renderer/core/layout/layout_media.cc
+++ b/third_party/blink/renderer/core/layout/layout_media.cc
@@ -42,10 +42,12 @@
 LayoutMedia::~LayoutMedia() = default;
 
 HTMLMediaElement* LayoutMedia::MediaElement() const {
+  CheckIsNotDestroyed();
   return To<HTMLMediaElement>(GetNode());
 }
 
 void LayoutMedia::UpdateLayout() {
+  CheckIsNotDestroyed();
   LayoutSize old_size(ContentWidth(), ContentHeight());
 
   LayoutImage::UpdateLayout();
@@ -104,6 +106,7 @@
 
 bool LayoutMedia::IsChildAllowed(LayoutObject* child,
                                  const ComputedStyle& style) const {
+  CheckIsNotDestroyed();
   // Two types of child layout objects are allowed: media controls
   // and the text track container. Filter children by node type.
   DCHECK(child->GetNode());
@@ -132,9 +135,12 @@
 }
 
 void LayoutMedia::PaintReplaced(const PaintInfo&,
-                                const PhysicalOffset& paint_offset) const {}
+                                const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
+}
 
 LayoutUnit LayoutMedia::ComputePanelWidth(const LayoutRect& media_rect) const {
+  CheckIsNotDestroyed();
   // TODO(mlamouri): we don't know if the main frame has an horizontal scrollbar
   // if it is out of process. See https://crbug.com/662480
   if (GetDocument().GetPage()->MainFrame()->IsRemoteFrame())
diff --git a/third_party/blink/renderer/core/layout/layout_media.h b/third_party/blink/renderer/core/layout/layout_media.h
index d303267..003f2bef 100644
--- a/third_party/blink/renderer/core/layout/layout_media.h
+++ b/third_party/blink/renderer/core/layout/layout_media.h
@@ -39,10 +39,12 @@
   ~LayoutMedia() override;
 
   LayoutObject* FirstChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->FirstChild();
   }
   LayoutObject* LastChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->LastChild();
   }
@@ -51,38 +53,62 @@
   void SlowFirstChild() const = delete;
   void SlowLastChild() const = delete;
 
-  const LayoutObjectChildList* Children() const { return &children_; }
-  LayoutObjectChildList* Children() { return &children_; }
+  const LayoutObjectChildList* Children() const {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
+  LayoutObjectChildList* Children() {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
 
   HTMLMediaElement* MediaElement() const;
 
-  const char* GetName() const override { return "LayoutMedia"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutMedia";
+  }
 
  protected:
   void UpdateLayout() override;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectMedia || LayoutImage::IsOfType(type);
   }
 
  private:
-  LayoutObjectChildList* VirtualChildren() final { return Children(); }
+  LayoutObjectChildList* VirtualChildren() final {
+    CheckIsNotDestroyed();
+    return Children();
+  }
   const LayoutObjectChildList* VirtualChildren() const final {
+    CheckIsNotDestroyed();
     return Children();
   }
 
   PaintLayerType LayerTypeRequired() const override {
+    CheckIsNotDestroyed();
     return kNormalPaintLayer;
   }
 
-  bool CanHaveChildren() const final { return true; }
+  bool CanHaveChildren() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
   bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const final;
 
-  bool IsImage() const final { return false; }
+  bool IsImage() const final {
+    CheckIsNotDestroyed();
+    return false;
+  }
   void PaintReplaced(const PaintInfo&,
                      const PhysicalOffset& paint_offset) const override;
 
-  bool BackgroundShouldAlwaysBeClipped() const final { return false; }
+  bool BackgroundShouldAlwaysBeClipped() const final {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   LayoutUnit ComputePanelWidth(const LayoutRect& media_width) const;
 
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 1670a3f..e5262c42 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
@@ -63,6 +63,7 @@
 }
 
 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::FirstMultiColumnSet() const {
+  CheckIsNotDestroyed();
   for (LayoutObject* sibling = NextSibling(); sibling;
        sibling = sibling->NextSibling()) {
     if (sibling->IsLayoutMultiColumnSet())
@@ -72,6 +73,7 @@
 }
 
 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::LastMultiColumnSet() const {
+  CheckIsNotDestroyed();
   for (LayoutObject* sibling = MultiColumnBlockFlow()->LastChild(); sibling;
        sibling = sibling->PreviousSibling()) {
     if (sibling->IsLayoutMultiColumnSet())
@@ -104,6 +106,7 @@
 // spanners inside objects that don't support fragmentation.
 bool LayoutMultiColumnFlowThread::CanContainSpannerInParentFragmentationContext(
     const LayoutObject& object) const {
+  CheckIsNotDestroyed();
   const auto* block_flow = DynamicTo<LayoutBlockFlow>(object);
   if (!block_flow)
     return false;
@@ -232,6 +235,7 @@
 
 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::MapDescendantToColumnSet(
     LayoutObject* layout_object) const {
+  CheckIsNotDestroyed();
   // Should not be used for spanners or content inside them.
   DCHECK(!ContainingColumnSpannerPlaceholder(layout_object));
   DCHECK_NE(layout_object, this);
@@ -271,6 +275,7 @@
 LayoutMultiColumnSpannerPlaceholder*
 LayoutMultiColumnFlowThread::ContainingColumnSpannerPlaceholder(
     const LayoutObject* descendant) const {
+  CheckIsNotDestroyed();
   DCHECK(descendant->IsDescendantOf(this));
 
   if (!HasAnyColumnSpanners(*this))
@@ -288,6 +293,7 @@
 }
 
 void LayoutMultiColumnFlowThread::Populate() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow* multicol_container = MultiColumnBlockFlow();
   DCHECK(!NextSibling());
   // Reparent children preceding the flow thread into the flow thread. It's
@@ -300,6 +306,7 @@
 }
 
 void LayoutMultiColumnFlowThread::EvacuateAndDestroy() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow* multicol_container = MultiColumnBlockFlow();
   is_being_evacuated_ = true;
 
@@ -327,6 +334,7 @@
 }
 
 LayoutUnit LayoutMultiColumnFlowThread::MaxColumnLogicalHeight() const {
+  CheckIsNotDestroyed();
   if (column_height_available_) {
     // If height is non-auto, it's already constrained against max-height as
     // well. Just return it.
@@ -347,6 +355,7 @@
 
 LayoutUnit LayoutMultiColumnFlowThread::TallestUnbreakableLogicalHeight(
     LayoutUnit offset_in_flow_thread) const {
+  CheckIsNotDestroyed();
   if (LayoutMultiColumnSet* multicol_set = ColumnSetAtBlockOffset(
           offset_in_flow_thread, kAssociateWithLatterPage))
     return multicol_set->TallestUnbreakableLogicalHeight();
@@ -355,11 +364,13 @@
 
 LayoutSize LayoutMultiColumnFlowThread::ColumnOffset(
     const LayoutPoint& point) const {
+  CheckIsNotDestroyed();
   return FlowThreadTranslationAtPoint(point,
                                       CoordinateSpaceConversion::kContaining);
 }
 
 bool LayoutMultiColumnFlowThread::NeedsNewWidth() const {
+  CheckIsNotDestroyed();
   LayoutUnit new_width;
   unsigned dummy_column_count;  // We only care if used column-width changes.
   CalculateColumnCountAndWidth(new_width, dummy_column_count);
@@ -367,10 +378,12 @@
 }
 
 bool LayoutMultiColumnFlowThread::IsPageLogicalHeightKnown() const {
+  CheckIsNotDestroyed();
   return all_columns_have_known_height_;
 }
 
 bool LayoutMultiColumnFlowThread::MayHaveNonUniformPageLogicalHeight() const {
+  CheckIsNotDestroyed();
   const LayoutMultiColumnSet* column_set = FirstMultiColumnSet();
   if (!column_set)
     return false;
@@ -383,6 +396,7 @@
     LayoutUnit offset_in_flow_thread,
     PageBoundaryRule rule,
     CoordinateSpaceConversion mode) const {
+  CheckIsNotDestroyed();
   if (!HasValidColumnSetInfo())
     return LayoutSize(0, 0);
   LayoutMultiColumnSet* column_set =
@@ -396,6 +410,7 @@
 LayoutSize LayoutMultiColumnFlowThread::FlowThreadTranslationAtPoint(
     const LayoutPoint& flow_thread_point,
     CoordinateSpaceConversion mode) const {
+  CheckIsNotDestroyed();
   LayoutPoint flipped_point = DeprecatedFlipForWritingMode(flow_thread_point);
   LayoutUnit block_offset =
       IsHorizontalWritingMode() ? flipped_point.Y() : flipped_point.X();
@@ -411,6 +426,7 @@
 
 LayoutPoint LayoutMultiColumnFlowThread::FlowThreadPointToVisualPoint(
     const LayoutPoint& flow_thread_point) const {
+  CheckIsNotDestroyed();
   return flow_thread_point +
          FlowThreadTranslationAtPoint(flow_thread_point,
                                       CoordinateSpaceConversion::kVisual);
@@ -418,6 +434,7 @@
 
 LayoutPoint LayoutMultiColumnFlowThread::VisualPointToFlowThreadPoint(
     const LayoutPoint& visual_point) const {
+  CheckIsNotDestroyed();
   LayoutUnit block_offset =
       IsHorizontalWritingMode() ? visual_point.Y() : visual_point.X();
   const LayoutMultiColumnSet* column_set = nullptr;
@@ -434,6 +451,7 @@
 
 LayoutUnit LayoutMultiColumnFlowThread::InlineBlockBaseline(
     LineDirectionMode line_direction) const {
+  CheckIsNotDestroyed();
   LayoutUnit baseline_in_flow_thread =
       LayoutFlowThread::InlineBlockBaseline(line_direction);
   LayoutMultiColumnSet* column_set =
@@ -449,6 +467,7 @@
 LayoutMultiColumnSet* LayoutMultiColumnFlowThread::ColumnSetAtBlockOffset(
     LayoutUnit offset,
     PageBoundaryRule page_boundary_rule) const {
+  CheckIsNotDestroyed();
   LayoutMultiColumnSet* column_set = last_set_worked_on_;
   if (column_set) {
     // Layout in progress. We are calculating the set heights as we speak, so
@@ -522,6 +541,7 @@
 
 void LayoutMultiColumnFlowThread::LayoutColumns(
     SubtreeLayoutScope& layout_scope) {
+  CheckIsNotDestroyed();
   // Since we ended up here, it means that the multicol container (our parent)
   // needed layout. Since contents of the multicol container are diverted to the
   // flow thread, the flow thread needs layout as well.
@@ -593,6 +613,7 @@
 }
 
 void LayoutMultiColumnFlowThread::ColumnRuleStyleDidChange() {
+  CheckIsNotDestroyed();
   for (LayoutMultiColumnSet* column_set = FirstMultiColumnSet(); column_set;
        column_set = column_set->NextSiblingMultiColumnSet()) {
     column_set->SetShouldDoFullPaintInvalidation(
@@ -602,6 +623,7 @@
 
 bool LayoutMultiColumnFlowThread::RemoveSpannerPlaceholderIfNoLongerValid(
     LayoutBox* spanner_object_in_flow_thread) {
+  CheckIsNotDestroyed();
   DCHECK(spanner_object_in_flow_thread->SpannerPlaceholder());
   if (DescendantIsValidColumnSpanner(spanner_object_in_flow_thread))
     return false;  // Still a valid spanner.
@@ -626,6 +648,7 @@
 
 LayoutMultiColumnFlowThread* LayoutMultiColumnFlowThread::EnclosingFlowThread(
     AncestorSearchConstraint constraint) const {
+  CheckIsNotDestroyed();
   if (!MultiColumnBlockFlow()->IsInsideFlowThread())
     return nullptr;
   return ToLayoutMultiColumnFlowThread(
@@ -635,6 +658,7 @@
 FragmentationContext*
 LayoutMultiColumnFlowThread::EnclosingFragmentationContext(
     AncestorSearchConstraint constraint) const {
+  CheckIsNotDestroyed();
   // If this multicol container is strictly unbreakable (due to having
   // scrollbars, for instance), it's also strictly unbreakable in any outer
   // fragmentation context. As such, what kind of fragmentation that goes on
@@ -651,6 +675,7 @@
 void LayoutMultiColumnFlowThread::AppendNewFragmentainerGroupIfNeeded(
     LayoutUnit offset_in_flow_thread,
     PageBoundaryRule page_boundary_rule) {
+  CheckIsNotDestroyed();
   LayoutMultiColumnSet* column_set =
       ColumnSetAtBlockOffset(offset_in_flow_thread, page_boundary_rule);
   if (!column_set->NewFragmentainerGroupsAllowed())
@@ -693,6 +718,7 @@
 }
 
 void LayoutMultiColumnFlowThread::UpdateFromNG() {
+  CheckIsNotDestroyed();
   all_columns_have_known_height_ = true;
   for (LayoutBox* column_box = FirstMultiColumnBox(); column_box;
        column_box = column_box->NextSiblingMultiColumnBox()) {
@@ -704,23 +730,27 @@
 }
 
 bool LayoutMultiColumnFlowThread::IsFragmentainerLogicalHeightKnown() {
+  CheckIsNotDestroyed();
   return IsPageLogicalHeightKnown();
 }
 
 LayoutUnit LayoutMultiColumnFlowThread::FragmentainerLogicalHeightAt(
     LayoutUnit block_offset) {
+  CheckIsNotDestroyed();
   DCHECK(IsPageLogicalHeightKnown());
   return PageLogicalHeightForOffset(block_offset);
 }
 
 LayoutUnit LayoutMultiColumnFlowThread::RemainingLogicalHeightAt(
     LayoutUnit block_offset) {
+  CheckIsNotDestroyed();
   DCHECK(IsPageLogicalHeightKnown());
   return PageRemainingLogicalHeightForOffset(block_offset,
                                              kAssociateWithLatterPage);
 }
 
 void LayoutMultiColumnFlowThread::CalculateColumnHeightAvailable() {
+  CheckIsNotDestroyed();
   // Calculate the non-auto content box height, or set it to 0 if it's auto. We
   // need to know this before layout, so that we can figure out where to insert
   // column breaks. We also treat LayoutView (which may be paginated, which uses
@@ -747,6 +777,7 @@
 void LayoutMultiColumnFlowThread::CalculateColumnCountAndWidth(
     LayoutUnit& width,
     unsigned& count) const {
+  CheckIsNotDestroyed();
   LayoutBlock* column_block = MultiColumnBlockFlow();
   const ComputedStyle* column_style = column_block->Style();
   LayoutUnit available_width = column_block->ContentLogicalWidth();
@@ -789,6 +820,7 @@
 
 void LayoutMultiColumnFlowThread::CreateAndInsertMultiColumnSet(
     LayoutBox* insert_before) {
+  CheckIsNotDestroyed();
   LayoutBlockFlow* multicol_container = MultiColumnBlockFlow();
   LayoutMultiColumnSet* new_set = LayoutMultiColumnSet::CreateAnonymous(
       *this, multicol_container->StyleRef());
@@ -806,6 +838,7 @@
 void LayoutMultiColumnFlowThread::CreateAndInsertSpannerPlaceholder(
     LayoutBox* spanner_object_in_flow_thread,
     LayoutObject* inserted_before_in_flow_thread) {
+  CheckIsNotDestroyed();
   LayoutBox* insert_before_column_box = nullptr;
   LayoutMultiColumnSet* set_to_split = nullptr;
   if (inserted_before_in_flow_thread) {
@@ -863,6 +896,7 @@
 
 void LayoutMultiColumnFlowThread::DestroySpannerPlaceholder(
     LayoutMultiColumnSpannerPlaceholder* placeholder) {
+  CheckIsNotDestroyed();
   if (LayoutBox* next_column_box = placeholder->NextSiblingMultiColumnBox()) {
     LayoutBox* previous_column_box =
         placeholder->PreviousSiblingMultiColumnBox();
@@ -878,6 +912,7 @@
 
 bool LayoutMultiColumnFlowThread::DescendantIsValidColumnSpanner(
     LayoutObject* descendant) const {
+  CheckIsNotDestroyed();
   // This method needs to behave correctly in the following situations:
   // - When the descendant doesn't have a spanner placeholder but should have
   //   one (return true).
@@ -922,6 +957,7 @@
 
 void LayoutMultiColumnFlowThread::AddColumnSetToThread(
     LayoutMultiColumnSet* column_set) {
+  CheckIsNotDestroyed();
   if (LayoutMultiColumnSet* next_set =
           column_set->NextSiblingMultiColumnSet()) {
     LayoutMultiColumnSetList::iterator it =
@@ -934,6 +970,7 @@
 }
 
 void LayoutMultiColumnFlowThread::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   LayoutFlowThread::InsertedIntoTree();
   if (MultiColumnBlockFlow()->IsLayoutNGObject())
     fragmentation_engine_ = kNGFragmentationEngine;
@@ -942,6 +979,7 @@
 }
 
 void LayoutMultiColumnFlowThread::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   // Detach all column sets from the flow thread. Cannot destroy them at this
   // point, since they are siblings of this object, and there may be pointers to
   // this object's sibling somewhere further up on the call stack.
@@ -955,6 +993,7 @@
 void LayoutMultiColumnFlowThread::SkipColumnSpanner(
     LayoutBox* layout_object,
     LayoutUnit logical_top_in_flow_thread) {
+  CheckIsNotDestroyed();
   DCHECK(layout_object->IsColumnSpanAll());
   LayoutMultiColumnSpannerPlaceholder* placeholder =
       layout_object->SpannerPlaceholder();
@@ -987,6 +1026,7 @@
 }
 
 bool LayoutMultiColumnFlowThread::FinishLayout() {
+  CheckIsNotDestroyed();
   all_columns_have_known_height_ = true;
   for (const auto* column_set = FirstMultiColumnSet(); column_set;
        column_set = column_set->NextSiblingMultiColumnSet()) {
@@ -1030,6 +1070,7 @@
 
 void LayoutMultiColumnFlowThread::FlowThreadDescendantWasInserted(
     LayoutObject* descendant) {
+  CheckIsNotDestroyed();
   DCHECK(!is_being_evacuated_);
   // This method ensures that the list of column sets and spanner placeholders
   // reflects the multicol content after having inserted a descendant (or
@@ -1089,6 +1130,7 @@
 
 void LayoutMultiColumnFlowThread::FlowThreadDescendantWillBeRemoved(
     LayoutObject* descendant) {
+  CheckIsNotDestroyed();
   // This method ensures that the list of column sets and spanner placeholders
   // reflects the multicol content that we'll be left with after removal of a
   // descendant (or descendant subtree). See the header file for more
@@ -1237,6 +1279,7 @@
     LayoutBox* descendant,
     StyleDifference diff,
     const ComputedStyle& new_style) {
+  CheckIsNotDestroyed();
   toggle_spanners_if_needed_ = false;
   if (NeedsToRemoveFromFlowThread(*descendant, descendant->StyleRef(),
                                   new_style)) {
@@ -1259,6 +1302,7 @@
     LayoutBox* descendant,
     StyleDifference diff,
     const ComputedStyle& old_style) {
+  CheckIsNotDestroyed();
   bool toggle_spanners_if_needed = toggle_spanners_if_needed_;
   toggle_spanners_if_needed_ = false;
 
@@ -1299,6 +1343,7 @@
 
 void LayoutMultiColumnFlowThread::ToggleSpannersInSubtree(
     LayoutBox* descendant) {
+  CheckIsNotDestroyed();
   DCHECK_NE(could_contain_spanners_,
             CanContainSpannerInParentFragmentationContext(*descendant));
 
@@ -1345,6 +1390,7 @@
 }
 
 MinMaxSizes LayoutMultiColumnFlowThread::PreferredLogicalWidths() const {
+  CheckIsNotDestroyed();
   // The min/max intrinsic widths calculated really tell how much space elements
   // need when laid out inside the columns. In order to eventually end up with
   // the desired column width, we need to convert them to values pertaining to
@@ -1387,18 +1433,21 @@
     LayoutUnit logical_height,
     LayoutUnit logical_top,
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   // We simply remain at our intrinsic height.
   computed_values.extent_ = logical_height;
   computed_values.position_ = logical_top;
 }
 
 void LayoutMultiColumnFlowThread::UpdateLogicalWidth() {
+  CheckIsNotDestroyed();
   LayoutUnit column_width;
   CalculateColumnCountAndWidth(column_width, column_count_);
   SetLogicalWidth(column_width);
 }
 
 void LayoutMultiColumnFlowThread::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(!last_set_worked_on_);
   last_set_worked_on_ = FirstMultiColumnSet();
   if (last_set_worked_on_)
@@ -1427,6 +1476,7 @@
 
 void LayoutMultiColumnFlowThread::ContentWasLaidOut(
     LayoutUnit logical_bottom_in_flow_thread_after_pagination) {
+  CheckIsNotDestroyed();
   // Check if we need another fragmentainer group. If we've run out of columns
   // in the last fragmentainer group (column row), we need to insert another
   // fragmentainer group to hold more columns.
@@ -1448,6 +1498,7 @@
 }
 
 bool LayoutMultiColumnFlowThread::CanSkipLayout(const LayoutBox& root) const {
+  CheckIsNotDestroyed();
   // Objects containing spanners is all we need to worry about, so if there are
   // no spanners at all in this multicol container, we can just return the good
   // news right away.
@@ -1473,11 +1524,13 @@
 
 MultiColumnLayoutState LayoutMultiColumnFlowThread::GetMultiColumnLayoutState()
     const {
+  CheckIsNotDestroyed();
   return MultiColumnLayoutState(last_set_worked_on_);
 }
 
 void LayoutMultiColumnFlowThread::RestoreMultiColumnLayoutState(
     const MultiColumnLayoutState& state) {
+  CheckIsNotDestroyed();
   last_set_worked_on_ = state.ColumnSet();
 }
 
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 759095c..0a60069 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
@@ -151,9 +151,13 @@
       const ComputedStyle& parent_style,
       bool needs_paint_layer);
 
-  bool IsLayoutMultiColumnFlowThread() const final { return true; }
+  bool IsLayoutMultiColumnFlowThread() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   LayoutBlockFlow* MultiColumnBlockFlow() const {
+    CheckIsNotDestroyed();
     return To<LayoutBlockFlow>(Parent());
   }
 
@@ -161,9 +165,13 @@
   LayoutMultiColumnSet* LastMultiColumnSet() const;
 
   // Return the first column set or spanner placeholder.
-  LayoutBox* FirstMultiColumnBox() const { return NextSiblingBox(); }
+  LayoutBox* FirstMultiColumnBox() const {
+    CheckIsNotDestroyed();
+    return NextSiblingBox();
+  }
   // Return the last column set or spanner placeholder.
   LayoutBox* LastMultiColumnBox() const {
+    CheckIsNotDestroyed();
     LayoutBox* last_sibling_box = MultiColumnBlockFlow()->LastChildBox();
     // The flow thread is the first child of the multicol container. If the flow
     // thread is also the last child, it means that there are no siblings; i.e.
@@ -190,12 +198,19 @@
   // a multicol container becomes a regular block.
   void EvacuateAndDestroy();
 
-  unsigned ColumnCount() const { return column_count_; }
+  unsigned ColumnCount() const {
+    CheckIsNotDestroyed();
+    return column_count_;
+  }
 
   // Total height available to columns and spanners. This is the multicol
   // container's content box logical height, or 0 if auto.
-  LayoutUnit ColumnHeightAvailable() const { return column_height_available_; }
+  LayoutUnit ColumnHeightAvailable() const {
+    CheckIsNotDestroyed();
+    return column_height_available_;
+  }
   void SetColumnHeightAvailable(LayoutUnit available) {
+    CheckIsNotDestroyed();
     column_height_available_ = available;
   }
 
@@ -250,8 +265,14 @@
   // again twice or even just once will suffice. Sometimes we need more passes
   // than that, though, but the number of retries should not exceed the number
   // of columns, unless we have a bug.
-  bool ColumnHeightsChanged() const { return column_heights_changed_; }
-  void SetColumnHeightsChanged() { column_heights_changed_ = true; }
+  bool ColumnHeightsChanged() const {
+    CheckIsNotDestroyed();
+    return column_heights_changed_;
+  }
+  void SetColumnHeightsChanged() {
+    CheckIsNotDestroyed();
+    column_heights_changed_ = true;
+  }
 
   // Finish multicol layout. Returns true if we're really done, or false if we
   // need another layout pass (typically because columns got new heights in the
@@ -270,6 +291,7 @@
   FragmentationContext* EnclosingFragmentationContext(
       AncestorSearchConstraint = kIsolateUnbreakableContainers) const;
   LayoutUnit BlockOffsetInEnclosingFragmentationContext() const {
+    CheckIsNotDestroyed();
     DCHECK(EnclosingFragmentationContext(kAnyAncestor));
     return block_offset_in_enclosing_fragmentation_context_;
   }
@@ -287,9 +309,15 @@
   bool IsFragmentainerLogicalHeightKnown() final;
   LayoutUnit FragmentainerLogicalHeightAt(LayoutUnit block_offset) final;
   LayoutUnit RemainingLogicalHeightAt(LayoutUnit block_offset) final;
-  LayoutMultiColumnFlowThread* AssociatedFlowThread() final { return this; }
+  LayoutMultiColumnFlowThread* AssociatedFlowThread() final {
+    CheckIsNotDestroyed();
+    return this;
+  }
 
-  const char* GetName() const override { return "LayoutMultiColumnFlowThread"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutMultiColumnFlowThread";
+  }
 
  private:
   explicit LayoutMultiColumnFlowThread(bool needs_paint_layer);
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 9240379b..b1c380de 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
@@ -54,6 +54,7 @@
 unsigned LayoutMultiColumnSet::FragmentainerGroupIndexAtFlowThreadOffset(
     LayoutUnit flow_thread_offset,
     PageBoundaryRule rule) const {
+  CheckIsNotDestroyed();
   DCHECK_GT(fragmentainer_groups_.size(), 0u);
   if (flow_thread_offset <= 0)
     return 0;
@@ -75,6 +76,7 @@
 const MultiColumnFragmentainerGroup&
 LayoutMultiColumnSet::FragmentainerGroupAtVisualPoint(
     const LayoutPoint& visual_point) const {
+  CheckIsNotDestroyed();
   DCHECK_GT(fragmentainer_groups_.size(), 0u);
   LayoutUnit block_offset =
       IsHorizontalWritingMode() ? visual_point.Y() : visual_point.X();
@@ -88,6 +90,7 @@
 
 LayoutUnit LayoutMultiColumnSet::PageLogicalHeightForOffset(
     LayoutUnit offset) const {
+  CheckIsNotDestroyed();
   DCHECK(IsPageLogicalHeightKnown());
   const MultiColumnFragmentainerGroup& last_row = LastFragmentainerGroup();
   if (offset >= last_row.LogicalTopInFlowThread() +
@@ -131,6 +134,7 @@
 LayoutUnit LayoutMultiColumnSet::PageRemainingLogicalHeightForOffset(
     LayoutUnit offset_in_flow_thread,
     PageBoundaryRule page_boundary_rule) const {
+  CheckIsNotDestroyed();
   const MultiColumnFragmentainerGroup& row =
       FragmentainerGroupAtFlowThreadOffset(offset_in_flow_thread,
                                            page_boundary_rule);
@@ -159,10 +163,12 @@
 }
 
 bool LayoutMultiColumnSet::IsPageLogicalHeightKnown() const {
+  CheckIsNotDestroyed();
   return FirstFragmentainerGroup().IsLogicalHeightKnown();
 }
 
 bool LayoutMultiColumnSet::NewFragmentainerGroupsAllowed() const {
+  CheckIsNotDestroyed();
   if (!IsPageLogicalHeightKnown()) {
     // If we have no clue about the height of the multicol container, bail. This
     // situation occurs initially when an auto-height multicol container is
@@ -185,6 +191,7 @@
 LayoutUnit LayoutMultiColumnSet::NextLogicalTopForUnbreakableContent(
     LayoutUnit flow_thread_offset,
     LayoutUnit content_logical_height) const {
+  CheckIsNotDestroyed();
   if (!MultiColumnFlowThread()->EnclosingFragmentationContext()) {
     // If there's no enclosing fragmentation context, there'll ever be only one
     // row, and all columns there will have the same height.
@@ -216,6 +223,7 @@
 }
 
 LayoutMultiColumnSet* LayoutMultiColumnSet::NextSiblingMultiColumnSet() const {
+  CheckIsNotDestroyed();
   for (LayoutObject* sibling = NextSibling(); sibling;
        sibling = sibling->NextSibling()) {
     if (sibling->IsLayoutMultiColumnSet())
@@ -226,6 +234,7 @@
 
 LayoutMultiColumnSet* LayoutMultiColumnSet::PreviousSiblingMultiColumnSet()
     const {
+  CheckIsNotDestroyed();
   for (LayoutObject* sibling = PreviousSibling(); sibling;
        sibling = sibling->PreviousSibling()) {
     if (sibling->IsLayoutMultiColumnSet())
@@ -237,6 +246,7 @@
 bool LayoutMultiColumnSet::NeedsNewFragmentainerGroupAt(
     LayoutUnit offset_in_flow_thread,
     PageBoundaryRule page_boundary_rule) const {
+  CheckIsNotDestroyed();
   // First the cheap check: Perhaps the last fragmentainer group has sufficient
   // capacity?
   const MultiColumnFragmentainerGroup& last_row = LastFragmentainerGroup();
@@ -285,6 +295,7 @@
 
 MultiColumnFragmentainerGroup&
 LayoutMultiColumnSet::AppendNewFragmentainerGroup() {
+  CheckIsNotDestroyed();
   MultiColumnFragmentainerGroup new_group(*this);
   {  // Extra scope here for previousGroup; it's potentially invalid once we
      // modify the m_fragmentainerGroups Vector.
@@ -307,6 +318,7 @@
 }
 
 LayoutUnit LayoutMultiColumnSet::LogicalTopFromMulticolContentEdge() const {
+  CheckIsNotDestroyed();
   // We subtract the position of the first column set or spanner placeholder,
   // rather than the "before" border+padding of the multicol container. This
   // distinction doesn't matter after layout, but during layout it does:
@@ -328,14 +340,17 @@
 }
 
 LayoutUnit LayoutMultiColumnSet::LogicalTopInFlowThread() const {
+  CheckIsNotDestroyed();
   return FirstFragmentainerGroup().LogicalTopInFlowThread();
 }
 
 LayoutUnit LayoutMultiColumnSet::LogicalBottomInFlowThread() const {
+  CheckIsNotDestroyed();
   return LastFragmentainerGroup().LogicalBottomInFlowThread();
 }
 
 bool LayoutMultiColumnSet::HeightIsAuto() const {
+  CheckIsNotDestroyed();
   LayoutMultiColumnFlowThread* flow_thread = MultiColumnFlowThread();
   // If support for the column-fill property isn't enabled, we want to behave
   // as if column-fill were auto, so that multicol containers with specified
@@ -360,12 +375,14 @@
     LayoutUnit block_offset,
     PageBoundaryRule rule,
     CoordinateSpaceConversion mode) const {
+  CheckIsNotDestroyed();
   return FragmentainerGroupAtFlowThreadOffset(block_offset, rule)
       .FlowThreadTranslationAtOffset(block_offset, rule, mode);
 }
 
 LayoutPoint LayoutMultiColumnSet::VisualPointToFlowThreadPoint(
     const LayoutPoint& visual_point) const {
+  CheckIsNotDestroyed();
   const MultiColumnFragmentainerGroup& row =
       FragmentainerGroupAtVisualPoint(visual_point);
   return row.VisualPointToFlowThreadPoint(visual_point -
@@ -374,11 +391,13 @@
 
 LayoutUnit LayoutMultiColumnSet::PageLogicalTopForOffset(
     LayoutUnit offset) const {
+  CheckIsNotDestroyed();
   return FragmentainerGroupAtFlowThreadOffset(offset, kAssociateWithLatterPage)
       .ColumnLogicalTopForOffset(offset);
 }
 
 bool LayoutMultiColumnSet::RecalculateColumnHeight() {
+  CheckIsNotDestroyed();
   if (old_logical_top_ != LogicalTop() &&
       MultiColumnFlowThread()->EnclosingFragmentationContext()) {
     // Preceding spanners or column sets have been moved or resized. This means
@@ -396,6 +415,7 @@
 }
 
 void LayoutMultiColumnSet::ResetColumnHeight() {
+  CheckIsNotDestroyed();
   fragmentainer_groups_.DeleteExtraGroups();
   fragmentainer_groups_.First().ResetColumnHeight();
   tallest_unbreakable_logical_height_ = LayoutUnit();
@@ -403,6 +423,7 @@
 }
 
 void LayoutMultiColumnSet::BeginFlow(LayoutUnit offset_in_flow_thread) {
+  CheckIsNotDestroyed();
   // At this point layout is exactly at the beginning of this set. Store block
   // offset from flow thread start.
   fragmentainer_groups_.First().SetLogicalTopInFlowThread(
@@ -410,6 +431,7 @@
 }
 
 void LayoutMultiColumnSet::EndFlow(LayoutUnit offset_in_flow_thread) {
+  CheckIsNotDestroyed();
   // At this point layout is exactly at the end of this set. Store block offset
   // from flow thread start. This set is now considered "flowed", although we
   // may have to revisit it later (with beginFlow()), e.g. if a subtree in the
@@ -421,6 +443,7 @@
 
 void LayoutMultiColumnSet::StyleDidChange(StyleDifference diff,
                                           const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::StyleDidChange(diff, old_style);
 
   // column-rule is specified on the parent (the multicol container) of this
@@ -436,6 +459,7 @@
 }
 
 void LayoutMultiColumnSet::UpdateLayout() {
+  CheckIsNotDestroyed();
   if (RecalculateColumnHeight())
     MultiColumnFlowThread()->SetColumnHeightsChanged();
   LayoutBlockFlow::UpdateLayout();
@@ -450,6 +474,7 @@
 }
 
 MinMaxSizes LayoutMultiColumnSet::ComputeIntrinsicLogicalWidths() const {
+  CheckIsNotDestroyed();
   return MinMaxSizes();
 }
 
@@ -457,6 +482,7 @@
     LayoutUnit,
     LayoutUnit logical_top,
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   LayoutUnit logical_height;
   // Under some circumstances column heights are unknown at this point. This
   // happens e.g. when this column set got pushed down by a preceding spanner
@@ -473,6 +499,7 @@
 
 PositionWithAffinity LayoutMultiColumnSet::PositionForPoint(
     const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   LayoutPoint flipped_point = FlipForWritingMode(point);
   // Convert the visual point to a flow thread point.
   const MultiColumnFragmentainerGroup& row =
@@ -486,6 +513,7 @@
 }
 
 LayoutUnit LayoutMultiColumnSet::ColumnGap() const {
+  CheckIsNotDestroyed();
   LayoutBlockFlow* parent_block = MultiColumnBlockFlow();
 
   if (const base::Optional<Length>& column_gap =
@@ -498,6 +526,7 @@
 }
 
 unsigned LayoutMultiColumnSet::ActualColumnCount() const {
+  CheckIsNotDestroyed();
   // FIXME: remove this method. It's a meaningless question to ask the set "how
   // many columns do you actually have?", since that may vary for each row.
   return FirstFragmentainerGroup().ActualColumnCount();
@@ -506,19 +535,21 @@
 void LayoutMultiColumnSet::PaintObject(
     const PaintInfo& paint_info,
     const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   MultiColumnSetPainter(*this).PaintObject(paint_info, paint_offset);
 }
 
 LayoutRect LayoutMultiColumnSet::FragmentsBoundingBox(
     const LayoutRect& bounding_box_in_flow_thread) const {
+  CheckIsNotDestroyed();
   LayoutRect result;
   for (const auto& group : fragmentainer_groups_)
     result.Unite(group.FragmentsBoundingBox(bounding_box_in_flow_thread));
   return result;
 }
 
-void LayoutMultiColumnSet::ComputeVisualOverflow(
-    bool recompute_floats) {
+void LayoutMultiColumnSet::ComputeVisualOverflow(bool recompute_floats) {
+  CheckIsNotDestroyed();
   LayoutRect previous_visual_overflow_rect = VisualOverflowRect();
   ClearVisualOverflow();
   AddVisualOverflowFromChildren();
@@ -536,6 +567,7 @@
 }
 
 void LayoutMultiColumnSet::AddVisualOverflowFromChildren() {
+  CheckIsNotDestroyed();
   if (ChildLayoutBlockedByDisplayLock())
     return;
 
@@ -553,6 +585,7 @@
 }
 
 void LayoutMultiColumnSet::AddLayoutOverflowFromChildren() {
+  CheckIsNotDestroyed();
   if (ChildLayoutBlockedByDisplayLock())
     return;
 
@@ -570,16 +603,19 @@
 }
 
 void LayoutMultiColumnSet::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::InsertedIntoTree();
   AttachToFlowThread();
 }
 
 void LayoutMultiColumnSet::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::WillBeRemovedFromTree();
   DetachFromFlowThread();
 }
 
 void LayoutMultiColumnSet::AttachToFlowThread() {
+  CheckIsNotDestroyed();
   if (DocumentBeingDestroyed())
     return;
 
@@ -590,6 +626,7 @@
 }
 
 void LayoutMultiColumnSet::DetachFromFlowThread() {
+  CheckIsNotDestroyed();
   if (flow_thread_) {
     flow_thread_->RemoveColumnSetFromThread(this);
     flow_thread_ = nullptr;
@@ -597,6 +634,7 @@
 }
 
 LayoutRect LayoutMultiColumnSet::FlowThreadPortionRect() const {
+  CheckIsNotDestroyed();
   LayoutRect portion_rect(LayoutUnit(), LogicalTopInFlowThread(),
                           PageLogicalWidth(), LogicalHeightInFlowThread());
   if (!IsHorizontalWritingMode())
@@ -607,6 +645,7 @@
 bool LayoutMultiColumnSet::ComputeColumnRuleBounds(
     const LayoutPoint& paint_offset,
     Vector<LayoutRect>& column_rule_bounds) const {
+  CheckIsNotDestroyed();
   // Reference: https://www.w3.org/TR/css3-multicol/#column-gaps-and-rules
   const ComputedStyle& block_style = MultiColumnBlockFlow()->StyleRef();
   bool rule_transparent = block_style.ColumnRuleIsTransparent();
@@ -667,6 +706,7 @@
 }
 
 PhysicalRect LayoutMultiColumnSet::LocalVisualRectIgnoringVisibility() const {
+  CheckIsNotDestroyed();
   PhysicalRect block_flow_bounds =
       LayoutBlockFlow::LocalVisualRectIgnoringVisibility();
 
@@ -681,6 +721,7 @@
 }
 
 void LayoutMultiColumnSet::UpdateFromNG() {
+  CheckIsNotDestroyed();
   DCHECK_EQ(fragmentainer_groups_.size(), 1U);
   auto& group = fragmentainer_groups_[0];
   group.UpdateFromNG(LogicalHeight());
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 6fdae46..e5d8b02 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
@@ -70,9 +70,11 @@
       const ComputedStyle& parent_style);
 
   const MultiColumnFragmentainerGroup& FirstFragmentainerGroup() const {
+    CheckIsNotDestroyed();
     return fragmentainer_groups_.First();
   }
   const MultiColumnFragmentainerGroup& LastFragmentainerGroup() const {
+    CheckIsNotDestroyed();
     return fragmentainer_groups_.Last();
   }
   unsigned FragmentainerGroupIndexAtFlowThreadOffset(LayoutUnit,
@@ -80,29 +82,39 @@
   MultiColumnFragmentainerGroup& FragmentainerGroupAtFlowThreadOffset(
       LayoutUnit flow_thread_offset,
       PageBoundaryRule rule) {
+    CheckIsNotDestroyed();
     return fragmentainer_groups_[FragmentainerGroupIndexAtFlowThreadOffset(
         flow_thread_offset, rule)];
   }
   const MultiColumnFragmentainerGroup& FragmentainerGroupAtFlowThreadOffset(
       LayoutUnit flow_thread_offset,
       PageBoundaryRule rule) const {
+    CheckIsNotDestroyed();
     return fragmentainer_groups_[FragmentainerGroupIndexAtFlowThreadOffset(
         flow_thread_offset, rule)];
   }
   const MultiColumnFragmentainerGroup& FragmentainerGroupAtVisualPoint(
       const LayoutPoint&) const;
   const MultiColumnFragmentainerGroupList& FragmentainerGroups() const {
+    CheckIsNotDestroyed();
     return fragmentainer_groups_;
   }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectLayoutMultiColumnSet ||
            LayoutBlockFlow::IsOfType(type);
   }
-  bool CanHaveChildren() const final { return false; }
+  bool CanHaveChildren() const final {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   // Return the width and height of a single column or page in the set.
-  LayoutUnit PageLogicalWidth() const { return FlowThread()->LogicalWidth(); }
+  LayoutUnit PageLogicalWidth() const {
+    CheckIsNotDestroyed();
+    return FlowThread()->LogicalWidth();
+  }
   LayoutUnit PageLogicalHeightForOffset(LayoutUnit) const;
   LayoutUnit PageRemainingLogicalHeightForOffset(LayoutUnit,
                                                  PageBoundaryRule) const;
@@ -113,9 +125,11 @@
   bool NewFragmentainerGroupsAllowed() const;
 
   LayoutUnit TallestUnbreakableLogicalHeight() const {
+    CheckIsNotDestroyed();
     return tallest_unbreakable_logical_height_;
   }
   void PropagateTallestUnbreakableLogicalHeight(LayoutUnit value) {
+    CheckIsNotDestroyed();
     tallest_unbreakable_logical_height_ =
         std::max(value, tallest_unbreakable_logical_height_);
   }
@@ -124,12 +138,17 @@
       LayoutUnit flow_thread_offset,
       LayoutUnit content_logical_height) const;
 
-  LayoutFlowThread* FlowThread() const { return flow_thread_; }
+  LayoutFlowThread* FlowThread() const {
+    CheckIsNotDestroyed();
+    return flow_thread_;
+  }
 
   LayoutBlockFlow* MultiColumnBlockFlow() const {
+    CheckIsNotDestroyed();
     return To<LayoutBlockFlow>(Parent());
   }
   LayoutMultiColumnFlowThread* MultiColumnFlowThread() const {
+    CheckIsNotDestroyed();
     return ToLayoutMultiColumnFlowThread(FlowThread());
   }
 
@@ -149,6 +168,7 @@
   LayoutUnit LogicalTopInFlowThread() const;
   LayoutUnit LogicalBottomInFlowThread() const;
   LayoutUnit LogicalHeightInFlowThread() const {
+    CheckIsNotDestroyed();
     // Due to negative margins, logical bottom may actually end up above logical
     // top, but we never want to return negative logical heights.
     return (LogicalBottomInFlowThread() - LogicalTopInFlowThread())
@@ -159,6 +179,7 @@
   // group can hold without overflowing.
   LayoutUnit FragmentainerGroupCapacity(
       const MultiColumnFragmentainerGroup& group) const {
+    CheckIsNotDestroyed();
     return group.ColumnLogicalHeight() * UsedColumnCount();
   }
 
@@ -167,6 +188,7 @@
   // The used CSS value of column-count, i.e. how many columns there are room
   // for without overflowing.
   unsigned UsedColumnCount() const {
+    CheckIsNotDestroyed();
     return MultiColumnFlowThread()->ColumnCount();
   }
 
@@ -191,8 +213,14 @@
   // Reset previously calculated column height. Will mark for layout if needed.
   void ResetColumnHeight();
 
-  void StoreOldPosition() { old_logical_top_ = LogicalTop(); }
-  bool IsInitialHeightCalculated() const { return initial_height_calculated_; }
+  void StoreOldPosition() {
+    CheckIsNotDestroyed();
+    old_logical_top_ = LogicalTop();
+  }
+  bool IsInitialHeightCalculated() const {
+    CheckIsNotDestroyed();
+    return initial_height_calculated_;
+  }
 
   // Layout of flow thread content that's to be rendered inside this column set
   // begins. This happens at the beginning of flow thread layout, and when
@@ -225,7 +253,10 @@
   // if any.
   unsigned ActualColumnCount() const;
 
-  const char* GetName() const override { return "LayoutMultiColumnSet"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutMultiColumnSet";
+  }
 
   // Sets |columnRuleBounds| to the bounds of each column rule rect's painted
   // extent, adjusted by paint offset, before pixel snapping. Returns true if
@@ -244,7 +275,10 @@
   void InsertedIntoTree() final;
   void WillBeRemovedFromTree() final;
 
-  bool IsSelfCollapsingBlock() const override { return false; }
+  bool IsSelfCollapsingBlock() const override {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   void ComputeLogicalHeight(LayoutUnit logical_height,
                             LayoutUnit logical_top,
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 10b19d7..d00ac6b 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
@@ -38,6 +38,7 @@
 
 void LayoutMultiColumnSpannerPlaceholder::
     LayoutObjectInFlowThreadStyleDidChange(const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutBox* object_in_flow_thread = layout_object_in_flow_thread_;
   if (FlowThread()->RemoveSpannerPlaceholderIfNoLongerValid(
           object_in_flow_thread)) {
@@ -61,6 +62,7 @@
 
 void LayoutMultiColumnSpannerPlaceholder::UpdateProperties(
     const ComputedStyle& parent_style) {
+  CheckIsNotDestroyed();
   scoped_refptr<ComputedStyle> new_style =
       ComputedStyle::CreateAnonymousStyleWithDisplay(parent_style,
                                                      EDisplay::kBlock);
@@ -69,6 +71,7 @@
 }
 
 void LayoutMultiColumnSpannerPlaceholder::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   LayoutBox::InsertedIntoTree();
   // The object may previously have been laid out as a non-spanner, but since
   // it's a spanner now, it needs to be relaid out.
@@ -77,6 +80,7 @@
 }
 
 void LayoutMultiColumnSpannerPlaceholder::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   if (layout_object_in_flow_thread_) {
     LayoutBox* ex_spanner = layout_object_in_flow_thread_;
     layout_object_in_flow_thread_->ClearSpannerPlaceholder();
@@ -91,10 +95,12 @@
 
 bool LayoutMultiColumnSpannerPlaceholder::NeedsPreferredWidthsRecalculation()
     const {
+  CheckIsNotDestroyed();
   return layout_object_in_flow_thread_->NeedsPreferredWidthsRecalculation();
 }
 
 void LayoutMultiColumnSpannerPlaceholder::RecalcVisualOverflow() {
+  CheckIsNotDestroyed();
   LayoutBox::RecalcVisualOverflow();
   ClearVisualOverflow();
   AddContentsVisualOverflow(
@@ -103,6 +109,7 @@
 
 MinMaxSizes LayoutMultiColumnSpannerPlaceholder::PreferredLogicalWidths()
     const {
+  CheckIsNotDestroyed();
   // There should be no contribution from a spanner if the multicol container is
   // size-contained. Normally we'd stop at the object that has contain:size
   // applied, but for multicol, we descend into the children, in order to get
@@ -116,6 +123,7 @@
 }
 
 void LayoutMultiColumnSpannerPlaceholder::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
 
   // The placeholder, like any other block level object, has its logical top
@@ -148,6 +156,7 @@
     LayoutUnit,
     LayoutUnit logical_top,
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   computed_values.extent_ = layout_object_in_flow_thread_->LogicalHeight();
   computed_values.position_ = logical_top;
   computed_values.margins_.before_ = MarginBefore();
@@ -156,6 +165,7 @@
 
 void LayoutMultiColumnSpannerPlaceholder::Paint(
     const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   if (!layout_object_in_flow_thread_->HasSelfPaintingLayer())
     layout_object_in_flow_thread_->Paint(paint_info);
 }
@@ -165,6 +175,7 @@
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& accumulated_offset,
     HitTestAction action) {
+  CheckIsNotDestroyed();
   return !layout_object_in_flow_thread_->HasSelfPaintingLayer() &&
          layout_object_in_flow_thread_->NodeAtPoint(result, hit_test_location,
                                                     accumulated_offset, action);
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 a2575a39..7b05321 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
@@ -18,6 +18,7 @@
 class LayoutMultiColumnSpannerPlaceholder final : public LayoutBox {
  public:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectLayoutMultiColumnSpannerPlaceholder ||
            LayoutBox::IsOfType(type);
   }
@@ -27,17 +28,21 @@
       LayoutBox&);
 
   LayoutBlockFlow* MultiColumnBlockFlow() const {
+    CheckIsNotDestroyed();
     return To<LayoutBlockFlow>(Parent());
   }
 
   LayoutMultiColumnFlowThread* FlowThread() const {
+    CheckIsNotDestroyed();
     return To<LayoutBlockFlow>(Parent())->MultiColumnFlowThread();
   }
 
   LayoutBox* LayoutObjectInFlowThread() const {
+    CheckIsNotDestroyed();
     return layout_object_in_flow_thread_;
   }
   void MarkForLayoutIfObjectInFlowThreadNeedsLayout() {
+    CheckIsNotDestroyed();
     if (!layout_object_in_flow_thread_->NeedsLayout())
       return;
     // The containing block of a spanner is the multicol container (our parent
@@ -46,12 +51,16 @@
     SetChildNeedsLayout(kMarkOnlyThis);
   }
 
-  bool AnonymousHasStylePropagationOverride() final { return true; }
+  bool AnonymousHasStylePropagationOverride() final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   void LayoutObjectInFlowThreadStyleDidChange(const ComputedStyle* old_style);
   void UpdateProperties(const ComputedStyle& parent_style);
 
   const char* GetName() const override {
+    CheckIsNotDestroyed();
     return "LayoutMultiColumnSpannerPlaceholder";
   }
 
@@ -75,6 +84,7 @@
   LayoutMultiColumnSpannerPlaceholder(LayoutBox*);
 
   MinMaxSizes ComputeIntrinsicLogicalWidths() const final {
+    CheckIsNotDestroyed();
     NOTREACHED();
     return MinMaxSizes();
   }
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index e9c34784..3d72aca 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -331,6 +331,7 @@
 }
 
 bool LayoutObject::IsDescendantOf(const LayoutObject* obj) const {
+  CheckIsNotDestroyed();
   for (const LayoutObject* r = this; r; r = r->parent_) {
     if (r == obj)
       return true;
@@ -339,10 +340,12 @@
 }
 
 bool LayoutObject::IsHR() const {
+  CheckIsNotDestroyed();
   return IsA<HTMLHRElement>(GetNode());
 }
 
 bool LayoutObject::IsStyleGenerated() const {
+  CheckIsNotDestroyed();
   if (const auto* layout_text_fragment = ToLayoutTextFragmentOrNull(this))
     return !layout_text_fragment->AssociatedTextNode();
 
@@ -352,6 +355,7 @@
 
 void LayoutObject::SetIsInsideFlowThreadIncludingDescendants(
     bool inside_flow_thread) {
+  CheckIsNotDestroyed();
   LayoutObject* next;
   for (LayoutObject* object = this; object; object = next) {
     // If object is a fragmentation context it already updated the descendants
@@ -368,6 +372,7 @@
 
 bool LayoutObject::RequiresAnonymousTableWrappers(
     const LayoutObject* new_child) const {
+  CheckIsNotDestroyed();
   // Check should agree with:
   // CSS 2.1 Tables: 17.2.1 Anonymous table objects
   // http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes
@@ -391,6 +396,7 @@
 #if DCHECK_IS_ON()
 
 void LayoutObject::AssertClearedPaintInvalidationFlags() const {
+  CheckIsNotDestroyed();
   if (!PaintInvalidationStateIsDirty() || ChildPrePaintBlockedByDisplayLock())
     return;
   // NG text objects are exempt, as pre-paint walking doesn't visit those with
@@ -408,6 +414,7 @@
 DISABLE_CFI_PERF
 void LayoutObject::AddChild(LayoutObject* new_child,
                             LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   DCHECK(IsAllowedToModifyLayoutTreeStructure(GetDocument()));
 
   LayoutObjectChildList* children = VirtualChildren();
@@ -440,6 +447,7 @@
 }
 
 void LayoutObject::RemoveChild(LayoutObject* old_child) {
+  CheckIsNotDestroyed();
   DCHECK(IsAllowedToModifyLayoutTreeStructure(GetDocument()));
 
   LayoutObjectChildList* children = VirtualChildren();
@@ -451,6 +459,7 @@
 }
 
 void LayoutObject::NotifyPriorityScrollAnchorStatusChanged() {
+  CheckIsNotDestroyed();
   if (!Parent())
     return;
   for (auto* layer = Parent()->EnclosingLayer(); layer;
@@ -464,6 +473,7 @@
 }
 
 void LayoutObject::RegisterSubtreeChangeListenerOnDescendants(bool value) {
+  CheckIsNotDestroyed();
   // If we're set to the same value then we're done as that means it's
   // set down the tree that way already.
   if (bitfields_.SubtreeChangeListenerRegistered() == value)
@@ -476,6 +486,7 @@
 }
 
 void LayoutObject::NotifyAncestorsOfSubtreeChange() {
+  CheckIsNotDestroyed();
   if (bitfields_.NotifiedOfSubtreeChange())
     return;
 
@@ -485,6 +496,7 @@
 }
 
 void LayoutObject::NotifyOfSubtreeChange() {
+  CheckIsNotDestroyed();
   if (!bitfields_.SubtreeChangeListenerRegistered())
     return;
   if (bitfields_.NotifiedOfSubtreeChange())
@@ -500,6 +512,7 @@
 }
 
 void LayoutObject::HandleSubtreeModifications() {
+  CheckIsNotDestroyed();
   DCHECK(WasNotifiedOfSubtreeChange());
   DCHECK(GetDocument().Lifecycle().StateAllowsLayoutTreeNotifications());
 
@@ -517,6 +530,7 @@
 }
 
 LayoutObject* LayoutObject::NextInPreOrder() const {
+  CheckIsNotDestroyed();
   if (LayoutObject* o = SlowFirstChild())
     return o;
 
@@ -524,6 +538,7 @@
 }
 
 bool LayoutObject::HasClipRelatedProperty() const {
+  CheckIsNotDestroyed();
   // This function detects a bunch of properties that can potentially affect
   // clip inheritance chain. However such generalization is practically useless
   // because these properties change clip inheritance in different way that
@@ -550,6 +565,7 @@
 }
 
 bool LayoutObject::IsRenderedLegendInternal() const {
+  CheckIsNotDestroyed();
   DCHECK(IsBox());
   DCHECK(IsRenderedLegendCandidate());
 
@@ -572,6 +588,7 @@
 }
 
 LayoutObject* LayoutObject::NextInPreOrderAfterChildren() const {
+  CheckIsNotDestroyed();
   LayoutObject* o = NextSibling();
   if (!o) {
     o = Parent();
@@ -586,6 +603,7 @@
 
 LayoutObject* LayoutObject::NextInPreOrder(
     const LayoutObject* stay_within) const {
+  CheckIsNotDestroyed();
   if (LayoutObject* o = SlowFirstChild())
     return o;
 
@@ -594,6 +612,7 @@
 
 LayoutObject* LayoutObject::PreviousInPostOrder(
     const LayoutObject* stay_within) const {
+  CheckIsNotDestroyed();
   if (LayoutObject* o = SlowLastChild())
     return o;
 
@@ -602,6 +621,7 @@
 
 LayoutObject* LayoutObject::NextInPreOrderAfterChildren(
     const LayoutObject* stay_within) const {
+  CheckIsNotDestroyed();
   if (this == stay_within)
     return nullptr;
 
@@ -617,6 +637,7 @@
 
 LayoutObject* LayoutObject::PreviousInPostOrderBeforeChildren(
     const LayoutObject* stay_within) const {
+  CheckIsNotDestroyed();
   if (this == stay_within)
     return nullptr;
 
@@ -631,6 +652,7 @@
 }
 
 LayoutObject* LayoutObject::PreviousInPreOrder() const {
+  CheckIsNotDestroyed();
   if (LayoutObject* o = PreviousSibling()) {
     while (LayoutObject* last_child = o->SlowLastChild())
       o = last_child;
@@ -642,6 +664,7 @@
 
 LayoutObject* LayoutObject::PreviousInPreOrder(
     const LayoutObject* stay_within) const {
+  CheckIsNotDestroyed();
   if (this == stay_within)
     return nullptr;
 
@@ -649,6 +672,7 @@
 }
 
 LayoutObject* LayoutObject::LastLeafChild() const {
+  CheckIsNotDestroyed();
   LayoutObject* r = SlowLastChild();
   while (r) {
     LayoutObject* n = nullptr;
@@ -683,6 +707,7 @@
 }
 
 void LayoutObject::AddLayers(PaintLayer* parent_layer) {
+  CheckIsNotDestroyed();
   if (!parent_layer)
     return;
 
@@ -692,6 +717,7 @@
 }
 
 void LayoutObject::RemoveLayers(PaintLayer* parent_layer) {
+  CheckIsNotDestroyed();
   if (!parent_layer)
     return;
 
@@ -705,6 +731,7 @@
 }
 
 void LayoutObject::MoveLayers(PaintLayer* old_parent, PaintLayer* new_parent) {
+  CheckIsNotDestroyed();
   if (!new_parent)
     return;
 
@@ -724,6 +751,7 @@
 PaintLayer* LayoutObject::FindNextLayer(PaintLayer* parent_layer,
                                         LayoutObject* start_point,
                                         bool check_parent) {
+  CheckIsNotDestroyed();
   // Error check the parent layer passed in. If it's null, we can't find
   // anything.
   if (!parent_layer)
@@ -764,6 +792,7 @@
 }
 
 PaintLayer* LayoutObject::EnclosingLayer() const {
+  CheckIsNotDestroyed();
   for (const LayoutObject* current = this; current;
        current = current->Parent()) {
     if (current->HasLayer())
@@ -775,6 +804,7 @@
 }
 
 PaintLayer* LayoutObject::PaintingLayer() const {
+  CheckIsNotDestroyed();
   auto FindContainer = [](const LayoutObject& object) -> const LayoutObject* {
     if (object.IsRenderedLegend())
       return LayoutFieldset::FindLegendContainingBlock(ToLayoutBox(object));
@@ -805,6 +835,7 @@
 }
 
 bool LayoutObject::IsFixedPositionObjectInPagedMedia() const {
+  CheckIsNotDestroyed();
   if (StyleRef().GetPosition() != EPosition::kFixed)
     return false;
   LayoutView* view = View();
@@ -817,6 +848,7 @@
 PhysicalRect LayoutObject::ScrollRectToVisible(
     const PhysicalRect& rect,
     mojom::blink::ScrollIntoViewParamsPtr params) {
+  CheckIsNotDestroyed();
   LayoutBox* enclosing_box = EnclosingBox();
   if (!enclosing_box)
     return rect;
@@ -834,6 +866,7 @@
 }
 
 LayoutBox* LayoutObject::EnclosingBox() const {
+  CheckIsNotDestroyed();
   LayoutObject* curr = const_cast<LayoutObject*>(this);
   while (curr) {
     if (curr->IsBox())
@@ -846,6 +879,7 @@
 }
 
 LayoutBlockFlow* LayoutObject::RootInlineFormattingContext() const {
+  CheckIsNotDestroyed();
   for (LayoutObject* parent = Parent(); parent; parent = parent->Parent()) {
     if (auto* block_flow = DynamicTo<LayoutBlockFlow>(parent)) {
       // Skip |LayoutFlowThread| because it is skipped when finding the first
@@ -859,6 +893,7 @@
 }
 
 LayoutBlockFlow* LayoutObject::FragmentItemsContainer() const {
+  CheckIsNotDestroyed();
   for (LayoutObject* parent = Parent(); parent; parent = parent->Parent()) {
     if (auto* block_flow = DynamicTo<LayoutBlockFlow>(parent))
       return block_flow;
@@ -867,6 +902,7 @@
 }
 
 LayoutBlockFlow* LayoutObject::ContainingNGBlockFlow() const {
+  CheckIsNotDestroyed();
   DCHECK(IsInline());
   if (!RuntimeEnabledFeatures::LayoutNGEnabled())
     return nullptr;
@@ -882,6 +918,7 @@
 }
 
 const NGPhysicalBoxFragment* LayoutObject::ContainingBlockFlowFragment() const {
+  CheckIsNotDestroyed();
   DCHECK(IsInline() || IsText());
   LayoutBlockFlow* const block_flow = ContainingNGBlockFlow();
   if (!block_flow || !block_flow->ChildrenInline())
@@ -892,12 +929,14 @@
 }
 
 bool LayoutObject::IsFirstInlineFragmentSafe() const {
+  CheckIsNotDestroyed();
   DCHECK(IsInline());
   LayoutBlockFlow* block_flow = ContainingNGBlockFlow();
   return block_flow && !block_flow->NeedsLayout();
 }
 
 LayoutBox* LayoutObject::EnclosingScrollableBox() const {
+  CheckIsNotDestroyed();
   for (LayoutObject* ancestor = Parent(); ancestor;
        ancestor = ancestor->Parent()) {
     if (!ancestor->IsBox())
@@ -912,6 +951,7 @@
 }
 
 LayoutFlowThread* LayoutObject::LocateFlowThreadContainingBlock() const {
+  CheckIsNotDestroyed();
   DCHECK(IsInsideFlowThread());
 
   // See if we have the thread cached because we're in the middle of layout.
@@ -1037,6 +1077,7 @@
 // |this|. When invalidating on inline blocks, floats, or OOF, caller need to
 // pay attention whether it should mark its inner context or outer.
 void LayoutObject::SetNeedsCollectInlines() {
+  CheckIsNotDestroyed();
   if (!RuntimeEnabledFeatures::LayoutNGEnabled())
     return;
 
@@ -1055,6 +1096,7 @@
 }
 
 void LayoutObject::SetChildNeedsCollectInlines() {
+  CheckIsNotDestroyed();
   if (!RuntimeEnabledFeatures::LayoutNGEnabled())
     return;
 
@@ -1082,6 +1124,7 @@
 
 void LayoutObject::MarkContainerChainForLayout(bool schedule_relayout,
                                                SubtreeLayoutScope* layouter) {
+  CheckIsNotDestroyed();
 #if DCHECK_IS_ON()
   DCHECK(!IsSetNeedsLayoutForbidden());
 #endif
@@ -1176,6 +1219,7 @@
 //    static-position, simply insert the object up the NGLayoutResult chain with
 //    an invalid static-position.
 void LayoutObject::MarkParentForOutOfFlowPositionedChange() {
+  CheckIsNotDestroyed();
 #if DCHECK_IS_ON()
   DCHECK(!IsSetNeedsLayoutForbidden());
 #endif
@@ -1202,6 +1246,7 @@
 
 #if DCHECK_IS_ON()
 void LayoutObject::CheckBlockPositionedObjectsNeedLayout() {
+  CheckIsNotDestroyed();
   if (ChildLayoutBlockedByDisplayLock())
     return;
   DCHECK(!NeedsLayout());
@@ -1214,6 +1259,7 @@
 
 void LayoutObject::SetIntrinsicLogicalWidthsDirty(
     MarkingBehavior mark_parents) {
+  CheckIsNotDestroyed();
   bitfields_.SetIntrinsicLogicalWidthsDirty(true);
   bitfields_.SetIntrinsicLogicalWidthsDependsOnPercentageBlockSize(true);
   bitfields_.SetIntrinsicLogicalWidthsChildDependsOnPercentageBlockSize(true);
@@ -1223,15 +1269,18 @@
 }
 
 void LayoutObject::ClearIntrinsicLogicalWidthsDirty() {
+  CheckIsNotDestroyed();
   bitfields_.SetIntrinsicLogicalWidthsDirty(false);
 }
 
 bool LayoutObject::IsFontFallbackValid() const {
+  CheckIsNotDestroyed();
   return StyleRef().GetFont().IsFallbackValid() &&
          FirstLineStyle()->GetFont().IsFallbackValid();
 }
 
 void LayoutObject::InvalidateSubtreeLayoutForFontUpdates() {
+  CheckIsNotDestroyed();
   if (!RuntimeEnabledFeatures::
           CSSReducedFontLoadingLayoutInvalidationsEnabled() ||
       !IsFontFallbackValid()) {
@@ -1245,6 +1294,7 @@
 }
 
 void LayoutObject::InvalidateIntersectionObserverCachedRects() {
+  CheckIsNotDestroyed();
   if (GetNode() && GetNode()->IsElementNode()) {
     if (auto* data = To<Element>(GetNode())->IntersectionObserverData()) {
       data->InvalidateCachedRects();
@@ -1269,6 +1319,7 @@
 }
 
 inline void LayoutObject::InvalidateContainerIntrinsicLogicalWidths() {
+  CheckIsNotDestroyed();
   // In order to avoid pathological behavior when inlines are deeply nested, we
   // do include them in the chain that we mark dirty (even though they're kind
   // of irrelevant).
@@ -1293,6 +1344,7 @@
 
 LayoutObject* LayoutObject::ContainerForAbsolutePosition(
     AncestorSkipInfo* skip_info) const {
+  CheckIsNotDestroyed();
   return FindAncestorByPredicate(this, skip_info, [](LayoutObject* candidate) {
     return candidate->CanContainAbsolutePositionObjects();
   });
@@ -1300,6 +1352,7 @@
 
 LayoutObject* LayoutObject::ContainerForFixedPosition(
     AncestorSkipInfo* skip_info) const {
+  CheckIsNotDestroyed();
   DCHECK(!IsText());
   return FindAncestorByPredicate(this, skip_info, [](LayoutObject* candidate) {
     return candidate->CanContainFixedPositionObjects();
@@ -1308,22 +1361,26 @@
 
 LayoutBlock* LayoutObject::ContainingBlockForAbsolutePosition(
     AncestorSkipInfo* skip_info) const {
+  CheckIsNotDestroyed();
   auto* container = ContainerForAbsolutePosition(skip_info);
   return FindNonAnonymousContainingBlock(container, skip_info);
 }
 
 LayoutBlock* LayoutObject::ContainingBlockForFixedPosition(
     AncestorSkipInfo* skip_info) const {
+  CheckIsNotDestroyed();
   auto* container = ContainerForFixedPosition(skip_info);
   return FindNonAnonymousContainingBlock(container, skip_info);
 }
 
 const LayoutBlock* LayoutObject::InclusiveContainingBlock() const {
+  CheckIsNotDestroyed();
   auto* layout_block = DynamicTo<LayoutBlock>(this);
   return layout_block ? layout_block : ContainingBlock();
 }
 
 LayoutBlock* LayoutObject::ContainingBlock(AncestorSkipInfo* skip_info) const {
+  CheckIsNotDestroyed();
   if (!IsTextOrSVGChild()) {
     if (style_->GetPosition() == EPosition::kFixed)
       return ContainingBlockForFixedPosition(skip_info);
@@ -1355,6 +1412,7 @@
 }
 
 LayoutObject* LayoutObject::NonAnonymousAncestor() const {
+  CheckIsNotDestroyed();
   LayoutObject* ancestor = Parent();
   while (ancestor && ancestor->IsAnonymous())
     ancestor = ancestor->Parent();
@@ -1380,6 +1438,7 @@
 }
 
 bool LayoutObject::ComputeIsFixedContainer(const ComputedStyle* style) const {
+  CheckIsNotDestroyed();
   if (!style)
     return false;
   bool is_document_element = IsDocumentElement();
@@ -1430,6 +1489,7 @@
 
 bool LayoutObject::ComputeIsAbsoluteContainer(
     const ComputedStyle* style) const {
+  CheckIsNotDestroyed();
   if (!style)
     return false;
   return style->CanContainAbsolutePositionObjects() ||
@@ -1438,6 +1498,7 @@
 
 FloatRect LayoutObject::AbsoluteBoundingBoxFloatRect(
     MapCoordinatesFlags flags) const {
+  CheckIsNotDestroyed();
   DCHECK(!(flags & kIgnoreTransforms));
   Vector<FloatQuad> quads;
   AbsoluteQuads(quads, flags);
@@ -1453,6 +1514,7 @@
 }
 
 IntRect LayoutObject::AbsoluteBoundingBoxRect(MapCoordinatesFlags flags) const {
+  CheckIsNotDestroyed();
   DCHECK(!(flags & kIgnoreTransforms));
   Vector<FloatQuad> quads;
   AbsoluteQuads(quads, flags);
@@ -1468,10 +1530,12 @@
 }
 
 PhysicalRect LayoutObject::AbsoluteBoundingBoxRectHandlingEmptyInline() const {
+  CheckIsNotDestroyed();
   return PhysicalRect::EnclosingRect(AbsoluteBoundingBoxFloatRect());
 }
 
 PhysicalRect LayoutObject::AbsoluteBoundingBoxRectForScrollIntoView() const {
+  CheckIsNotDestroyed();
   PhysicalRect rect = AbsoluteBoundingBoxRectHandlingEmptyInline();
   const auto& style = StyleRef();
   rect.ExpandEdges(LayoutUnit(style.ScrollMarginTop()),
@@ -1482,6 +1546,7 @@
 }
 
 void LayoutObject::AddAbsoluteRectForLayer(IntRect& result) {
+  CheckIsNotDestroyed();
   if (HasLayer())
     result.Unite(AbsoluteBoundingBoxRect());
   for (LayoutObject* current = SlowFirstChild(); current;
@@ -1490,6 +1555,7 @@
 }
 
 IntRect LayoutObject::AbsoluteBoundingBoxRectIncludingDescendants() const {
+  CheckIsNotDestroyed();
   IntRect result = AbsoluteBoundingBoxRect();
   for (LayoutObject* current = SlowFirstChild(); current;
        current = current->NextSibling())
@@ -1497,10 +1563,13 @@
   return result;
 }
 
-void LayoutObject::Paint(const PaintInfo&) const {}
+void LayoutObject::Paint(const PaintInfo&) const {
+  CheckIsNotDestroyed();
+}
 
 const LayoutBoxModelObject& LayoutObject::DirectlyCompositableContainer()
     const {
+  CheckIsNotDestroyed();
   CHECK(IsRooted());
 
   if (const LayoutBoxModelObject* container =
@@ -1520,6 +1589,7 @@
 
 const LayoutBoxModelObject*
 LayoutObject::EnclosingDirectlyCompositableContainer() const {
+  CheckIsNotDestroyed();
   DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
   LayoutBoxModelObject* container = nullptr;
   // FIXME: CompositingState is not necessarily up to date for many callers of
@@ -1536,6 +1606,7 @@
 }
 
 bool LayoutObject::RecalcLayoutOverflow() {
+  CheckIsNotDestroyed();
   if (!ChildNeedsLayoutOverflowRecalc())
     return false;
   ClearChildNeedsLayoutOverflowRecalc();
@@ -1549,6 +1620,7 @@
 }
 
 void LayoutObject::RecalcVisualOverflow() {
+  CheckIsNotDestroyed();
   for (LayoutObject* current = SlowFirstChild(); current;
        current = current->NextSibling()) {
     if (current->HasLayer() &&
@@ -1559,6 +1631,7 @@
 }
 
 void LayoutObject::RecalcNormalFlowChildVisualOverflowIfNeeded() {
+  CheckIsNotDestroyed();
   if (IsOutOfFlowPositioned() ||
       (HasLayer() && ToLayoutBoxModelObject(this)->HasSelfPaintingLayer()))
     return;
@@ -1566,6 +1639,7 @@
 }
 
 bool LayoutObject::HasDistortingVisualEffects() const {
+  CheckIsNotDestroyed();
   // TODO(szager): Check occlusion information propagated from out-of-process
   // parent frame.
 
@@ -1606,6 +1680,7 @@
 }
 
 bool LayoutObject::HasNonZeroEffectiveOpacity() const {
+  CheckIsNotDestroyed();
   const FragmentData& fragment =
       EnclosingLayer()->GetLayoutObject().FirstFragment();
 
@@ -1627,6 +1702,7 @@
 }
 
 String LayoutObject::DecoratedName() const {
+  CheckIsNotDestroyed();
   StringBuilder name;
   name.Append(GetName());
 
@@ -1649,6 +1725,7 @@
 }
 
 String LayoutObject::DebugName() const {
+  CheckIsNotDestroyed();
   StringBuilder name;
   name.Append(DecoratedName());
 
@@ -1660,15 +1737,18 @@
 }
 
 DOMNodeId LayoutObject::OwnerNodeId() const {
+  CheckIsNotDestroyed();
   return GetNode() ? DOMNodeIds::IdForNode(GetNode()) : kInvalidDOMNodeId;
 }
 
 bool LayoutObject::IsPaintInvalidationContainer() const {
+  CheckIsNotDestroyed();
   return HasLayer() &&
          ToLayoutBoxModelObject(this)->Layer()->IsPaintInvalidationContainer();
 }
 
 bool LayoutObject::CanBeCompositedForDirectReasons() const {
+  CheckIsNotDestroyed();
   return HasLayer() && ToLayoutBoxModelObject(this)
                            ->Layer()
                            ->CanBeCompositedForDirectReasons();
@@ -1676,6 +1756,7 @@
 
 void LayoutObject::InvalidateDisplayItemClients(
     PaintInvalidationReason reason) const {
+  CheckIsNotDestroyed();
   // This default implementation invalidates only the object itself as a
   // DisplayItemClient.
   DCHECK(!GetSelectionDisplayItemClient());
@@ -1684,11 +1765,13 @@
 
 bool LayoutObject::CompositedScrollsWithRespectTo(
     const LayoutBoxModelObject& paint_invalidation_container) const {
+  CheckIsNotDestroyed();
   return paint_invalidation_container.UsesCompositedScrolling() &&
          this != &paint_invalidation_container;
 }
 
 PhysicalRect LayoutObject::AbsoluteSelectionRect() const {
+  CheckIsNotDestroyed();
   PhysicalRect selection_rect = LocalSelectionVisualRect();
   if (!selection_rect.IsEmpty())
     MapToVisualRectInAncestorSpace(View(), selection_rect);
@@ -1702,16 +1785,19 @@
 DISABLE_CFI_PERF
 void LayoutObject::InvalidatePaint(
     const PaintInvalidatorContext& context) const {
+  CheckIsNotDestroyed();
   ObjectPaintInvalidatorWithContext(*this, context).InvalidatePaint();
 }
 
 PhysicalRect LayoutObject::VisualRectInDocument(VisualRectFlags flags) const {
+  CheckIsNotDestroyed();
   PhysicalRect rect = LocalVisualRect();
   MapToVisualRectInAncestorSpace(View(), rect, flags);
   return rect;
 }
 
 PhysicalRect LayoutObject::LocalVisualRectIgnoringVisibility() const {
+  CheckIsNotDestroyed();
   NOTREACHED();
   return PhysicalRect();
 }
@@ -1721,6 +1807,7 @@
     PhysicalRect& rect,
     VisualRectFlags visual_rect_flags,
     bool& intersects) const {
+  CheckIsNotDestroyed();
   intersects = true;
   if (!(visual_rect_flags & kUseGeometryMapper) || !ancestor ||
       !ancestor->FirstFragment().HasLocalBorderBoxProperties())
@@ -1760,6 +1847,7 @@
     const LayoutBoxModelObject* ancestor,
     PhysicalRect& rect,
     VisualRectFlags visual_rect_flags) const {
+  CheckIsNotDestroyed();
   bool intersects = true;
   if (MapToVisualRectInAncestorSpaceInternalFastPath(
           ancestor, rect, visual_rect_flags, intersects))
@@ -1779,6 +1867,7 @@
     const LayoutBoxModelObject* ancestor,
     TransformState& transform_state,
     VisualRectFlags visual_rect_flags) const {
+  CheckIsNotDestroyed();
   // For any layout object that doesn't override this method (the main example
   // is LayoutText), the rect is assumed to be in the parent's coordinate space,
   // except for container flip.
@@ -1807,6 +1896,7 @@
 const LayoutObject* LayoutObject::GetPropertyContainer(
     AncestorSkipInfo* skip_info,
     PropertyTreeStateOrAlias* container_properties) const {
+  CheckIsNotDestroyed();
   const LayoutObject* property_container = this;
   while (!property_container->FirstFragment().HasLocalBorderBoxProperties()) {
     property_container = property_container->Container(skip_info);
@@ -1827,6 +1917,7 @@
 
 HitTestResult LayoutObject::HitTestForOcclusion(
     const PhysicalRect& hit_rect) const {
+  CheckIsNotDestroyed();
   LocalFrame* frame = GetDocument().GetFrame();
   DCHECK(!frame->View()->NeedsLayout());
   HitTestRequest::HitTestRequestType hit_type =
@@ -1839,7 +1930,9 @@
                                                           this, true);
 }
 
-void LayoutObject::DirtyLinesFromChangedChild(LayoutObject*, MarkingBehavior) {}
+void LayoutObject::DirtyLinesFromChangedChild(LayoutObject*, MarkingBehavior) {
+  CheckIsNotDestroyed();
+}
 
 std::ostream& operator<<(std::ostream& out, const LayoutObject& object) {
   String info;
@@ -1862,15 +1955,18 @@
 #if DCHECK_IS_ON()
 
 void LayoutObject::ShowTreeForThis() const {
+  CheckIsNotDestroyed();
   if (GetNode())
     ::showTree(GetNode());
 }
 
 void LayoutObject::ShowLayoutTreeForThis() const {
+  CheckIsNotDestroyed();
   showLayoutTree(this, nullptr);
 }
 
 void LayoutObject::ShowLineTreeForThis() const {
+  CheckIsNotDestroyed();
   if (const LayoutBlock* cb = InclusiveContainingBlock()) {
     auto* child_block_flow = DynamicTo<LayoutBlockFlow>(cb);
     if (child_block_flow) {
@@ -1881,6 +1977,7 @@
 }
 
 void LayoutObject::ShowLayoutObject() const {
+  CheckIsNotDestroyed();
   StringBuilder string_builder;
   DumpLayoutObject(string_builder, true, kShowTreeCharacterOffset);
   DLOG(INFO) << "\n" << string_builder.ToString().Utf8();
@@ -1889,6 +1986,7 @@
 void LayoutObject::DumpLayoutObject(StringBuilder& string_builder,
                                     bool dump_address,
                                     unsigned show_tree_character_offset) const {
+  CheckIsNotDestroyed();
   string_builder.Append(DecoratedName());
 
   if (dump_address)
@@ -1918,6 +2016,7 @@
                                          const LayoutObject* marked_object2,
                                          const char* marked_label2,
                                          unsigned depth) const {
+  CheckIsNotDestroyed();
   StringBuilder object_info;
   if (marked_object1 == this && marked_label1)
     object_info.Append(marked_label1);
@@ -1943,6 +2042,7 @@
 #endif  // DCHECK_IS_ON()
 
 bool LayoutObject::IsSelected() const {
+  CheckIsNotDestroyed();
   // Keep this fast and small, used in very hot functions to skip computing
   // selection when this is not selected. This function may be inlined in
   // link-optimized builds, but keeping fast and small helps running perf
@@ -1955,12 +2055,14 @@
 }
 
 bool LayoutObject::IsSelectable() const {
+  CheckIsNotDestroyed();
   return !IsInert() && !(StyleRef().UserSelect() == EUserSelect::kNone &&
                          StyleRef().UserModify() == EUserModify::kReadOnly);
 }
 
 const ComputedStyle& LayoutObject::SlowEffectiveStyle(
     NGStyleVariant style_variant) const {
+  CheckIsNotDestroyed();
   switch (style_variant) {
     case NGStyleVariant::kStandard:
       return StyleRef();
@@ -2004,6 +2106,7 @@
 
 StyleDifference LayoutObject::AdjustStyleDifference(
     StyleDifference diff) const {
+  CheckIsNotDestroyed();
   if (diff.TransformChanged() && IsSVG()) {
     // Skip a full layout for transforms at the html/svg boundary which do not
     // affect sizes inside SVG.
@@ -2052,6 +2155,7 @@
 
 void LayoutObject::SetPseudoElementStyle(
     scoped_refptr<const ComputedStyle> pseudo_style) {
+  CheckIsNotDestroyed();
   DCHECK(pseudo_style->StyleType() == kPseudoIdBefore ||
          pseudo_style->StyleType() == kPseudoIdAfter ||
          pseudo_style->StyleType() == kPseudoIdMarker ||
@@ -2079,6 +2183,7 @@
 
 void LayoutObject::MarkContainerChainForOverflowRecalcIfNeeded(
     bool mark_container_chain_layout_overflow_recalc) {
+  CheckIsNotDestroyed();
   LayoutObject* object = this;
   do {
     // Cell and row need to propagate the flag to their containing section and
@@ -2115,6 +2220,7 @@
 
 void LayoutObject::SetNeedsOverflowRecalc(
     OverflowRecalcType overflow_recalc_type) {
+  CheckIsNotDestroyed();
   bool mark_container_chain_layout_overflow_recalc =
       !SelfNeedsLayoutOverflowRecalc();
 
@@ -2140,6 +2246,7 @@
 DISABLE_CFI_PERF
 void LayoutObject::SetStyle(scoped_refptr<const ComputedStyle> style,
                             ApplyStyleChanges apply_changes) {
+  CheckIsNotDestroyed();
   if (style_ == style)
     return;
 
@@ -2212,11 +2319,11 @@
 
   if (diff.NeedsRecomputeVisualOverflow()) {
     if (!IsLayoutNGObject() && !IsLayoutBlock() && !NeedsLayout()) {
-      // TODO(rego): This is still needed because RecalcVisualOverflow() does
-      // not actually compute the visual overflow for inline elements (legacy
-      // layout). However in LayoutNG RecalcInlineChildrenInkOverflow() is
-      // called and visual overflow is recomputed properly so we don't need this
-      // (see crbug.com/1043927).
+      // TODO(crbug.com/1128199): This is still needed because
+      // RecalcVisualOverflow() does not actually compute the visual overflow
+      // for inline elements (legacy layout). However in LayoutNG
+      // RecalcInlineChildrenInkOverflow() is called and visual overflow is
+      // recomputed properly so we don't need this (see crbug.com/1043927).
       SetNeedsLayoutAndIntrinsicWidthsRecalc(
           layout_invalidation_reason::kStyleChange);
     } else {
@@ -2261,6 +2368,7 @@
 
 void LayoutObject::UpdateImageObservers(const ComputedStyle* old_style,
                                         const ComputedStyle* new_style) {
+  CheckIsNotDestroyed();
   DCHECK(old_style || new_style);
   DCHECK(!IsText());
 
@@ -2306,6 +2414,7 @@
 
 void LayoutObject::UpdateFirstLineImageObservers(
     const ComputedStyle* new_style) {
+  CheckIsNotDestroyed();
   bool has_new_first_line_style =
       new_style && new_style->HasPseudoElementStyle(kPseudoIdFirstLine) &&
       BehavesLikeBlockContainer();
@@ -2361,6 +2470,7 @@
 
 void LayoutObject::StyleWillChange(StyleDifference diff,
                                    const ComputedStyle& new_style) {
+  CheckIsNotDestroyed();
   if (style_) {
     bool visibility_changed = style_->Visibility() != new_style.Visibility();
     // If our z-index changes value or our visibility changes,
@@ -2475,6 +2585,7 @@
 }
 
 void LayoutObject::ClearBaseComputedStyle() {
+  CheckIsNotDestroyed();
   auto* element = DynamicTo<Element>(GetNode());
   if (!element)
     return;
@@ -2496,6 +2607,7 @@
 }
 
 void LayoutObject::SetScrollAnchorDisablingStyleChangedOnAncestor() {
+  CheckIsNotDestroyed();
   // Walk up the parent chain and find the first scrolling block to disable
   // scroll anchoring on.
   LayoutObject* object = Parent();
@@ -2529,6 +2641,7 @@
 
 void LayoutObject::StyleDidChange(StyleDifference diff,
                                   const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   if (style_->TransformStyle3D() == ETransformStyle3D::kPreserve3d) {
     if (style_->HasNonInitialBackdropFilter() || style_->HasBlendMode() ||
         !style_->HasAutoClip() || style_->ClipPath() ||
@@ -2633,6 +2746,7 @@
 
 void LayoutObject::ApplyPseudoElementStyleChanges(
     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   ApplyFirstLineChanges(old_style);
 
   if ((old_style && old_style->HasPseudoElementStyle(kPseudoIdSelection)) ||
@@ -2641,6 +2755,7 @@
 }
 
 void LayoutObject::ApplyFirstLineChanges(const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   bool has_old_first_line_style =
       old_style && old_style->HasPseudoElementStyle(kPseudoIdFirstLine);
   bool has_new_first_line_style =
@@ -2681,6 +2796,7 @@
 }
 
 void LayoutObject::PropagateStyleToAnonymousChildren() {
+  CheckIsNotDestroyed();
   // FIXME: We could save this call when the change only affected non-inherited
   // properties.
   for (LayoutObject* child = SlowFirstChild(); child;
@@ -2741,6 +2857,7 @@
 }
 
 void LayoutObject::AddAsImageObserver(StyleImage* image) {
+  CheckIsNotDestroyed();
   if (!image)
     return;
 #if DCHECK_IS_ON()
@@ -2750,6 +2867,7 @@
 }
 
 void LayoutObject::RemoveAsImageObserver(StyleImage* image) {
+  CheckIsNotDestroyed();
   if (!image)
     return;
 #if DCHECK_IS_ON()
@@ -2761,6 +2879,7 @@
 
 void LayoutObject::UpdateFillImages(const FillLayer* old_layers,
                                     const FillLayer* new_layers) {
+  CheckIsNotDestroyed();
   // Optimize the common case
   if (FillLayer::ImagesIdentical(old_layers, new_layers))
     return;
@@ -2778,6 +2897,7 @@
 
 void LayoutObject::UpdateCursorImages(const CursorList* old_cursors,
                                       const CursorList* new_cursors) {
+  CheckIsNotDestroyed();
   if (old_cursors && new_cursors && *old_cursors == *new_cursors)
     return;
 
@@ -2792,6 +2912,7 @@
 }
 
 void LayoutObject::UpdateImage(StyleImage* old_image, StyleImage* new_image) {
+  CheckIsNotDestroyed();
   if (old_image != new_image) {
     // AddAsImageObserver first, to avoid removing all clients of an image.
     AddAsImageObserver(new_image);
@@ -2801,6 +2922,7 @@
 
 void LayoutObject::UpdateShapeImage(const ShapeValue* old_shape_value,
                                     const ShapeValue* new_shape_value) {
+  CheckIsNotDestroyed();
   if (old_shape_value || new_shape_value) {
     UpdateImage(old_shape_value ? old_shape_value->GetImage() : nullptr,
                 new_shape_value ? new_shape_value->GetImage() : nullptr);
@@ -2809,6 +2931,7 @@
 
 void LayoutObject::CheckCounterChanges(const ComputedStyle* old_style,
                                        const ComputedStyle* new_style) {
+  CheckIsNotDestroyed();
   DCHECK(new_style);
   if (old_style) {
     if (old_style->CounterDirectivesEqual(*new_style))
@@ -2822,6 +2945,7 @@
 }
 
 PhysicalRect LayoutObject::ViewRect() const {
+  CheckIsNotDestroyed();
   return View()->ViewRect();
 }
 
@@ -2829,6 +2953,7 @@
     const LayoutBoxModelObject* ancestor,
     const FloatPoint& container_point,
     MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   TransformState transform_state(
       TransformState::kUnapplyInverseTransformDirection, container_point);
   MapAncestorToLocal(ancestor, transform_state, mode);
@@ -2841,6 +2966,7 @@
     const LayoutBoxModelObject* ancestor,
     const FloatQuad& quad,
     MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   TransformState transform_state(
       TransformState::kUnapplyInverseTransformDirection,
       quad.BoundingBox().Center(), quad);
@@ -2852,6 +2978,7 @@
 void LayoutObject::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                                       TransformState& transform_state,
                                       MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   if (ancestor == this)
     return;
 
@@ -2919,6 +3046,7 @@
 const LayoutObject* LayoutObject::PushMappingToContainer(
     const LayoutBoxModelObject* ancestor_to_stop_at,
     LayoutGeometryMap& geometry_map) const {
+  CheckIsNotDestroyed();
   NOTREACHED();
   return nullptr;
 }
@@ -2926,6 +3054,7 @@
 void LayoutObject::MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
                                       TransformState& transform_state,
                                       MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   if (this == ancestor)
     return;
 
@@ -2979,6 +3108,7 @@
 
 bool LayoutObject::ShouldUseTransformFromContainer(
     const LayoutObject* container_object) const {
+  CheckIsNotDestroyed();
   // hasTransform() indicates whether the object has transform, transform-style
   // or perspective. We just care about transform, so check the layer's
   // transform directly.
@@ -2990,6 +3120,7 @@
     const LayoutObject* container_object,
     const PhysicalOffset& offset_in_container,
     TransformationMatrix& transform) const {
+  CheckIsNotDestroyed();
   transform.MakeIdentity();
   PaintLayer* layer =
       HasLayer() ? ToLayoutBoxModelObject(this)->Layer() : nullptr;
@@ -3025,6 +3156,7 @@
     const FloatPoint& local_point,
     const LayoutBoxModelObject* ancestor,
     MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   TransformState transform_state(TransformState::kApplyTransformDirection,
                                  local_point);
   MapLocalToAncestor(ancestor, transform_state, mode);
@@ -3038,6 +3170,7 @@
     const LayoutBoxModelObject* ancestor,
     MapCoordinatesFlags mode,
     PhysicalRect& result) const {
+  CheckIsNotDestroyed();
   if (!(mode & kUseGeometryMapperMode))
     return false;
   // No other modes are supported.
@@ -3083,6 +3216,7 @@
     const PhysicalRect& rect,
     const LayoutBoxModelObject* ancestor,
     MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   PhysicalRect result;
   if (LocalToAncestorRectFastPath(rect, ancestor, mode, result))
     return result;
@@ -3095,6 +3229,7 @@
     const FloatQuad& local_quad,
     const LayoutBoxModelObject* ancestor,
     MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   // Track the point at the center of the quad's bounding box. As
   // MapLocalToAncestor() calls OffsetFromContainer(), it will use that point
   // as the reference point to decide which column's transform to apply in
@@ -3112,6 +3247,7 @@
     const LayoutBoxModelObject* ancestor,
     const PhysicalOffset& pre_offset,
     const PhysicalOffset& post_offset) const {
+  CheckIsNotDestroyed();
   for (wtf_size_t i = 0; i < rects.size(); ++i) {
     PhysicalRect& rect = rects[i];
     rect.Move(pre_offset);
@@ -3131,6 +3267,7 @@
 TransformationMatrix LayoutObject::LocalToAncestorTransform(
     const LayoutBoxModelObject* ancestor,
     MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   DCHECK(!(mode & kIgnoreTransforms));
   TransformState transform_state(TransformState::kApplyTransformDirection);
   MapLocalToAncestor(ancestor, transform_state, mode);
@@ -3140,12 +3277,14 @@
 PhysicalOffset LayoutObject::OffsetFromContainer(
     const LayoutObject* o,
     bool ignore_scroll_offset) const {
+  CheckIsNotDestroyed();
   return OffsetFromContainerInternal(o, ignore_scroll_offset);
 }
 
 PhysicalOffset LayoutObject::OffsetFromContainerInternal(
     const LayoutObject* o,
     bool ignore_scroll_offset) const {
+  CheckIsNotDestroyed();
   DCHECK_EQ(o, Container());
   return o->HasNonVisibleOverflow()
              ? OffsetFromScrollableContainer(o, ignore_scroll_offset)
@@ -3155,6 +3294,7 @@
 PhysicalOffset LayoutObject::OffsetFromScrollableContainer(
     const LayoutObject* container,
     bool ignore_scroll_offset) const {
+  CheckIsNotDestroyed();
   DCHECK(container->HasNonVisibleOverflow());
   const LayoutBox* box = ToLayoutBox(container);
   if (!ignore_scroll_offset)
@@ -3167,6 +3307,7 @@
 
 PhysicalOffset LayoutObject::OffsetFromAncestor(
     const LayoutObject* ancestor_container) const {
+  CheckIsNotDestroyed();
   if (ancestor_container == this)
     return PhysicalOffset();
 
@@ -3201,6 +3342,7 @@
     const InlineBox*,
     int,
     LayoutUnit* extra_width_to_end_of_line) const {
+  CheckIsNotDestroyed();
   if (extra_width_to_end_of_line)
     *extra_width_to_end_of_line = LayoutUnit();
 
@@ -3208,6 +3350,7 @@
 }
 
 bool LayoutObject::IsRooted() const {
+  CheckIsNotDestroyed();
   const LayoutObject* object = this;
   while (object->Parent() && !object->HasLayer())
     object = object->Parent();
@@ -3227,6 +3370,7 @@
 }
 
 LayoutObject* LayoutObject::Container(AncestorSkipInfo* skip_info) const {
+  CheckIsNotDestroyed();
   // TODO(mstensho): Get rid of this. Nobody should call this method with those
   // flags already set.
   if (skip_info)
@@ -3263,12 +3407,14 @@
 }
 
 inline LayoutObject* LayoutObject::ParentCrossingFrames() const {
+  CheckIsNotDestroyed();
   if (IsA<LayoutView>(this))
     return GetFrame()->OwnerLayoutObject();
   return Parent();
 }
 
 inline void LayoutObject::ClearLayoutRootIfNeeded() const {
+  CheckIsNotDestroyed();
   if (LocalFrameView* view = GetFrameView()) {
     if (!DocumentBeingDestroyed())
       view->ClearLayoutSubtreeRoot(*this);
@@ -3276,6 +3422,7 @@
 }
 
 void LayoutObject::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   // Destroy any leftover anonymous children.
   LayoutObjectChildList* children = VirtualChildren();
   if (children)
@@ -3344,6 +3491,7 @@
 
 DISABLE_CFI_PERF
 void LayoutObject::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   // FIXME: We should DCHECK(isRooted()) here but generated content makes some
   // out-of-order insertion.
 
@@ -3407,6 +3555,7 @@
 }
 
 void LayoutObject::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   // FIXME: We should DCHECK(isRooted()) but we have some out-of-order removals
   // which would need to be fixed first.
 
@@ -3448,11 +3597,13 @@
 }
 
 void LayoutObject::SetNeedsPaintPropertyUpdate() {
+  CheckIsNotDestroyed();
   SetNeedsPaintPropertyUpdatePreservingCachedRects();
   InvalidateIntersectionObserverCachedRects();
 }
 
 void LayoutObject::SetNeedsPaintPropertyUpdatePreservingCachedRects() {
+  CheckIsNotDestroyed();
   if (bitfields_.NeedsPaintPropertyUpdate())
     return;
 
@@ -3472,6 +3623,7 @@
 }
 
 void LayoutObject::SetAncestorsNeedPaintPropertyUpdateForMainThreadScrolling() {
+  CheckIsNotDestroyed();
   LayoutObject* ancestor = ParentCrossingFrames();
   while (ancestor) {
     ancestor->SetNeedsPaintPropertyUpdate();
@@ -3480,6 +3632,7 @@
 }
 
 void LayoutObject::MaybeClearIsScrollAnchorObject() {
+  CheckIsNotDestroyed();
   if (!bitfields_.IsScrollAnchorObject())
     return;
   bitfields_.SetIsScrollAnchorObject(
@@ -3487,6 +3640,7 @@
 }
 
 void LayoutObject::RemoveFromLayoutFlowThread() {
+  CheckIsNotDestroyed();
   if (!IsInsideFlowThread())
     return;
 
@@ -3510,6 +3664,7 @@
 
 void LayoutObject::RemoveFromLayoutFlowThreadRecursive(
     LayoutFlowThread* layout_flow_thread) {
+  CheckIsNotDestroyed();
   if (const LayoutObjectChildList* children = VirtualChildren()) {
     for (LayoutObject* child = children->FirstChild(); child;
          child = child->NextSibling()) {
@@ -3528,6 +3683,7 @@
 }
 
 void LayoutObject::DestroyAndCleanupAnonymousWrappers() {
+  CheckIsNotDestroyed();
   // If the tree is destroyed, there is no need for a clean-up phase.
   if (DocumentBeingDestroyed()) {
     Destroy();
@@ -3579,6 +3735,7 @@
 }
 
 void LayoutObject::Destroy() {
+  CheckIsNotDestroyed();
   CHECK(g_allow_destroying_layout_object_in_finalizer ||
         !ThreadState::Current()->InAtomicSweepingPause());
 
@@ -3590,25 +3747,30 @@
 }
 
 void LayoutObject::DeleteThis() {
+  CheckIsNotDestroyed();
   delete this;
 }
 
 PositionWithAffinity LayoutObject::PositionForPoint(
     const PhysicalOffset&) const {
+  CheckIsNotDestroyed();
   return CreatePositionWithAffinity(CaretMinOffset());
 }
 
 CompositingState LayoutObject::GetCompositingState() const {
+  CheckIsNotDestroyed();
   return HasLayer()
              ? ToLayoutBoxModelObject(this)->Layer()->GetCompositingState()
              : kNotComposited;
 }
 
 bool LayoutObject::CanHaveAdditionalCompositingReasons() const {
+  CheckIsNotDestroyed();
   return false;
 }
 
 CompositingReasons LayoutObject::AdditionalCompositingReasons() const {
+  CheckIsNotDestroyed();
   return CompositingReason::kNone;
 }
 
@@ -3616,6 +3778,7 @@
                                     const HitTestLocation& hit_test_location,
                                     const PhysicalOffset& accumulated_offset,
                                     HitTestFilter hit_test_filter) {
+  CheckIsNotDestroyed();
   bool inside = false;
   if (hit_test_filter != kHitTestSelf) {
     // First test the foreground layer (lines and inlines).
@@ -3643,6 +3806,7 @@
 }
 
 Node* LayoutObject::NodeForHitTest() const {
+  CheckIsNotDestroyed();
   if (Node* node = GetNode())
     return node;
 
@@ -3663,6 +3827,7 @@
 
 void LayoutObject::UpdateHitTestResult(HitTestResult& result,
                                        const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   if (result.InnerNode())
     return;
 
@@ -3674,10 +3839,12 @@
                                const HitTestLocation&,
                                const PhysicalOffset&,
                                HitTestAction) {
+  CheckIsNotDestroyed();
   return false;
 }
 
 void LayoutObject::ScheduleRelayout() {
+  CheckIsNotDestroyed();
   if (auto* layout_view = DynamicTo<LayoutView>(this)) {
     if (LocalFrameView* view = layout_view->GetFrameView())
       view->ScheduleRelayout();
@@ -3692,11 +3859,13 @@
 }
 
 void LayoutObject::ForceLayout() {
+  CheckIsNotDestroyed();
   SetSelfNeedsLayoutForAvailableSpace(true);
   UpdateLayout();
 }
 
 const ComputedStyle* LayoutObject::FirstLineStyleWithoutFallback() const {
+  CheckIsNotDestroyed();
   DCHECK(GetDocument().GetStyleEngine().UsesFirstLineRules());
 
   // Normal markers don't use ::first-line styles in Chromium, so be consistent
@@ -3756,6 +3925,7 @@
 
 const ComputedStyle* LayoutObject::GetCachedPseudoElementStyle(
     PseudoId pseudo) const {
+  CheckIsNotDestroyed();
   DCHECK_NE(pseudo, kPseudoIdBefore);
   DCHECK_NE(pseudo, kPseudoIdAfter);
   if (!GetNode())
@@ -3772,6 +3942,7 @@
 scoped_refptr<ComputedStyle> LayoutObject::GetUncachedPseudoElementStyle(
     const PseudoElementStyleRequest& request,
     const ComputedStyle* parent_style) const {
+  CheckIsNotDestroyed();
   DCHECK_NE(request.pseudo_id, kPseudoIdBefore);
   DCHECK_NE(request.pseudo_id, kPseudoIdAfter);
   if (!GetNode())
@@ -3787,6 +3958,7 @@
 }
 
 void LayoutObject::AddAnnotatedRegions(Vector<AnnotatedRegionValue>& regions) {
+  CheckIsNotDestroyed();
   // Convert the style regions to absolute coordinates.
   if (StyleRef().Visibility() != EVisibility::kVisible || !IsBox())
     return;
@@ -3806,6 +3978,7 @@
 }
 
 bool LayoutObject::WillRenderImage() {
+  CheckIsNotDestroyed();
   // Without visibility we won't render (and therefore don't care about
   // animation).
   if (StyleRef().Visibility() != EVisibility::kVisible)
@@ -3826,6 +3999,7 @@
 
 bool LayoutObject::GetImageAnimationPolicy(
     web_pref::ImageAnimationPolicy& policy) {
+  CheckIsNotDestroyed();
   if (!GetDocument().GetSettings())
     return false;
   policy = GetDocument().GetSettings()->GetImageAnimationPolicy();
@@ -3833,22 +4007,26 @@
 }
 
 bool LayoutObject::IsInsideListMarker() const {
+  CheckIsNotDestroyed();
   return (IsListMarkerForNormalContent() &&
           ToLayoutListMarker(this)->IsInside()) ||
          IsInsideListMarkerForCustomContent();
 }
 
 bool LayoutObject::IsOutsideListMarker() const {
+  CheckIsNotDestroyed();
   return (IsListMarkerForNormalContent() &&
           !ToLayoutListMarker(this)->IsInside()) ||
          IsOutsideListMarkerForCustomContent();
 }
 
 int LayoutObject::CaretMinOffset() const {
+  CheckIsNotDestroyed();
   return 0;
 }
 
 int LayoutObject::CaretMaxOffset() const {
+  CheckIsNotDestroyed();
   if (IsAtomicInlineLevel())
     return GetNode() ? std::max(1U, GetNode()->CountChildren()) : 1;
   if (IsHR())
@@ -3857,6 +4035,7 @@
 }
 
 bool LayoutObject::IsInert() const {
+  CheckIsNotDestroyed();
   const LayoutObject* layout_object = this;
   while (!layout_object->GetNode())
     layout_object = layout_object->Parent();
@@ -3865,6 +4044,7 @@
 
 void LayoutObject::ImageChanged(ImageResourceContent* image,
                                 CanDeferInvalidation defer) {
+  CheckIsNotDestroyed();
   DCHECK(node_);
 
   // Image change notifications should not be received during paint because
@@ -3877,6 +4057,7 @@
 }
 
 void LayoutObject::ImageNotifyFinished(ImageResourceContent* image) {
+  CheckIsNotDestroyed();
   if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
     cache->ImageLoaded(this);
 
@@ -3887,6 +4068,7 @@
 }
 
 Element* LayoutObject::OffsetParent(const Element* base) const {
+  CheckIsNotDestroyed();
   if (IsDocumentElement() || IsBody())
     return nullptr;
 
@@ -3936,6 +4118,7 @@
 }
 
 void LayoutObject::NotifyImageFullyRemoved(ImageResourceContent* image) {
+  CheckIsNotDestroyed();
   if (LocalDOMWindow* window = GetDocument().domWindow())
     ImageElementTiming::From(*window).NotifyImageRemoved(this, image);
   if (LocalFrameView* frame_view = GetFrameView())
@@ -3945,6 +4128,7 @@
 PositionWithAffinity LayoutObject::CreatePositionWithAffinity(
     int offset,
     TextAffinity affinity) const {
+  CheckIsNotDestroyed();
   // If this is a non-anonymous layoutObject in an editable area, then it's
   // simple.
   if (Node* node = NonPseudoNode()) {
@@ -4007,11 +4191,13 @@
 
 PositionWithAffinity LayoutObject::CreatePositionWithAffinity(
     int offset) const {
+  CheckIsNotDestroyed();
   return CreatePositionWithAffinity(offset, TextAffinity::kDownstream);
 }
 
 PositionWithAffinity LayoutObject::CreatePositionWithAffinity(
     const Position& position) const {
+  CheckIsNotDestroyed();
   if (position.IsNotNull())
     return PositionWithAffinity(position);
 
@@ -4021,10 +4207,12 @@
 
 CursorDirective LayoutObject::GetCursor(const PhysicalOffset&,
                                         ui::Cursor&) const {
+  CheckIsNotDestroyed();
   return kSetCursorBasedOnStyle;
 }
 
 bool LayoutObject::CanUpdateSelectionOnRootLineBoxes() const {
+  CheckIsNotDestroyed();
   if (NeedsLayout())
     return false;
 
@@ -4033,6 +4221,7 @@
 }
 
 void LayoutObject::SetNeedsBoundariesUpdate() {
+  CheckIsNotDestroyed();
   if (IsSVGChild()) {
     // The boundaries affect mask clip.
     auto* resources = SVGResourcesCache::CachedResourcesForLayoutObject(*this);
@@ -4046,29 +4235,35 @@
 }
 
 FloatRect LayoutObject::ObjectBoundingBox() const {
+  CheckIsNotDestroyed();
   NOTREACHED();
   return FloatRect();
 }
 
 FloatRect LayoutObject::StrokeBoundingBox() const {
+  CheckIsNotDestroyed();
   NOTREACHED();
   return FloatRect();
 }
 
 FloatRect LayoutObject::VisualRectInLocalSVGCoordinates() const {
+  CheckIsNotDestroyed();
   NOTREACHED();
   return FloatRect();
 }
 
 AffineTransform LayoutObject::LocalSVGTransform() const {
+  CheckIsNotDestroyed();
   return AffineTransform();
 }
 
 bool LayoutObject::IsRelayoutBoundary() const {
+  CheckIsNotDestroyed();
   return ObjectIsRelayoutBoundary(this);
 }
 
 inline void LayoutObject::SetShouldCheckGeometryForPaintInvalidation() {
+  CheckIsNotDestroyed();
   DCHECK(ShouldCheckForPaintInvalidation());
   bitfields_.SetShouldCheckGeometryForPaintInvalidation(true);
   for (auto* ancestor = ParentCrossingFrames();
@@ -4081,12 +4276,14 @@
 }
 
 void LayoutObject::SetShouldInvalidateSelection() {
+  CheckIsNotDestroyed();
   bitfields_.SetShouldInvalidateSelection(true);
   SetShouldCheckForPaintInvalidation();
 }
 
 void LayoutObject::SetShouldDoFullPaintInvalidation(
     PaintInvalidationReason reason) {
+  CheckIsNotDestroyed();
   SetShouldDoFullPaintInvalidationWithoutGeometryChange(reason);
   SetShouldCheckGeometryForPaintInvalidation();
 }
@@ -4110,6 +4307,7 @@
 
 void LayoutObject::SetShouldDoFullPaintInvalidationWithoutGeometryChange(
     PaintInvalidationReason reason) {
+  CheckIsNotDestroyed();
   // Only full invalidation reasons are allowed.
   DCHECK(IsFullPaintInvalidationReason(reason));
   if (ShouldDoFullPaintInvalidation())
@@ -4125,11 +4323,13 @@
 }
 
 void LayoutObject::SetShouldCheckForPaintInvalidation() {
+  CheckIsNotDestroyed();
   SetShouldCheckForPaintInvalidationWithoutGeometryChange();
   SetShouldCheckGeometryForPaintInvalidation();
 }
 
 void LayoutObject::SetShouldCheckForPaintInvalidationWithoutGeometryChange() {
+  CheckIsNotDestroyed();
   if (ShouldCheckForPaintInvalidation())
     return;
   GetFrameView()->ScheduleVisualUpdateForPaintInvalidationIfNeeded();
@@ -4143,6 +4343,7 @@
 }
 
 void LayoutObject::SetSubtreeShouldCheckForPaintInvalidation() {
+  CheckIsNotDestroyed();
   if (SubtreeShouldCheckForPaintInvalidation()) {
     DCHECK(ShouldCheckForPaintInvalidation());
     return;
@@ -4152,6 +4353,7 @@
 }
 
 void LayoutObject::SetMayNeedPaintInvalidationAnimatedBackgroundImage() {
+  CheckIsNotDestroyed();
   if (MayNeedPaintInvalidationAnimatedBackgroundImage())
     return;
   bitfields_.SetMayNeedPaintInvalidationAnimatedBackgroundImage(true);
@@ -4159,6 +4361,7 @@
 }
 
 void LayoutObject::SetShouldDelayFullPaintInvalidation() {
+  CheckIsNotDestroyed();
   // Should have already set a full paint invalidation reason.
   DCHECK(IsFullPaintInvalidationReason(full_paint_invalidation_reason_));
 
@@ -4175,6 +4378,7 @@
 }
 
 void LayoutObject::ClearPaintInvalidationFlags() {
+  CheckIsNotDestroyed();
 // PaintInvalidationStateIsDirty should be kept in sync with the
 // booleans that are cleared below.
 #if DCHECK_IS_ON()
@@ -4196,6 +4400,7 @@
 
 #if DCHECK_IS_ON()
 bool LayoutObject::PaintInvalidationStateIsDirty() const {
+  CheckIsNotDestroyed();
   return BackgroundNeedsFullPaintInvalidation() ||
          ShouldCheckForPaintInvalidation() || ShouldInvalidateSelection() ||
          ShouldCheckGeometryForPaintInvalidation() ||
@@ -4208,6 +4413,7 @@
 #endif
 
 void LayoutObject::EnsureIsReadyForPaintInvalidation() {
+  CheckIsNotDestroyed();
   DCHECK(!NeedsLayout() || ChildLayoutBlockedByDisplayLock());
 
   // Force full paint invalidation if the outline may be affected by descendants
@@ -4222,6 +4428,7 @@
 }
 
 void LayoutObject::ClearPaintFlags() {
+  CheckIsNotDestroyed();
   DCHECK_EQ(GetDocument().Lifecycle().GetState(),
             DocumentLifecycle::kInPrePaint);
   ClearPaintInvalidationFlags();
@@ -4241,12 +4448,14 @@
 
 void LayoutObject::SetSubtreeShouldDoFullPaintInvalidation(
     PaintInvalidationReason reason) {
+  CheckIsNotDestroyed();
   SetShouldDoFullPaintInvalidation(reason);
   bitfields_.SetSubtreeShouldDoFullPaintInvalidation(true);
 }
 
 void LayoutObject::SetIsBackgroundAttachmentFixedObject(
     bool is_background_attachment_fixed_object) {
+  CheckIsNotDestroyed();
   DCHECK(GetFrameView());
   if (bitfields_.IsBackgroundAttachmentFixedObject() ==
       is_background_attachment_fixed_object)
@@ -4260,10 +4469,12 @@
 }
 
 PhysicalRect LayoutObject::DebugRect() const {
+  CheckIsNotDestroyed();
   return PhysicalRect();
 }
 
 void LayoutObject::InvalidateSelectedChildrenOnStyleChange() {
+  CheckIsNotDestroyed();
   // LayoutSelection::Commit() propagates the state up the containing node
   // chain to
   // tell if a block contains selected nodes or not. If this layout object is
@@ -4290,6 +4501,7 @@
 }
 
 void LayoutObject::MarkEffectiveAllowedTouchActionChanged() {
+  CheckIsNotDestroyed();
   bitfields_.SetEffectiveAllowedTouchActionChanged(true);
   // If we're locked, mark our descendants as needing this change. This is used
   // a signal to ensure we mark the element as needing effective allowed
@@ -4364,6 +4576,7 @@
 }
 
 bool LayoutObject::CanBeSelectionLeaf() const {
+  CheckIsNotDestroyed();
   if (SlowFirstChild() || StyleRef().Visibility() != EVisibility::kVisible ||
       DisplayLockUtilities::NearestLockedExclusiveAncestor(*this)) {
     return false;
@@ -4372,6 +4585,7 @@
 }
 
 void LayoutObject::InvalidateClipPathCache() {
+  CheckIsNotDestroyed();
   SetNeedsPaintPropertyUpdate();
   for (auto* fragment = &fragment_; fragment;
        fragment = fragment->NextFragment())
@@ -4381,6 +4595,7 @@
 Vector<PhysicalRect> LayoutObject::OutlineRects(
     const PhysicalOffset& additional_offset,
     NGOutlineType outline_type) const {
+  CheckIsNotDestroyed();
   Vector<PhysicalRect> outline_rects;
   AddOutlineRects(outline_rects, additional_offset, outline_type);
   return outline_rects;
@@ -4389,6 +4604,7 @@
 void LayoutObject::SetModifiedStyleOutsideStyleRecalc(
     scoped_refptr<const ComputedStyle> style,
     ApplyStyleChanges apply_changes) {
+  CheckIsNotDestroyed();
   SetStyle(style, apply_changes);
   if (IsAnonymous() || !GetNode() || !GetNode()->IsElementNode())
     return;
@@ -4399,6 +4615,7 @@
     LayoutUnit position,
     LayoutUnit width,
     const LayoutBox* box_for_flipping) const {
+  CheckIsNotDestroyed();
   DCHECK(!IsBox());
   DCHECK(HasFlippedBlocksWritingMode());
   DCHECK(!box_for_flipping || box_for_flipping == ContainingBlock());
@@ -4410,6 +4627,7 @@
 }
 
 bool LayoutObject::SelfPaintingLayerNeedsVisualOverflowRecalc() const {
+  CheckIsNotDestroyed();
   if (HasLayer()) {
     auto* box_model_object = ToLayoutBoxModelObject(this);
     if (box_model_object->HasSelfPaintingLayer())
@@ -4419,6 +4637,7 @@
 }
 
 void LayoutObject::MarkSelfPaintingLayerForVisualOverflowRecalc() {
+  CheckIsNotDestroyed();
   if (HasLayer()) {
     auto* box_model_object = ToLayoutBoxModelObject(this);
     if (box_model_object->HasSelfPaintingLayer())
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 4adf5ac..a796ef7 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -285,7 +285,10 @@
   bool HasNonZeroEffectiveOpacity() const;
 
  protected:
-  void EnsureIdForTesting() { fragment_.EnsureId(); }
+  void EnsureIdForTesting() {
+    CheckIsNotDestroyed();
+    fragment_.EnsureId();
+  }
 
  private:
   // DisplayItemClient methods.
@@ -303,27 +306,42 @@
 
   // End of DisplayItemClient methods.
 
-  LayoutObject* Parent() const { return parent_; }
+  LayoutObject* Parent() const {
+    CheckIsNotDestroyed();
+    return parent_;
+  }
   bool IsDescendantOf(const LayoutObject*) const;
 
-  LayoutObject* PreviousSibling() const { return previous_; }
-  LayoutObject* NextSibling() const { return next_; }
+  LayoutObject* PreviousSibling() const {
+    CheckIsNotDestroyed();
+    return previous_;
+  }
+  LayoutObject* NextSibling() const {
+    CheckIsNotDestroyed();
+    return next_;
+  }
 
   DISABLE_CFI_PERF
   LayoutObject* SlowFirstChild() const {
+    CheckIsNotDestroyed();
     if (const LayoutObjectChildList* children = VirtualChildren())
       return children->FirstChild();
     return nullptr;
   }
   LayoutObject* SlowLastChild() const {
+    CheckIsNotDestroyed();
     if (const LayoutObjectChildList* children = VirtualChildren())
       return children->LastChild();
     return nullptr;
   }
 
   // See comment in the class description as to why there is no child.
-  virtual LayoutObjectChildList* VirtualChildren() { return nullptr; }
+  virtual LayoutObjectChildList* VirtualChildren() {
+    CheckIsNotDestroyed();
+    return nullptr;
+  }
   virtual const LayoutObjectChildList* VirtualChildren() const {
+    CheckIsNotDestroyed();
     return nullptr;
   }
 
@@ -404,14 +422,21 @@
   // Function to return our enclosing flow thread if we are contained inside
   // one. This function follows the containing block chain.
   LayoutFlowThread* FlowThreadContainingBlock() const {
+    CheckIsNotDestroyed();
     if (!IsInsideFlowThread())
       return nullptr;
     return LocateFlowThreadContainingBlock();
   }
 
 #if DCHECK_IS_ON()
-  void SetHasAXObject(bool flag) { has_ax_object_ = flag; }
-  bool HasAXObject() const { return has_ax_object_; }
+  void SetHasAXObject(bool flag) {
+    CheckIsNotDestroyed();
+    has_ax_object_ = flag;
+  }
+  bool HasAXObject() const {
+    CheckIsNotDestroyed();
+    return has_ax_object_;
+  }
 
   // Helper class forbidding calls to setNeedsLayout() during its lifetime.
   class SetLayoutNeededForbiddenScope {
@@ -427,12 +452,14 @@
   };
 
   void AssertLaidOut() const {
+    CheckIsNotDestroyed();
     if (NeedsLayout() && !ChildLayoutBlockedByDisplayLock())
       ShowLayoutTreeForThis();
     SECURITY_DCHECK(!NeedsLayout() || ChildLayoutBlockedByDisplayLock());
   }
 
   void AssertSubtreeIsLaidOut() const {
+    CheckIsNotDestroyed();
     for (const LayoutObject* layout_object = this; layout_object;
          layout_object = layout_object->ChildLayoutBlockedByDisplayLock()
                              ? layout_object->NextInPreOrderAfterChildren()
@@ -444,6 +471,7 @@
   void AssertClearedPaintInvalidationFlags() const;
 
   void AssertSubtreeClearedPaintInvalidationFlags() const {
+    CheckIsNotDestroyed();
     for (const LayoutObject* layout_object = this; layout_object;
          layout_object = layout_object->ChildPrePaintBlockedByDisplayLock()
                              ? layout_object->NextInPreOrderAfterChildren()
@@ -457,9 +485,11 @@
   // LayoutObject tree manipulation
   //////////////////////////////////////////
   DISABLE_CFI_PERF virtual bool CanHaveChildren() const {
+    CheckIsNotDestroyed();
     return VirtualChildren();
   }
   virtual bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const {
+    CheckIsNotDestroyed();
     return true;
   }
 
@@ -498,52 +528,69 @@
   virtual void AddChildIgnoringContinuation(
       LayoutObject* new_child,
       LayoutObject* before_child = nullptr) {
+    CheckIsNotDestroyed();
     return AddChild(new_child, before_child);
   }
   virtual void RemoveChild(LayoutObject*);
-  virtual bool CreatesAnonymousWrapper() const { return false; }
+  virtual bool CreatesAnonymousWrapper() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
   //////////////////////////////////////////
 
-  UniqueObjectId UniqueId() const { return fragment_.UniqueId(); }
+  UniqueObjectId UniqueId() const {
+    CheckIsNotDestroyed();
+    return fragment_.UniqueId();
+  }
 
   inline bool ShouldApplyPaintContainment(const ComputedStyle& style) const {
+    CheckIsNotDestroyed();
     return style.ContainsPaint() && (!IsInline() || IsAtomicInlineLevel()) &&
            !IsRubyText() && (!IsTablePart() || IsLayoutBlockFlow());
   }
 
   inline bool ShouldApplyPaintContainment() const {
+    CheckIsNotDestroyed();
     return ShouldApplyPaintContainment(StyleRef());
   }
 
   inline bool ShouldApplyLayoutContainment(const ComputedStyle& style) const {
+    CheckIsNotDestroyed();
     return style.ContainsLayout() && (!IsInline() || IsAtomicInlineLevel()) &&
            !IsRubyText() && (!IsTablePart() || IsLayoutBlockFlow());
   }
 
   inline bool ShouldApplyLayoutContainment() const {
+    CheckIsNotDestroyed();
     return ShouldApplyLayoutContainment(StyleRef());
   }
 
   inline bool ShouldApplySizeContainment() const {
+    CheckIsNotDestroyed();
     return StyleRef().ContainsSize() &&
            (!IsInline() || IsAtomicInlineLevel()) && !IsRubyText() &&
            (!IsTablePart() || IsTableCaption()) && !IsTable();
   }
   inline bool ShouldApplyStyleContainment() const {
+    CheckIsNotDestroyed();
     return StyleRef().ContainsStyle();
   }
   inline bool ShouldApplyContentContainment() const {
+    CheckIsNotDestroyed();
     return ShouldApplyPaintContainment() && ShouldApplyLayoutContainment();
   }
   inline bool ShouldApplyStrictContainment() const {
+    CheckIsNotDestroyed();
     return ShouldApplyPaintContainment() && ShouldApplyLayoutContainment() &&
            ShouldApplySizeContainment();
   }
 
   inline bool IsStackingContext() const {
+    CheckIsNotDestroyed();
     return IsStackingContext(StyleRef());
   }
   inline bool IsStackingContext(const ComputedStyle& style) const {
+    CheckIsNotDestroyed();
     // This is an inlined version of the following:
     // `IsStackingContextWithoutContainment() ||
     //  ShouldApplyLayoutContainment() ||
@@ -556,8 +603,12 @@
             (!IsTablePart() || IsLayoutBlockFlow()));
   }
 
-  inline bool IsStacked() const { return IsStacked(StyleRef()); }
+  inline bool IsStacked() const {
+    CheckIsNotDestroyed();
+    return IsStacked(StyleRef());
+  }
   inline bool IsStacked(const ComputedStyle& style) const {
+    CheckIsNotDestroyed();
     return style.GetPosition() != EPosition::kStatic ||
            IsStackingContext(style);
   }
@@ -567,9 +618,16 @@
  private:
   //////////////////////////////////////////
   // Helper functions. Dangerous to use!
-  void SetPreviousSibling(LayoutObject* previous) { previous_ = previous; }
-  void SetNextSibling(LayoutObject* next) { next_ = next; }
+  void SetPreviousSibling(LayoutObject* previous) {
+    CheckIsNotDestroyed();
+    previous_ = previous;
+  }
+  void SetNextSibling(LayoutObject* next) {
+    CheckIsNotDestroyed();
+    next_ = next;
+  }
   void SetParent(LayoutObject* parent) {
+    CheckIsNotDestroyed();
     parent_ = parent;
 
     // Only update if our flow thread state is different from our new parent and
@@ -584,8 +642,12 @@
   //////////////////////////////////////////
  private:
 #if DCHECK_IS_ON()
-  bool IsSetNeedsLayoutForbidden() const { return set_needs_layout_forbidden_; }
+  bool IsSetNeedsLayoutForbidden() const {
+    CheckIsNotDestroyed();
+    return set_needs_layout_forbidden_;
+  }
   void SetNeedsLayoutIsForbidden(bool flag) {
+    CheckIsNotDestroyed();
     set_needs_layout_forbidden_ = flag;
   }
 #endif
@@ -642,149 +704,318 @@
   void operator delete(void*);
 
   bool IsPseudoElement() const {
+    CheckIsNotDestroyed();
     return GetNode() && GetNode()->IsPseudoElement();
   }
 
-  virtual bool IsBoxModelObject() const { return false; }
-  bool IsBR() const { return IsOfType(kLayoutObjectBr); }
-  bool IsCanvas() const { return IsOfType(kLayoutObjectCanvas); }
-  bool IsCounter() const { return IsOfType(kLayoutObjectCounter); }
-  bool IsDetailsMarker() const { return IsOfType(kLayoutObjectDetailsMarker); }
+  virtual bool IsBoxModelObject() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
+  bool IsBR() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectBr);
+  }
+  bool IsCanvas() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectCanvas);
+  }
+  bool IsCounter() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectCounter);
+  }
+  bool IsDetailsMarker() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectDetailsMarker);
+  }
   bool IsEmbeddedObject() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectEmbeddedObject);
   }
-  bool IsFieldset() const { return IsOfType(kLayoutObjectFieldset); }
-  bool IsLayoutNGFieldset() const { return IsOfType(kLayoutObjectNGFieldset); }
+  bool IsFieldset() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectFieldset);
+  }
+  bool IsLayoutNGFieldset() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectNGFieldset);
+  }
   bool IsFieldsetIncludingNG() const {
+    CheckIsNotDestroyed();
     return IsFieldset() || IsLayoutNGFieldset();
   }
   bool IsFileUploadControl() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectFileUploadControl);
   }
-  bool IsFrame() const { return IsOfType(kLayoutObjectFrame); }
-  bool IsFrameSet() const { return IsOfType(kLayoutObjectFrameSet); }
+  bool IsFrame() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectFrame);
+  }
+  bool IsFrameSet() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectFrameSet);
+  }
   bool IsInsideListMarkerForCustomContent() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectInsideListMarker);
   }
   bool IsLayoutNGBlockFlow() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectNGBlockFlow);
   }
   bool IsLayoutNGFlexibleBox() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectNGFlexibleBox);
   }
-  bool IsLayoutNGGrid() const { return IsOfType(kLayoutObjectNGGrid); }
-  bool IsLayoutNGMixin() const { return IsOfType(kLayoutObjectNGMixin); }
-  bool IsLayoutNGListItem() const { return IsOfType(kLayoutObjectNGListItem); }
+  bool IsLayoutNGGrid() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectNGGrid);
+  }
+  bool IsLayoutNGMixin() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectNGMixin);
+  }
+  bool IsLayoutNGListItem() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectNGListItem);
+  }
   bool IsLayoutNGInsideListMarker() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectNGInsideListMarker);
   }
   bool IsLayoutNGOutsideListMarker() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectNGOutsideListMarker);
   }
-  bool IsLayoutNGProgress() const { return IsOfType(kLayoutObjectNGProgress); }
-  bool IsLayoutNGText() const { return IsOfType(kLayoutObjectNGText); }
+  bool IsLayoutNGProgress() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectNGProgress);
+  }
+  bool IsLayoutNGText() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectNGText);
+  }
   bool IsLayoutTableCol() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectLayoutTableCol);
   }
   bool IsLayoutNGTableCol() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectLayoutNGTableCol);
   }
-  bool IsListItem() const { return IsOfType(kLayoutObjectListItem); }
+  bool IsListItem() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectListItem);
+  }
   bool IsListMarkerForNormalContent() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectListMarker);
   }
   bool IsListMarkerImage() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectListMarkerImage);
   }
-  bool IsMathML() const { return IsOfType(kLayoutObjectMathML); }
-  bool IsMathMLRoot() const { return IsOfType(kLayoutObjectMathMLRoot); }
-  bool IsMedia() const { return IsOfType(kLayoutObjectMedia); }
+  bool IsMathML() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectMathML);
+  }
+  bool IsMathMLRoot() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectMathMLRoot);
+  }
+  bool IsMedia() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectMedia);
+  }
   bool IsOutsideListMarkerForCustomContent() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectOutsideListMarker);
   }
-  bool IsProgress() const { return IsOfType(kLayoutObjectProgress); }
-  bool IsQuote() const { return IsOfType(kLayoutObjectQuote); }
+  bool IsProgress() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectProgress);
+  }
+  bool IsQuote() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectQuote);
+  }
   bool IsButtonOrNGButton() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectLayoutButton) ||
            IsOfType(kLayoutObjectNGButton);
   }
-  bool IsLayoutNGButton() const { return IsOfType(kLayoutObjectNGButton); }
+  bool IsLayoutNGButton() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectNGButton);
+  }
   bool IsLayoutNGCustom() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectLayoutNGCustom);
   }
-  bool IsLayoutGrid() const { return IsOfType(kLayoutObjectLayoutGrid); }
-  bool IsLayoutIFrame() const { return IsOfType(kLayoutObjectLayoutIFrame); }
-  bool IsLayoutImage() const { return IsOfType(kLayoutObjectLayoutImage); }
+  bool IsLayoutGrid() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectLayoutGrid);
+  }
+  bool IsLayoutIFrame() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectLayoutIFrame);
+  }
+  bool IsLayoutImage() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectLayoutImage);
+  }
   bool IsLayoutMultiColumnSet() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectLayoutMultiColumnSet);
   }
   bool IsLayoutMultiColumnSpannerPlaceholder() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectLayoutMultiColumnSpannerPlaceholder);
   }
   bool IsLayoutReplaced() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectLayoutReplaced);
   }
   bool IsLayoutCustomScrollbarPart() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectLayoutCustomScrollbarPart);
   }
-  bool IsLayoutView() const { return IsOfType(kLayoutObjectLayoutView); }
-  bool IsRuby() const { return IsOfType(kLayoutObjectRuby); }
-  bool IsRubyBase() const { return IsOfType(kLayoutObjectRubyBase); }
-  bool IsRubyRun() const { return IsOfType(kLayoutObjectRubyRun); }
-  bool IsRubyText() const { return IsOfType(kLayoutObjectRubyText); }
-  bool IsTable() const { return IsOfType(kLayoutObjectTable); }
-  bool IsTableCaption() const { return IsOfType(kLayoutObjectTableCaption); }
-  bool IsTableCell() const { return IsOfType(kLayoutObjectTableCell); }
+  bool IsLayoutView() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectLayoutView);
+  }
+  bool IsRuby() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectRuby);
+  }
+  bool IsRubyBase() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectRubyBase);
+  }
+  bool IsRubyRun() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectRubyRun);
+  }
+  bool IsRubyText() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectRubyText);
+  }
+  bool IsTable() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectTable);
+  }
+  bool IsTableCaption() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectTableCaption);
+  }
+  bool IsTableCell() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectTableCell);
+  }
   bool IsTableCellLegacy() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectTableCellLegacy);
   }
-  bool IsTableRow() const { return IsOfType(kLayoutObjectTableRow); }
-  bool IsTableSection() const { return IsOfType(kLayoutObjectTableSection); }
-  bool IsTextArea() const { return IsOfType(kLayoutObjectTextArea); }
-  bool IsTextControl() const { return IsOfType(kLayoutObjectTextControl); }
-  bool IsTextField() const { return IsOfType(kLayoutObjectTextField); }
-  bool IsVideo() const { return IsOfType(kLayoutObjectVideo); }
-  bool IsWidget() const { return IsOfType(kLayoutObjectWidget); }
+  bool IsTableRow() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectTableRow);
+  }
+  bool IsTableSection() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectTableSection);
+  }
+  bool IsTextArea() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectTextArea);
+  }
+  bool IsTextControl() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectTextControl);
+  }
+  bool IsTextField() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectTextField);
+  }
+  bool IsVideo() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectVideo);
+  }
+  bool IsWidget() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectWidget);
+  }
 
-  virtual bool IsImage() const { return false; }
+  virtual bool IsImage() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
-  virtual bool IsInlineBlockOrInlineTable() const { return false; }
-  virtual bool IsLayoutBlock() const { return false; }
-  virtual bool IsLayoutBlockFlow() const { return false; }
-  virtual bool IsLayoutFlowThread() const { return false; }
-  virtual bool IsLayoutInline() const { return false; }
-  virtual bool IsLayoutEmbeddedContent() const { return false; }
-  virtual bool IsLayoutNGObject() const { return false; }
+  virtual bool IsInlineBlockOrInlineTable() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
+  virtual bool IsLayoutBlock() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
+  virtual bool IsLayoutBlockFlow() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
+  virtual bool IsLayoutFlowThread() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
+  virtual bool IsLayoutInline() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
+  virtual bool IsLayoutEmbeddedContent() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
+  virtual bool IsLayoutNGObject() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   bool IsDocumentElement() const {
+    CheckIsNotDestroyed();
     return GetDocument().documentElement() == node_;
   }
   // isBody is called from LayoutBox::styleWillChange and is thus quite hot.
   bool IsBody() const {
+    CheckIsNotDestroyed();
     return GetNode() && GetNode()->HasTagName(html_names::kBodyTag);
   }
 
   bool IsHR() const;
 
   bool IsTablePart() const {
+    CheckIsNotDestroyed();
     return IsTableCell() || IsLayoutTableCol() || IsTableCaption() ||
            IsTableRow() || IsTableSection();
   }
   virtual const LayoutNGTableInterface* ToLayoutNGTableInterface() const {
+    CheckIsNotDestroyed();
     DCHECK(false);
     return nullptr;
   }
   virtual const LayoutNGTableSectionInterface* ToLayoutNGTableSectionInterface()
       const {
+    CheckIsNotDestroyed();
     DCHECK(false);
     return nullptr;
   }
   virtual const LayoutNGTableRowInterface* ToLayoutNGTableRowInterface() const {
+    CheckIsNotDestroyed();
     DCHECK(false);
     return nullptr;
   }
   virtual const LayoutNGTableCellInterface* ToLayoutNGTableCellInterface()
       const {
+    CheckIsNotDestroyed();
     DCHECK(false);
     return nullptr;
   }
@@ -802,35 +1033,56 @@
   // |NGTextType::kLayoutGenerated| for the other type of generated text.
   bool IsStyleGenerated() const;
 
-  bool HasCounterNodeMap() const { return bitfields_.HasCounterNodeMap(); }
+  bool HasCounterNodeMap() const {
+    CheckIsNotDestroyed();
+    return bitfields_.HasCounterNodeMap();
+  }
   void SetHasCounterNodeMap(bool has_counter_node_map) {
+    CheckIsNotDestroyed();
     bitfields_.SetHasCounterNodeMap(has_counter_node_map);
   }
 
-  bool IsTruncated() const { return bitfields_.IsTruncated(); }
+  bool IsTruncated() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsTruncated();
+  }
   void SetIsTruncated(bool is_truncated) {
+    CheckIsNotDestroyed();
     bitfields_.SetIsTruncated(is_truncated);
   }
 
-  bool EverHadLayout() const { return bitfields_.EverHadLayout(); }
+  bool EverHadLayout() const {
+    CheckIsNotDestroyed();
+    return bitfields_.EverHadLayout();
+  }
 
-  bool ChildrenInline() const { return bitfields_.ChildrenInline(); }
-  void SetChildrenInline(bool b) { bitfields_.SetChildrenInline(b); }
+  bool ChildrenInline() const {
+    CheckIsNotDestroyed();
+    return bitfields_.ChildrenInline();
+  }
+  void SetChildrenInline(bool b) {
+    CheckIsNotDestroyed();
+    bitfields_.SetChildrenInline(b);
+  }
 
   bool AlwaysCreateLineBoxesForLayoutInline() const {
+    CheckIsNotDestroyed();
     DCHECK(IsLayoutInline());
     return bitfields_.AlwaysCreateLineBoxesForLayoutInline();
   }
   void SetAlwaysCreateLineBoxesForLayoutInline(bool always_create_line_boxes) {
+    CheckIsNotDestroyed();
     DCHECK(IsLayoutInline());
     bitfields_.SetAlwaysCreateLineBoxesForLayoutInline(
         always_create_line_boxes);
   }
 
   bool AncestorLineBoxDirty() const {
+    CheckIsNotDestroyed();
     return bitfields_.AncestorLineBoxDirty();
   }
   void SetAncestorLineBoxDirty(bool value = true) {
+    CheckIsNotDestroyed();
     bitfields_.SetAncestorLineBoxDirty(value);
     if (value) {
       SetNeedsLayoutAndFullPaintInvalidation(
@@ -840,40 +1092,80 @@
 
   void SetIsInsideFlowThreadIncludingDescendants(bool);
 
-  bool IsInsideFlowThread() const { return bitfields_.IsInsideFlowThread(); }
+  bool IsInsideFlowThread() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsInsideFlowThread();
+  }
   void SetIsInsideFlowThread(bool inside_flow_thread) {
+    CheckIsNotDestroyed();
     bitfields_.SetIsInsideFlowThread(inside_flow_thread);
   }
 
   // FIXME: Until all SVG layoutObjects can be subclasses of
   // LayoutSVGModelObject we have to add SVG layoutObject methods to
   // LayoutObject with an NOTREACHED() default implementation.
-  bool IsSVG() const { return IsOfType(kLayoutObjectSVG); }
-  bool IsSVGRoot() const { return IsOfType(kLayoutObjectSVGRoot); }
-  bool IsSVGChild() const { return IsSVG() && !IsSVGRoot(); }
-  bool IsSVGContainer() const { return IsOfType(kLayoutObjectSVGContainer); }
+  bool IsSVG() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectSVG);
+  }
+  bool IsSVGRoot() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectSVGRoot);
+  }
+  bool IsSVGChild() const {
+    CheckIsNotDestroyed();
+    return IsSVG() && !IsSVGRoot();
+  }
+  bool IsSVGContainer() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectSVGContainer);
+  }
   bool IsSVGTransformableContainer() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectSVGTransformableContainer);
   }
   bool IsSVGViewportContainer() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectSVGViewportContainer);
   }
   bool IsSVGHiddenContainer() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectSVGHiddenContainer);
   }
-  bool IsSVGShape() const { return IsOfType(kLayoutObjectSVGShape); }
-  bool IsSVGText() const { return IsOfType(kLayoutObjectSVGText); }
-  bool IsSVGTextPath() const { return IsOfType(kLayoutObjectSVGTextPath); }
-  bool IsSVGInline() const { return IsOfType(kLayoutObjectSVGInline); }
-  bool IsSVGInlineText() const { return IsOfType(kLayoutObjectSVGInlineText); }
-  bool IsSVGImage() const { return IsOfType(kLayoutObjectSVGImage); }
+  bool IsSVGShape() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectSVGShape);
+  }
+  bool IsSVGText() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectSVGText);
+  }
+  bool IsSVGTextPath() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectSVGTextPath);
+  }
+  bool IsSVGInline() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectSVGInline);
+  }
+  bool IsSVGInlineText() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectSVGInlineText);
+  }
+  bool IsSVGImage() const {
+    CheckIsNotDestroyed();
+    return IsOfType(kLayoutObjectSVGImage);
+  }
   bool IsSVGForeignObject() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectSVGForeignObject);
   }
   bool IsSVGResourceContainer() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectSVGResourceContainer);
   }
   bool IsSVGFilterPrimitive() const {
+    CheckIsNotDestroyed();
     return IsOfType(kLayoutObjectSVGFilterPrimitive);
   }
 
@@ -881,7 +1173,7 @@
   // (see above). Unfortunately we don't have such a class yet, because it's not
   // possible for all layoutObjects to inherit from LayoutSVGObject ->
   // LayoutObject (some need LayoutBlock inheritance for instance)
-  virtual void SetNeedsTransformUpdate() {}
+  virtual void SetNeedsTransformUpdate() { CheckIsNotDestroyed(); }
   virtual void SetNeedsBoundariesUpdate();
 
   // Per the spec, mix-blend-mode applies to all non-SVG elements, and SVG
@@ -889,6 +1181,7 @@
   // referencing elements.
   // https://www.w3.org/TR/compositing-1/#propdef-mix-blend-mode
   bool IsBlendingAllowed() const {
+    CheckIsNotDestroyed();
     return !IsSVG() || IsSVGShape() || IsSVGImage() || IsSVGText() ||
            IsSVGInline() || IsSVGRoot() || IsSVGForeignObject() ||
            // Blending does not apply to non-renderable elements such as
@@ -896,6 +1189,7 @@
            (IsSVGContainer() && !IsSVGHiddenContainer());
   }
   virtual bool HasNonIsolatedBlendingDescendants() const {
+    CheckIsNotDestroyed();
     // This is only implemented for layout objects that containt SVG flow.
     // For HTML/CSS layout objects, use the PaintLayer version instead.
     DCHECK(IsSVG());
@@ -906,7 +1200,9 @@
     kDescendantIsolationNeedsUpdate,
   };
   virtual void DescendantIsolationRequirementsChanged(
-      DescendantIsolationState) {}
+      DescendantIsolationState) {
+    CheckIsNotDestroyed();
+  }
 
   // Per SVG 1.1 objectBoundingBox ignores clipping, masking, filter effects,
   // opacity and stroke-width.
@@ -939,13 +1235,18 @@
   // this includes any viewport transforms and x/y offsets as well as
   // localSVGTransform.
   virtual AffineTransform LocalToSVGParentTransform() const {
+    CheckIsNotDestroyed();
     return LocalSVGTransform();
   }
 
   // End of SVG-specific methods.
 
-  bool IsAnonymous() const { return bitfields_.IsAnonymous(); }
+  bool IsAnonymous() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsAnonymous();
+  }
   bool IsAnonymousBlock() const {
+    CheckIsNotDestroyed();
     // This function is kept in sync with anonymous block creation conditions in
     // LayoutBlock::createAnonymousBlock(). This includes creating an anonymous
     // LayoutBlock having a BLOCK or BOX display. Other classes such as
@@ -960,52 +1261,95 @@
   // If node has been split into continuations, it returns the first layout
   // object generated for the node.
   const LayoutObject* ContinuationRoot() const {
+    CheckIsNotDestroyed();
     return GetNode() ? GetNode()->GetLayoutObject() : this;
   }
   bool IsElementContinuation() const {
+    CheckIsNotDestroyed();
     return GetNode() && GetNode()->GetLayoutObject() != this;
   }
   bool IsInlineElementContinuation() const {
+    CheckIsNotDestroyed();
     return IsElementContinuation() && IsInline();
   }
-  virtual LayoutBoxModelObject* VirtualContinuation() const { return nullptr; }
+  virtual LayoutBoxModelObject* VirtualContinuation() const {
+    CheckIsNotDestroyed();
+    return nullptr;
+  }
 
-  bool IsFloating() const { return bitfields_.Floating(); }
+  bool IsFloating() const {
+    CheckIsNotDestroyed();
+    return bitfields_.Floating();
+  }
 
   bool IsFloatingWithNonContainingBlockParent() const {
+    CheckIsNotDestroyed();
     return IsFloating() && Parent() && !Parent()->IsLayoutBlockFlow();
   }
 
   // absolute or fixed positioning
   bool IsOutOfFlowPositioned() const {
+    CheckIsNotDestroyed();
     return bitfields_.IsOutOfFlowPositioned();
   }
   // relative or sticky positioning
-  bool IsInFlowPositioned() const { return bitfields_.IsInFlowPositioned(); }
-  bool IsRelPositioned() const { return bitfields_.IsRelPositioned(); }
-  bool IsStickyPositioned() const { return bitfields_.IsStickyPositioned(); }
+  bool IsInFlowPositioned() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsInFlowPositioned();
+  }
+  bool IsRelPositioned() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsRelPositioned();
+  }
+  bool IsStickyPositioned() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsStickyPositioned();
+  }
   bool IsFixedPositioned() const {
+    CheckIsNotDestroyed();
     return IsOutOfFlowPositioned() &&
            StyleRef().GetPosition() == EPosition::kFixed;
   }
   bool IsAbsolutePositioned() const {
+    CheckIsNotDestroyed();
     return IsOutOfFlowPositioned() &&
            StyleRef().GetPosition() == EPosition::kAbsolute;
   }
-  bool IsPositioned() const { return bitfields_.IsPositioned(); }
+  bool IsPositioned() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsPositioned();
+  }
 
-  bool IsText() const { return bitfields_.IsText(); }
-  bool IsBox() const { return bitfields_.IsBox(); }
-  bool IsInline() const { return bitfields_.IsInline(); }  // inline object
+  bool IsText() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsText();
+  }
+  bool IsBox() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsBox();
+  }
+  bool IsInline() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsInline();
+  }  // inline object
   bool IsInLayoutNGInlineFormattingContext() const {
+    CheckIsNotDestroyed();
     return bitfields_.IsInLayoutNGInlineFormattingContext();
   }
-  bool ForceLegacyLayout() const { return bitfields_.ForceLegacyLayout(); }
-  bool IsAtomicInlineLevel() const { return bitfields_.IsAtomicInlineLevel(); }
+  bool ForceLegacyLayout() const {
+    CheckIsNotDestroyed();
+    return bitfields_.ForceLegacyLayout();
+  }
+  bool IsAtomicInlineLevel() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsAtomicInlineLevel();
+  }
   bool IsHorizontalWritingMode() const {
+    CheckIsNotDestroyed();
     return bitfields_.HorizontalWritingMode();
   }
   bool HasFlippedBlocksWritingMode() const {
+    CheckIsNotDestroyed();
     return StyleRef().IsFlippedBlocksWritingMode();
   }
 
@@ -1018,6 +1362,7 @@
   WARN_UNUSED_RESULT LayoutRect
   FlipForWritingMode(const PhysicalRect& r,
                      const LayoutBox* box_for_flipping = nullptr) const {
+    CheckIsNotDestroyed();
     if (LIKELY(!HasFlippedBlocksWritingMode()))
       return r.ToLayoutRect();
     return {FlipForWritingModeInternal(r.X(), r.Width(), box_for_flipping),
@@ -1026,6 +1371,7 @@
   WARN_UNUSED_RESULT PhysicalRect
   FlipForWritingMode(const LayoutRect& r,
                      const LayoutBox* box_for_flipping = nullptr) const {
+    CheckIsNotDestroyed();
     if (LIKELY(!HasFlippedBlocksWritingMode()))
       return PhysicalRect(r);
     return {FlipForWritingModeInternal(r.X(), r.Width(), box_for_flipping),
@@ -1034,6 +1380,7 @@
   WARN_UNUSED_RESULT LayoutPoint
   FlipForWritingMode(const PhysicalOffset& p,
                      const LayoutBox* box_for_flipping = nullptr) const {
+    CheckIsNotDestroyed();
     if (LIKELY(!HasFlippedBlocksWritingMode()))
       return p.ToLayoutPoint();
     return {FlipForWritingModeInternal(p.left, LayoutUnit(), box_for_flipping),
@@ -1042,22 +1389,28 @@
   WARN_UNUSED_RESULT PhysicalOffset
   FlipForWritingMode(const LayoutPoint& p,
                      const LayoutBox* box_for_flipping = nullptr) const {
+    CheckIsNotDestroyed();
     if (LIKELY(!HasFlippedBlocksWritingMode()))
       return PhysicalOffset(p);
     return {FlipForWritingModeInternal(p.X(), LayoutUnit(), box_for_flipping),
             p.Y()};
   }
 
-  bool HasLayer() const { return bitfields_.HasLayer(); }
+  bool HasLayer() const {
+    CheckIsNotDestroyed();
+    return bitfields_.HasLayer();
+  }
 
   // This may be different from StyleRef().hasBoxDecorationBackground() because
   // some objects may have box decoration background other than from their own
   // style.
   bool HasBoxDecorationBackground() const {
+    CheckIsNotDestroyed();
     return bitfields_.HasBoxDecorationBackground();
   }
 
   bool NeedsLayout() const {
+    CheckIsNotDestroyed();
     return bitfields_.SelfNeedsLayoutForStyle() ||
            bitfields_.SelfNeedsLayoutForAvailableSpace() ||
            bitfields_.NormalChildNeedsLayout() ||
@@ -1067,6 +1420,7 @@
   }
 
   bool NeedsPositionedMovementLayoutOnly() const {
+    CheckIsNotDestroyed();
     return bitfields_.NeedsPositionedMovementLayout() &&
            !bitfields_.SelfNeedsLayoutForStyle() &&
            !bitfields_.SelfNeedsLayoutForAvailableSpace() &&
@@ -1076,6 +1430,7 @@
   }
 
   bool NeedsSimplifiedLayoutOnly() const {
+    CheckIsNotDestroyed();
     // We don't need to check |SelfNeedsLayoutForAvailableSpace| as an
     // additional check will determine if we need to perform full layout based
     // on the available space.
@@ -1087,32 +1442,46 @@
   }
 
   bool SelfNeedsLayout() const {
+    CheckIsNotDestroyed();
     return bitfields_.SelfNeedsLayoutForStyle() ||
            bitfields_.SelfNeedsLayoutForAvailableSpace();
   }
   bool SelfNeedsLayoutForStyle() const {
+    CheckIsNotDestroyed();
     return bitfields_.SelfNeedsLayoutForStyle();
   }
   bool SelfNeedsLayoutForAvailableSpace() const {
+    CheckIsNotDestroyed();
     return bitfields_.SelfNeedsLayoutForAvailableSpace();
   }
   bool NeedsPositionedMovementLayout() const {
+    CheckIsNotDestroyed();
     return bitfields_.NeedsPositionedMovementLayout();
   }
 
-  bool PosChildNeedsLayout() const { return bitfields_.PosChildNeedsLayout(); }
+  bool PosChildNeedsLayout() const {
+    CheckIsNotDestroyed();
+    return bitfields_.PosChildNeedsLayout();
+  }
   bool NeedsSimplifiedNormalFlowLayout() const {
+    CheckIsNotDestroyed();
     return bitfields_.NeedsSimplifiedNormalFlowLayout();
   }
   bool NormalChildNeedsLayout() const {
+    CheckIsNotDestroyed();
     return bitfields_.NormalChildNeedsLayout();
   }
-  bool NeedsCollectInlines() const { return bitfields_.NeedsCollectInlines(); }
+  bool NeedsCollectInlines() const {
+    CheckIsNotDestroyed();
+    return bitfields_.NeedsCollectInlines();
+  }
 
   bool MaybeHasPercentHeightDescendant() const {
+    CheckIsNotDestroyed();
     return bitfields_.MaybeHasPercentHeightDescendant();
   }
   void SetMaybeHasPercentHeightDescendant() {
+    CheckIsNotDestroyed();
     bitfields_.SetMaybeHasPercentHeightDescendant(true);
   }
 
@@ -1123,56 +1492,74 @@
   // min/max), this flag will never be cleared (since the values will never be
   // calculated).
   bool IntrinsicLogicalWidthsDirty() const {
+    CheckIsNotDestroyed();
     return bitfields_.IntrinsicLogicalWidthsDirty();
   }
 
   bool IntrinsicLogicalWidthsDependsOnPercentageBlockSize() const {
+    CheckIsNotDestroyed();
     return bitfields_.IntrinsicLogicalWidthsDependsOnPercentageBlockSize();
   }
   void SetIntrinsicLogicalWidthsDependsOnPercentageBlockSize(bool b) {
+    CheckIsNotDestroyed();
     bitfields_.SetIntrinsicLogicalWidthsDependsOnPercentageBlockSize(b);
   }
   bool IntrinsicLogicalWidthsChildDependsOnPercentageBlockSize() const {
+    CheckIsNotDestroyed();
     return bitfields_.IntrinsicLogicalWidthsChildDependsOnPercentageBlockSize();
   }
   void SetIntrinsicLogicalWidthsChildDependsOnPercentageBlockSize(bool b) {
+    CheckIsNotDestroyed();
     bitfields_.SetIntrinsicLogicalWidthsChildDependsOnPercentageBlockSize(b);
   }
 
   bool NeedsLayoutOverflowRecalc() const {
+    CheckIsNotDestroyed();
     return bitfields_.SelfNeedsLayoutOverflowRecalc() ||
            bitfields_.ChildNeedsLayoutOverflowRecalc();
   }
   bool SelfNeedsLayoutOverflowRecalc() const {
+    CheckIsNotDestroyed();
     return bitfields_.SelfNeedsLayoutOverflowRecalc();
   }
   bool ChildNeedsLayoutOverflowRecalc() const {
+    CheckIsNotDestroyed();
     return bitfields_.ChildNeedsLayoutOverflowRecalc();
   }
   void SetSelfNeedsLayoutOverflowRecalc() {
+    CheckIsNotDestroyed();
     bitfields_.SetSelfNeedsLayoutOverflowRecalc(true);
   }
   void SetChildNeedsLayoutOverflowRecalc() {
+    CheckIsNotDestroyed();
     bitfields_.SetChildNeedsLayoutOverflowRecalc(true);
   }
   void ClearSelfNeedsLayoutOverflowRecalc() {
+    CheckIsNotDestroyed();
     bitfields_.SetSelfNeedsLayoutOverflowRecalc(false);
   }
   void ClearChildNeedsLayoutOverflowRecalc() {
+    CheckIsNotDestroyed();
     bitfields_.SetChildNeedsLayoutOverflowRecalc(false);
   }
 
   // CSS clip only applies when position is absolute or fixed. Prefer this check
   // over !StyleRef().HasAutoClip().
   bool HasClip() const {
+    CheckIsNotDestroyed();
     return IsOutOfFlowPositioned() && !StyleRef().HasAutoClip();
   }
   bool HasNonVisibleOverflow() const {
+    CheckIsNotDestroyed();
     return bitfields_.HasNonVisibleOverflow();
   }
-  bool ShouldClipOverflow() const { return bitfields_.ShouldClipOverflow(); }
+  bool ShouldClipOverflow() const {
+    CheckIsNotDestroyed();
+    return bitfields_.ShouldClipOverflow();
+  }
   bool HasClipRelatedProperty() const;
   bool IsScrollContainer() const {
+    CheckIsNotDestroyed();
     // Always check HasNonVisibleOverflow() in case the object is not allowed to
     // have non-visible overflow.
     return HasNonVisibleOverflow() && StyleRef().IsScrollContainer();
@@ -1181,15 +1568,27 @@
   // Not returning StyleRef().HasTransformRelatedProperty() because some objects
   // ignore the transform-related styles (e.g. LayoutInline, LayoutSVGBlock).
   bool HasTransformRelatedProperty() const {
+    CheckIsNotDestroyed();
     return bitfields_.HasTransformRelatedProperty();
   }
-  bool IsTransformApplicable() const { return IsBox() || IsSVG(); }
-  bool HasMask() const { return StyleRef().HasMask(); }
-  bool HasClipPath() const { return StyleRef().ClipPath(); }
+  bool IsTransformApplicable() const {
+    CheckIsNotDestroyed();
+    return IsBox() || IsSVG();
+  }
+  bool HasMask() const {
+    CheckIsNotDestroyed();
+    return StyleRef().HasMask();
+  }
+  bool HasClipPath() const {
+    CheckIsNotDestroyed();
+    return StyleRef().ClipPath();
+  }
   bool HasHiddenBackface() const {
+    CheckIsNotDestroyed();
     return StyleRef().BackfaceVisibility() == EBackfaceVisibility::kHidden;
   }
   bool HasNonInitialBackdropFilter() const {
+    CheckIsNotDestroyed();
     return StyleRef().HasNonInitialBackdropFilter();
   }
 
@@ -1198,10 +1597,14 @@
   // Not calling StyleRef().HasFilterInducingProperty() because some objects
   // ignore reflection style (e.g. LayoutInline, LayoutSVGBlock).
   bool HasFilterInducingProperty() const {
+    CheckIsNotDestroyed();
     return StyleRef().HasNonInitialFilter() || HasReflection();
   }
 
-  bool HasShapeOutside() const { return StyleRef().ShapeOutside(); }
+  bool HasShapeOutside() const {
+    CheckIsNotDestroyed();
+    return StyleRef().ShapeOutside();
+  }
 
   // Return true if the given object is the effective root scroller in its
   // Document. See |effective root scroller| in page/scrolling/README.md.
@@ -1210,19 +1613,25 @@
   // RootScrollerController::RecomputeEffectiveRootScroller in the LayoutClean
   // document lifecycle phase.
   bool IsEffectiveRootScroller() const {
+    CheckIsNotDestroyed();
     return bitfields_.IsEffectiveRootScroller();
   }
 
   // Returns true if the given object is the global root scroller. See
   // |global root scroller| in page/scrolling/README.md.
   bool IsGlobalRootScroller() const {
+    CheckIsNotDestroyed();
     return bitfields_.IsGlobalRootScroller();
   }
 
-  bool IsHTMLLegendElement() const { return bitfields_.IsHTMLLegendElement(); }
+  bool IsHTMLLegendElement() const {
+    CheckIsNotDestroyed();
+    return bitfields_.IsHTMLLegendElement();
+  }
 
   // Returns true if this can be used as a rendered legend.
   bool IsRenderedLegendCandidate() const {
+    CheckIsNotDestroyed();
     // Note, we can't directly use LayoutObject::IsFloating() because in the
     // case where the legend is a flex/grid item, LayoutObject::IsFloating()
     // could get set to false, even if the legend's computed style indicates
@@ -1237,6 +1646,7 @@
   //
   // This function is performance sensitive.
   inline bool IsRenderedLegend() const {
+    CheckIsNotDestroyed();
     if (LIKELY(!IsRenderedLegendCandidate()))
       return false;
 
@@ -1255,36 +1665,56 @@
       const PseudoElementStyleRequest&,
       const ComputedStyle* parent_style = nullptr) const;
 
-  LayoutView* View() const { return GetDocument().GetLayoutView(); }
-  LocalFrameView* GetFrameView() const { return GetDocument().View(); }
+  LayoutView* View() const {
+    CheckIsNotDestroyed();
+    return GetDocument().GetLayoutView();
+  }
+  LocalFrameView* GetFrameView() const {
+    CheckIsNotDestroyed();
+    return GetDocument().View();
+  }
 
   bool IsRooted() const;
 
-  Node* GetNode() const { return IsAnonymous() ? nullptr : node_; }
+  Node* GetNode() const {
+    CheckIsNotDestroyed();
+    return IsAnonymous() ? nullptr : node_;
+  }
 
   Node* NonPseudoNode() const {
+    CheckIsNotDestroyed();
     return IsPseudoElement() ? nullptr : GetNode();
   }
 
-  void ClearNode() { node_ = nullptr; }
+  void ClearNode() {
+    CheckIsNotDestroyed();
+    node_ = nullptr;
+  }
 
   // Returns the styled node that caused the generation of this layoutObject.
   // This is the same as node() except for layoutObjects of :before, :after and
   // :first-letter pseudo elements for which their parent node is returned.
   Node* GeneratingNode() const {
+    CheckIsNotDestroyed();
     return IsPseudoElement() ? GetNode()->ParentOrShadowHostNode() : GetNode();
   }
 
   Document& GetDocument() const {
+    CheckIsNotDestroyed();
     DCHECK(node_ || Parent());  // crbug.com/402056
     return node_ ? node_->GetDocument() : Parent()->GetDocument();
   }
-  LocalFrame* GetFrame() const { return GetDocument().GetFrame(); }
+  LocalFrame* GetFrame() const {
+    CheckIsNotDestroyed();
+    return GetDocument().GetFrame();
+  }
 
   virtual LayoutMultiColumnSpannerPlaceholder* SpannerPlaceholder() const {
+    CheckIsNotDestroyed();
     return nullptr;
   }
   bool IsColumnSpanAll() const {
+    CheckIsNotDestroyed();
     return StyleRef().GetColumnSpan() == EColumnSpan::kAll &&
            SpannerPlaceholder();
   }
@@ -1299,6 +1729,7 @@
   // TODO(cbiesinger): Remove when buttons are implemented with align-items
   // instead of flex box. crbug.com/226252.
   bool BehavesLikeBlockContainer() const {
+    CheckIsNotDestroyed();
     return (IsLayoutBlockFlow() && StyleRef().IsDisplayBlockContainer()) ||
            IsButtonOrNGButton();
   }
@@ -1378,6 +1809,7 @@
   LayoutObject* ContainerForFixedPosition(AncestorSkipInfo* = nullptr) const;
 
   bool CanContainOutOfFlowPositionedElement(EPosition position) const {
+    CheckIsNotDestroyed();
     DCHECK(position == EPosition::kAbsolute || position == EPosition::kFixed);
     return (position == EPosition::kAbsolute &&
             CanContainAbsolutePositionObjects()) ||
@@ -1391,7 +1823,10 @@
   // This value gets cached by bitfields_.can_contain_fixed_position_objects_.
   bool ComputeIsFixedContainer(const ComputedStyle* style) const;
 
-  virtual LayoutObject* HoverAncestor() const { return Parent(); }
+  virtual LayoutObject* HoverAncestor() const {
+    CheckIsNotDestroyed();
+    return Parent();
+  }
 
   Element* OffsetParent(const Element* = nullptr) const;
 
@@ -1399,8 +1834,14 @@
   // marked too if needed.
   void SetNeedsCollectInlines();
   void SetChildNeedsCollectInlines();
-  void ClearNeedsCollectInlines() { SetNeedsCollectInlines(false); }
-  void SetNeedsCollectInlines(bool b) { bitfields_.SetNeedsCollectInlines(b); }
+  void ClearNeedsCollectInlines() {
+    CheckIsNotDestroyed();
+    SetNeedsCollectInlines(false);
+  }
+  void SetNeedsCollectInlines(bool b) {
+    CheckIsNotDestroyed();
+    bitfields_.SetNeedsCollectInlines(b);
+  }
 
   void MarkContainerChainForLayout(bool schedule_relayout = true,
                                    SubtreeLayoutScope* = nullptr);
@@ -1426,11 +1867,13 @@
 
   void SetNeedsLayoutAndIntrinsicWidthsRecalc(
       LayoutInvalidationReasonForTracing reason) {
+    CheckIsNotDestroyed();
     SetNeedsLayout(reason);
     SetIntrinsicLogicalWidthsDirty();
   }
   void SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
       LayoutInvalidationReasonForTracing reason) {
+    CheckIsNotDestroyed();
     SetNeedsLayoutAndFullPaintInvalidation(reason);
     SetIntrinsicLogicalWidthsDirty();
   }
@@ -1446,15 +1889,25 @@
   void InvalidateIntersectionObserverCachedRects();
 
   void SetPositionState(EPosition position) {
+    CheckIsNotDestroyed();
     DCHECK(
         (position != EPosition::kAbsolute && position != EPosition::kFixed) ||
         IsBox());
     bitfields_.SetPositionedState(position);
   }
-  void ClearPositionedState() { bitfields_.ClearPositionedState(); }
+  void ClearPositionedState() {
+    CheckIsNotDestroyed();
+    bitfields_.ClearPositionedState();
+  }
 
-  void SetFloating(bool is_floating) { bitfields_.SetFloating(is_floating); }
-  void SetInline(bool is_inline) { bitfields_.SetIsInline(is_inline); }
+  void SetFloating(bool is_floating) {
+    CheckIsNotDestroyed();
+    bitfields_.SetFloating(is_floating);
+  }
+  void SetInline(bool is_inline) {
+    CheckIsNotDestroyed();
+    bitfields_.SetIsInline(is_inline);
+  }
 
   // Return whether we can directly traverse fragments generated for this layout
   // object, when it comes to painting, hit-testing and other layout read
@@ -1468,57 +1921,97 @@
 
   // Returns the associated |NGPaintFragment|. When this is not a |nullptr|,
   // this is the root of an inline formatting context, laid out by LayoutNG.
-  virtual const NGPaintFragment* PaintFragment() const { return nullptr; }
+  virtual const NGPaintFragment* PaintFragment() const {
+    CheckIsNotDestroyed();
+    return nullptr;
+  }
 
   // Return true if |this| produces one or more inline fragments, including
   // whitespace-only text fragments.
-  virtual bool HasInlineFragments() const { return false; }
+  virtual bool HasInlineFragments() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   // Paint/Physical fragments are not in sync with LayoutObject tree until it is
   // laid out. For inline, it needs to check if the containing block is
   // layout-clean. crbug.com/963103
   bool IsFirstInlineFragmentSafe() const;
   void SetIsInLayoutNGInlineFormattingContext(bool);
-  virtual NGPaintFragment* FirstInlineFragment() const { return nullptr; }
-  virtual void SetFirstInlineFragment(NGPaintFragment*) {}
-  virtual wtf_size_t FirstInlineFragmentItemIndex() const { return 0u; }
-  virtual void ClearFirstInlineFragmentItemIndex() {}
-  virtual void SetFirstInlineFragmentItemIndex(wtf_size_t) {}
-  void SetForceLegacyLayout() { bitfields_.SetForceLegacyLayout(true); }
+  virtual NGPaintFragment* FirstInlineFragment() const {
+    CheckIsNotDestroyed();
+    return nullptr;
+  }
+  virtual void SetFirstInlineFragment(NGPaintFragment*) {
+    CheckIsNotDestroyed();
+  }
+  virtual wtf_size_t FirstInlineFragmentItemIndex() const {
+    CheckIsNotDestroyed();
+    return 0u;
+  }
+  virtual void ClearFirstInlineFragmentItemIndex() { CheckIsNotDestroyed(); }
+  virtual void SetFirstInlineFragmentItemIndex(wtf_size_t) {
+    CheckIsNotDestroyed();
+  }
+  void SetForceLegacyLayout() {
+    CheckIsNotDestroyed();
+    bitfields_.SetForceLegacyLayout(true);
+  }
 
   void SetHasBoxDecorationBackground(bool);
 
-  void SetIsText() { bitfields_.SetIsText(true); }
-  void SetIsBox() { bitfields_.SetIsBox(true); }
+  void SetIsText() {
+    CheckIsNotDestroyed();
+    bitfields_.SetIsText(true);
+  }
+  void SetIsBox() {
+    CheckIsNotDestroyed();
+    bitfields_.SetIsBox(true);
+  }
   void SetIsAtomicInlineLevel(bool is_atomic_inline_level) {
+    CheckIsNotDestroyed();
     bitfields_.SetIsAtomicInlineLevel(is_atomic_inline_level);
   }
   void SetHorizontalWritingMode(bool has_horizontal_writing_mode) {
+    CheckIsNotDestroyed();
     bitfields_.SetHorizontalWritingMode(has_horizontal_writing_mode);
   }
   void SetHasNonVisibleOverflow(bool has_non_visible_overflow) {
+    CheckIsNotDestroyed();
     bitfields_.SetHasNonVisibleOverflow(has_non_visible_overflow);
   }
   void SetShouldClipOverflow(bool should_clip_overflow) {
+    CheckIsNotDestroyed();
     bitfields_.SetShouldClipOverflow(should_clip_overflow);
   }
-  void SetHasLayer(bool has_layer) { bitfields_.SetHasLayer(has_layer); }
+  void SetHasLayer(bool has_layer) {
+    CheckIsNotDestroyed();
+    bitfields_.SetHasLayer(has_layer);
+  }
   void SetHasTransformRelatedProperty(bool has_transform) {
+    CheckIsNotDestroyed();
     bitfields_.SetHasTransformRelatedProperty(has_transform);
   }
   void SetHasReflection(bool has_reflection) {
+    CheckIsNotDestroyed();
     bitfields_.SetHasReflection(has_reflection);
   }
   void SetCanContainFixedPositionObjects(bool can_contain_fixed_position) {
+    CheckIsNotDestroyed();
     bitfields_.SetCanContainFixedPositionObjects(can_contain_fixed_position);
   }
   void SetIsEffectiveRootScroller(bool is_effective_root_scroller) {
+    CheckIsNotDestroyed();
     bitfields_.SetIsEffectiveRootScroller(is_effective_root_scroller);
   }
   void SetIsGlobalRootScroller(bool is_global_root_scroller) {
+    CheckIsNotDestroyed();
     bitfields_.SetIsGlobalRootScroller(is_global_root_scroller);
   }
-  void SetIsHTMLLegendElement() { bitfields_.SetIsHTMLLegendElement(true); }
+  void SetIsHTMLLegendElement() {
+    CheckIsNotDestroyed();
+    bitfields_.SetIsHTMLLegendElement(true);
+  }
 
   virtual void Paint(const PaintInfo&) const;
 
@@ -1538,13 +2031,15 @@
   virtual void UpdateLayout() = 0;
 
   void HandleSubtreeModifications();
-  virtual void SubtreeDidChange() {}
+  virtual void SubtreeDidChange() { CheckIsNotDestroyed(); }
 
   // Flags used to mark if an object consumes subtree change notifications.
   bool ConsumesSubtreeChangeNotification() const {
+    CheckIsNotDestroyed();
     return bitfields_.ConsumesSubtreeChangeNotification();
   }
   void SetConsumesSubtreeChangeNotification() {
+    CheckIsNotDestroyed();
     bitfields_.SetConsumesSubtreeChangeNotification(true);
   }
 
@@ -1552,6 +2047,7 @@
   void NotifyOfSubtreeChange();
   void NotifyAncestorsOfSubtreeChange();
   bool WasNotifiedOfSubtreeChange() const {
+    CheckIsNotDestroyed();
     return bitfields_.NotifiedOfSubtreeChange();
   }
 
@@ -1559,24 +2055,27 @@
   // descendants that they have had their child subtree changed.
   void RegisterSubtreeChangeListenerOnDescendants(bool);
   bool HasSubtreeChangeListenerRegistered() const {
+    CheckIsNotDestroyed();
     return bitfields_.SubtreeChangeListenerRegistered();
   }
 
   /* This function performs a layout only if one is needed. */
   DISABLE_CFI_PERF void LayoutIfNeeded() {
+    CheckIsNotDestroyed();
     if (NeedsLayout())
       UpdateLayout();
   }
 
   void ForceLayout();
   void ForceLayoutWithPaintInvalidation() {
+    CheckIsNotDestroyed();
     SetShouldDoFullPaintInvalidation();
     ForceLayout();
   }
 
   // Used for element state updates that cannot be fixed with a paint
   // invalidation and do not need a relayout.
-  virtual void UpdateFromElement() {}
+  virtual void UpdateFromElement() { CheckIsNotDestroyed(); }
 
   virtual void AddAnnotatedRegions(Vector<AnnotatedRegionValue>&);
 
@@ -1680,10 +2179,12 @@
   const LayoutBlock* InclusiveContainingBlock() const;
 
   bool CanContainAbsolutePositionObjects() const {
+    CheckIsNotDestroyed();
     return style_->CanContainAbsolutePositionObjects() ||
            CanContainFixedPositionObjects();
   }
   bool CanContainFixedPositionObjects() const {
+    CheckIsNotDestroyed();
     return bitfields_.CanContainFixedPositionObjects();
   }
 
@@ -1701,6 +2202,7 @@
   PhysicalRect AncestorToLocalRect(const LayoutBoxModelObject* ancestor,
                                    const PhysicalRect& rect,
                                    MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return PhysicalRect::EnclosingRect(
         AncestorToLocalQuad(ancestor, FloatRect(rect), mode).BoundingBox());
   }
@@ -1710,6 +2212,7 @@
   PhysicalOffset AncestorToLocalPoint(const LayoutBoxModelObject* ancestor,
                                       const PhysicalOffset& p,
                                       MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return PhysicalOffset::FromFloatPointRound(
         AncestorToLocalFloatPoint(ancestor, FloatPoint(p), mode));
   }
@@ -1735,6 +2238,7 @@
   FloatQuad LocalRectToAncestorQuad(const PhysicalRect& rect,
                                     const LayoutBoxModelObject* ancestor,
                                     MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return LocalToAncestorQuad(FloatRect(rect), ancestor, mode);
   }
   FloatQuad LocalToAncestorQuad(const FloatQuad&,
@@ -1743,6 +2247,7 @@
   PhysicalOffset LocalToAncestorPoint(const PhysicalOffset& p,
                                       const LayoutBoxModelObject* ancestor,
                                       MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return PhysicalOffset::FromFloatPointRound(
         LocalToAncestorFloatPoint(FloatPoint(p), ancestor, mode));
   }
@@ -1763,6 +2268,7 @@
       MapCoordinatesFlags = 0) const;
   TransformationMatrix LocalToAbsoluteTransform(
       MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return LocalToAncestorTransform(nullptr, mode);
   }
 
@@ -1772,38 +2278,47 @@
   // This method supports kUseGeometryMapperMode.
   PhysicalRect LocalToAbsoluteRect(const PhysicalRect& rect,
                                    MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return LocalToAncestorRect(rect, nullptr, mode);
   }
   FloatQuad LocalRectToAbsoluteQuad(const PhysicalRect& rect,
                                     MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return LocalRectToAncestorQuad(rect, nullptr, mode);
   }
   FloatQuad LocalToAbsoluteQuad(const FloatQuad& quad,
                                 MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return LocalToAncestorQuad(quad, nullptr, mode);
   }
   PhysicalOffset LocalToAbsolutePoint(const PhysicalOffset& p,
                                       MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return LocalToAncestorPoint(p, nullptr, mode);
   }
   FloatPoint LocalToAbsoluteFloatPoint(const FloatPoint& p,
                                        MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return LocalToAncestorFloatPoint(p, nullptr, mode);
   }
   PhysicalRect AbsoluteToLocalRect(const PhysicalRect& rect,
                                    MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return AncestorToLocalRect(nullptr, rect, mode);
   }
   FloatQuad AbsoluteToLocalQuad(const FloatQuad& quad,
                                 MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return AncestorToLocalQuad(nullptr, quad, mode);
   }
   PhysicalOffset AbsoluteToLocalPoint(const PhysicalOffset& p,
                                       MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return AncestorToLocalPoint(nullptr, p, mode);
   }
   FloatPoint AbsoluteToLocalFloatPoint(const FloatPoint& p,
                                        MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
     return AncestorToLocalFloatPoint(nullptr, p, mode);
   }
 
@@ -1836,7 +2351,9 @@
 
   // Build an array of quads in absolute coords for line boxes
   virtual void AbsoluteQuads(Vector<FloatQuad>&,
-                             MapCoordinatesFlags mode = 0) const {}
+                             MapCoordinatesFlags mode = 0) const {
+    CheckIsNotDestroyed();
+  }
 
   // The bounding box (see: absoluteBoundingBoxRect) including all descendant
   // bounding boxes.
@@ -1860,13 +2377,20 @@
   // https://drafts.csswg.org/css-sizing-3/#min-content-inline-size
   // https://drafts.csswg.org/css-sizing-3/#max-content-inline-size
   // TODO(jchaffraix): We will probably want to rename it to match CSS 3.
-  virtual MinMaxSizes PreferredLogicalWidths() const { return MinMaxSizes(); }
+  virtual MinMaxSizes PreferredLogicalWidths() const {
+    CheckIsNotDestroyed();
+    return MinMaxSizes();
+  }
 
-  const ComputedStyle* Style() const { return style_.get(); }
+  const ComputedStyle* Style() const {
+    CheckIsNotDestroyed();
+    return style_.get();
+  }
 
   // style_ can only be nullptr before the first style is set, thus most
   // callers will never see a nullptr style and should use StyleRef().
   const ComputedStyle& StyleRef() const {
+    CheckIsNotDestroyed();
     DCHECK(style_);
     return *style_;
   }
@@ -1880,6 +2404,7 @@
   inline const ComputedStyle& StyleRef(bool first_line) const;
 
   const ComputedStyle& EffectiveStyle(NGStyleVariant style_variant) const {
+    CheckIsNotDestroyed();
     return style_variant == NGStyleVariant::kStandard
                ? StyleRef()
                : SlowEffectiveStyle(style_variant);
@@ -1891,6 +2416,7 @@
   }
 
   inline Color ResolveColor(const CSSProperty& color_property) const {
+    CheckIsNotDestroyed();
     return StyleRef().VisitedDependentColor(color_property);
   }
 
@@ -1914,6 +2440,7 @@
   // LayoutSVGRoot) should use VisualRectInLocalSVGCoordinates() and map with
   // SVG transforms instead.
   PhysicalRect LocalVisualRect() const {
+    CheckIsNotDestroyed();
     if (StyleRef().Visibility() != EVisibility::kVisible &&
         VisualRectRespectsVisibility())
       return PhysicalRect();
@@ -1966,6 +2493,7 @@
   // Do a rect-based hit test with this object as the stop node.
   HitTestResult HitTestForOcclusion(const PhysicalRect&) const;
   HitTestResult HitTestForOcclusion() const {
+    CheckIsNotDestroyed();
     return HitTestForOcclusion(VisualRectInDocument());
   }
 
@@ -1973,12 +2501,17 @@
   // flow-thread coordinates) lives. This is used to convert a flow-thread point
   // to a point in the containing coordinate space.
   virtual LayoutSize ColumnOffset(const LayoutPoint&) const {
+    CheckIsNotDestroyed();
     return LayoutSize();
   }
 
-  virtual unsigned length() const { return 1; }
+  virtual unsigned length() const {
+    CheckIsNotDestroyed();
+    return 1;
+  }
 
   bool IsFloatingOrOutOfFlowPositioned() const {
+    CheckIsNotDestroyed();
     return (IsFloating() || IsOutOfFlowPositioned());
   }
 
@@ -1987,21 +2520,27 @@
   // generating an anonymous block box for the whitespace between the marker
   // and the <ol>.
   bool AffectsWhitespaceSiblings() const {
+    CheckIsNotDestroyed();
     return !IsFloatingOrOutOfFlowPositioned() &&
            !IsLayoutNGOutsideListMarker() && !IsOutsideListMarker();
   }
 
   // Not returning StyleRef().BoxReflect() because some objects ignore the
   // reflection style (e.g. LayoutInline, LayoutSVGBlock).
-  bool HasReflection() const { return bitfields_.HasReflection(); }
+  bool HasReflection() const {
+    CheckIsNotDestroyed();
+    return bitfields_.HasReflection();
+  }
 
   // The current selection state for an object.  For blocks, the state refers to
   // the state of the leaf descendants (as described above in the SelectionState
   // enum declaration).
   SelectionState GetSelectionState() const {
+    CheckIsNotDestroyed();
     return bitfields_.GetSelectionState();
   }
   void SetSelectionState(SelectionState state) {
+    CheckIsNotDestroyed();
     bitfields_.SetSelectionState(state);
   }
   bool CanUpdateSelectionOnRootLineBoxes() const;
@@ -2010,6 +2549,7 @@
   // object. Used to determine the tightest possible bounding box for the
   // selection. The rect is in the object's local physical coordinate space.
   virtual PhysicalRect LocalSelectionVisualRect() const {
+    CheckIsNotDestroyed();
     return PhysicalRect();
   }
 
@@ -2035,6 +2575,7 @@
       const InlineBox* inline_box,
       int caret_offset,
       LayoutUnit* extra_width_to_end_of_line = nullptr) const {
+    CheckIsNotDestroyed();
     return FlipForWritingMode(
         LocalCaretRect(inline_box, caret_offset, extra_width_to_end_of_line));
   }
@@ -2050,17 +2591,30 @@
 
   // Virtual function helpers for the deprecated Flexible Box Layout (display:
   // -webkit-box).
-  virtual bool IsDeprecatedFlexibleBox() const { return false; }
+  virtual bool IsDeprecatedFlexibleBox() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   // Virtual function helper for the new FlexibleBox Layout (display:
   // -webkit-flex).
-  virtual bool IsFlexibleBox() const { return false; }
+  virtual bool IsFlexibleBox() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
-  virtual bool IsFlexibleBoxIncludingDeprecatedAndNG() const { return false; }
+  virtual bool IsFlexibleBoxIncludingDeprecatedAndNG() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
-  virtual bool IsFlexibleBoxIncludingNG() const { return false; }
+  virtual bool IsFlexibleBoxIncludingNG() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   bool IsListItemIncludingNG() const {
+    CheckIsNotDestroyed();
     return IsListItem() || IsLayoutNGListItem();
   }
 
@@ -2081,50 +2635,64 @@
   bool IsOutsideListMarker() const;
   // Any kind of legacy list marker.
   bool IsListMarker() const {
+    CheckIsNotDestroyed();
     return IsListMarkerForNormalContent() ||
            IsInsideListMarkerForCustomContent() ||
            IsOutsideListMarkerForCustomContent();
   }
   // Any kind of LayoutBox list marker.
   bool IsBoxListMarkerIncludingNG() const {
+    CheckIsNotDestroyed();
     return IsListMarkerForNormalContent() ||
            IsOutsideListMarkerForCustomContent() ||
            IsLayoutNGOutsideListMarker();
   }
   // Any kind of LayoutNG list marker.
   bool IsLayoutNGListMarker() const {
+    CheckIsNotDestroyed();
     return IsLayoutNGInsideListMarker() || IsLayoutNGOutsideListMarker();
   }
   // Any kind of list marker.
   bool IsListMarkerIncludingAll() const {
+    CheckIsNotDestroyed();
     return IsListMarker() || IsLayoutNGListMarker();
   }
 
-  virtual bool IsCombineText() const { return false; }
+  virtual bool IsCombineText() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   virtual int CaretMinOffset() const;
   virtual int CaretMaxOffset() const;
 
   // ImageResourceObserver override.
   void ImageChanged(ImageResourceContent*, CanDeferInvalidation) final;
-  void ImageChanged(WrappedImagePtr, CanDeferInvalidation) override {}
+  void ImageChanged(WrappedImagePtr, CanDeferInvalidation) override {
+    CheckIsNotDestroyed();
+  }
   void ImageNotifyFinished(ImageResourceContent*) override;
   void NotifyImageFullyRemoved(ImageResourceContent*) override;
   bool WillRenderImage() final;
   bool GetImageAnimationPolicy(web_pref::ImageAnimationPolicy&) final;
 
   void Remove() {
+    CheckIsNotDestroyed();
     if (Parent())
       Parent()->RemoveChild(this);
   }
 
   bool VisibleToHitTestRequest(const HitTestRequest& request) const {
+    CheckIsNotDestroyed();
     return StyleRef().Visibility() == EVisibility::kVisible &&
            (request.IgnorePointerEventsNone() ||
             StyleRef().PointerEvents() != EPointerEvents::kNone);
   }
 
-  bool VisibleToHitTesting() const { return StyleRef().VisibleToHitTesting(); }
+  bool VisibleToHitTesting() const {
+    CheckIsNotDestroyed();
+    return StyleRef().VisibleToHitTesting();
+  }
 
   // Map points and quads through elements, potentially via 3d transforms. You
   // should never need to call these directly; use localToAbsolute/
@@ -2156,6 +2724,7 @@
                                  TransformationMatrix&) const;
 
   bool CreatesGroup() const {
+    CheckIsNotDestroyed();
     // See |HasReflection()| for why |StyleRef().BoxReflect()| is not used.
     return StyleRef().HasGroupingProperty(HasReflection());
   }
@@ -2168,13 +2737,16 @@
   // rects also cover continuations.
   virtual void AddOutlineRects(Vector<PhysicalRect>&,
                                const PhysicalOffset& additional_offset,
-                               NGOutlineType) const {}
+                               NGOutlineType) const {
+    CheckIsNotDestroyed();
+  }
 
   // For history and compatibility reasons, we draw outline:auto (for focus
   // rings) and normal style outline differently.
   // Focus rings enclose block visual overflows (of line boxes and descendants),
   // while normal outlines don't.
   NGOutlineType OutlineRectsShouldIncludeBlockVisualOverflow() const {
+    CheckIsNotDestroyed();
     return StyleRef().OutlineStyleIsAuto()
                ? NGOutlineType::kIncludeBlockVisualOverflow
                : NGOutlineType::kDontIncludeBlockVisualOverflow;
@@ -2182,6 +2754,7 @@
 
   // Only public for LayoutNG.
   void SetContainsInlineWithOutlineAndContinuation(bool b) {
+    CheckIsNotDestroyed();
     bitfields_.SetContainsInlineWithOutlineAndContinuation(b);
   }
 
@@ -2191,15 +2764,18 @@
   bool IsRelayoutBoundary() const;
 
   void SetSelfNeedsLayoutForAvailableSpace(bool flag) {
+    CheckIsNotDestroyed();
     bitfields_.SetSelfNeedsLayoutForAvailableSpace(flag);
     if (flag)
       MarkSelfPaintingLayerForVisualOverflowRecalc();
   }
 
   PaintInvalidationReason FullPaintInvalidationReason() const {
+    CheckIsNotDestroyed();
     return full_paint_invalidation_reason_;
   }
   bool ShouldDoFullPaintInvalidation() const {
+    CheckIsNotDestroyed();
     if (!ShouldDelayFullPaintInvalidation() &&
         full_paint_invalidation_reason_ != PaintInvalidationReason::kNone) {
       DCHECK(IsFullPaintInvalidationReason(full_paint_invalidation_reason_));
@@ -2226,24 +2802,29 @@
   void ClearPaintInvalidationFlags();
 
   bool ShouldCheckForPaintInvalidation() const {
+    CheckIsNotDestroyed();
     return bitfields_.ShouldCheckForPaintInvalidation();
   }
   void SetShouldCheckForPaintInvalidation();
   void SetShouldCheckForPaintInvalidationWithoutGeometryChange();
 
   bool SubtreeShouldCheckForPaintInvalidation() const {
+    CheckIsNotDestroyed();
     return bitfields_.SubtreeShouldCheckForPaintInvalidation();
   }
   void SetSubtreeShouldCheckForPaintInvalidation();
 
   bool ShouldCheckGeometryForPaintInvalidation() const {
+    CheckIsNotDestroyed();
     return bitfields_.ShouldCheckGeometryForPaintInvalidation();
   }
   bool DescendantShouldCheckGeometryForPaintInvalidation() const {
+    CheckIsNotDestroyed();
     return bitfields_.DescendantShouldCheckGeometryForPaintInvalidation();
   }
 
   bool MayNeedPaintInvalidationAnimatedBackgroundImage() const {
+    CheckIsNotDestroyed();
     return bitfields_.MayNeedPaintInvalidationAnimatedBackgroundImage();
   }
   void SetMayNeedPaintInvalidationAnimatedBackgroundImage();
@@ -2251,6 +2832,7 @@
   void SetSubtreeShouldDoFullPaintInvalidation(
       PaintInvalidationReason reason = PaintInvalidationReason::kSubtree);
   bool SubtreeShouldDoFullPaintInvalidation() const {
+    CheckIsNotDestroyed();
     DCHECK(!bitfields_.SubtreeShouldDoFullPaintInvalidation() ||
            ShouldDoFullPaintInvalidation());
     return bitfields_.SubtreeShouldDoFullPaintInvalidation();
@@ -2260,11 +2842,13 @@
   // delayed until a future frame. This can be the case for an object whose
   // content is not visible to the user.
   bool ShouldDelayFullPaintInvalidation() const {
+    CheckIsNotDestroyed();
     return bitfields_.ShouldDelayFullPaintInvalidation();
   }
   void SetShouldDelayFullPaintInvalidation();
 
   bool ShouldInvalidateSelection() const {
+    CheckIsNotDestroyed();
     return bitfields_.ShouldInvalidateSelection();
   }
   void SetShouldInvalidateSelection();
@@ -2288,13 +2872,16 @@
   // Get the dedicated DisplayItemClient for selection. Returns nullptr if this
   // object doesn't have a dedicated DisplayItemClient.
   virtual const DisplayItemClient* GetSelectionDisplayItemClient() const {
+    CheckIsNotDestroyed();
     return nullptr;
   }
 
   // Called before setting style for existing/new anonymous child. Override to
   // set custom styles for the child. For new anonymous child, |child| is null.
   virtual void UpdateAnonymousChildStyle(const LayoutObject* child,
-                                         ComputedStyle& style) const {}
+                                         ComputedStyle& style) const {
+    CheckIsNotDestroyed();
+  }
 
   // Returns a rect corresponding to this LayoutObject's bounds for use in
   // debugging output
@@ -2303,7 +2890,10 @@
   // Each LayoutObject has one or more painting fragments (exactly one
   // in the absence of multicol/pagination).
   // See ../paint/README.md for more on fragments.
-  const FragmentData& FirstFragment() const { return fragment_; }
+  const FragmentData& FirstFragment() const {
+    CheckIsNotDestroyed();
+    return fragment_;
+  }
 
   enum OverflowRecalcType {
     kOnlyVisualOverflowRecalc,
@@ -2321,17 +2911,20 @@
   // The allowed touch action is the union of the effective touch action
   // (from style) and blocking touch event handlers.
   TouchAction EffectiveAllowedTouchAction() const {
+    CheckIsNotDestroyed();
     if (InsideBlockingTouchEventHandler())
       return TouchAction::kNone;
     return StyleRef().GetEffectiveTouchAction();
   }
   bool HasEffectiveAllowedTouchAction() const {
+    CheckIsNotDestroyed();
     return EffectiveAllowedTouchAction() != TouchAction::kAuto;
   }
 
   // Whether this object's Node has a blocking touch event handler on itself
   // or an ancestor.
   bool InsideBlockingTouchEventHandler() const {
+    CheckIsNotDestroyed();
     return bitfields_.InsideBlockingTouchEventHandler();
   }
   // Mark this object as having a |EffectiveAllowedTouchAction| changed, and
@@ -2339,12 +2932,15 @@
   // PrePaint tree walk to update effective allowed touch action.
   void MarkEffectiveAllowedTouchActionChanged();
   bool EffectiveAllowedTouchActionChanged() const {
+    CheckIsNotDestroyed();
     return bitfields_.EffectiveAllowedTouchActionChanged();
   }
   bool DescendantEffectiveAllowedTouchActionChanged() const {
+    CheckIsNotDestroyed();
     return bitfields_.DescendantEffectiveAllowedTouchActionChanged();
   }
   void UpdateInsideBlockingTouchEventHandler(bool inside) {
+    CheckIsNotDestroyed();
     bitfields_.SetInsideBlockingTouchEventHandler(inside);
   }
 
@@ -2452,6 +3048,7 @@
     LayoutObject& layout_object_;
   };
   MutableForPainting GetMutableForPainting() const {
+    CheckIsNotDestroyed();
     return MutableForPainting(*this);
   }
 
@@ -2466,44 +3063,54 @@
   void SetNeedsPaintPropertyUpdate();
   void SetNeedsPaintPropertyUpdatePreservingCachedRects();
   bool NeedsPaintPropertyUpdate() const {
+    CheckIsNotDestroyed();
     return bitfields_.NeedsPaintPropertyUpdate();
   }
 
   void AddSubtreePaintPropertyUpdateReason(
       SubtreePaintPropertyUpdateReason reason) {
+    CheckIsNotDestroyed();
     bitfields_.AddSubtreePaintPropertyUpdateReason(reason);
     SetNeedsPaintPropertyUpdate();
   }
   unsigned SubtreePaintPropertyUpdateReasons() const {
+    CheckIsNotDestroyed();
     return bitfields_.SubtreePaintPropertyUpdateReasons();
   }
   bool DescendantNeedsPaintPropertyUpdate() const {
+    CheckIsNotDestroyed();
     return bitfields_.DescendantNeedsPaintPropertyUpdate();
   }
   // Main thread scrolling reasons require fully updating paint propeties of all
   // ancestors (see: ScrollPaintPropertyNode.h).
   void SetAncestorsNeedPaintPropertyUpdateForMainThreadScrolling();
 
-  void SetIsScrollAnchorObject() { bitfields_.SetIsScrollAnchorObject(true); }
+  void SetIsScrollAnchorObject() {
+    CheckIsNotDestroyed();
+    bitfields_.SetIsScrollAnchorObject(true);
+  }
   // Clears the IsScrollAnchorObject bit if and only if no ScrollAnchors still
   // reference this LayoutObject.
   void MaybeClearIsScrollAnchorObject();
 
   bool ScrollAnchorDisablingStyleChanged() {
+    CheckIsNotDestroyed();
     return bitfields_.ScrollAnchorDisablingStyleChanged();
   }
   void SetScrollAnchorDisablingStyleChanged(bool changed) {
+    CheckIsNotDestroyed();
     bitfields_.SetScrollAnchorDisablingStyleChanged(changed);
   }
 
-
   bool CompositedScrollsWithRespectTo(
       const LayoutBoxModelObject& paint_invalidation_container) const;
 
   BackgroundPaintLocation GetBackgroundPaintLocation() const {
+    CheckIsNotDestroyed();
     return bitfields_.GetBackgroundPaintLocation();
   }
   void SetBackgroundPaintLocation(BackgroundPaintLocation location) {
+    CheckIsNotDestroyed();
     if (GetBackgroundPaintLocation() != location) {
       SetBackgroundNeedsFullPaintInvalidation();
       bitfields_.SetBackgroundPaintLocation(location);
@@ -2511,38 +3118,46 @@
   }
 
   bool IsBackgroundAttachmentFixedObject() const {
+    CheckIsNotDestroyed();
     return bitfields_.IsBackgroundAttachmentFixedObject();
   }
 
   bool BackgroundNeedsFullPaintInvalidation() const {
+    CheckIsNotDestroyed();
     return !ShouldDelayFullPaintInvalidation() &&
            bitfields_.BackgroundNeedsFullPaintInvalidation();
   }
   void SetBackgroundNeedsFullPaintInvalidation() {
+    CheckIsNotDestroyed();
     SetShouldDoFullPaintInvalidationWithoutGeometryChange(
         PaintInvalidationReason::kBackground);
     bitfields_.SetBackgroundNeedsFullPaintInvalidation(true);
   }
 
   bool ContainsInlineWithOutlineAndContinuation() const {
+    CheckIsNotDestroyed();
     return bitfields_.ContainsInlineWithOutlineAndContinuation();
   }
 
   void SetOutlineMayBeAffectedByDescendants(bool b) {
+    CheckIsNotDestroyed();
     bitfields_.SetOutlineMayBeAffectedByDescendants(b);
   }
 
   inline bool ChildLayoutBlockedByDisplayLock() const {
+    CheckIsNotDestroyed();
     auto* context = GetDisplayLockContext();
     return context && !context->ShouldLayoutChildren();
   }
 
   bool ChildPrePaintBlockedByDisplayLock() const {
+    CheckIsNotDestroyed();
     auto* context = GetDisplayLockContext();
     return context && !context->ShouldPrePaintChildren();
   }
 
   bool ChildPaintBlockedByDisplayLock() const {
+    CheckIsNotDestroyed();
     auto* context = GetDisplayLockContext();
     return context && !context->ShouldPaintChildren();
   }
@@ -2550,18 +3165,24 @@
   // This flag caches StyleRef().HasBorderDecoration() &&
   // !Table()->ShouldCollapseBorders().
   bool HasNonCollapsedBorderDecoration() const {
+    CheckIsNotDestroyed();
     // We can only ensure this flag is up-to-date after PrePaint.
     DCHECK_GE(GetDocument().Lifecycle().GetState(),
               DocumentLifecycle::kPrePaintClean);
     return bitfields_.HasNonCollapsedBorderDecoration();
   }
   void SetHasNonCollapsedBorderDecoration(bool b) {
+    CheckIsNotDestroyed();
     bitfields_.SetHasNonCollapsedBorderDecoration(b);
   }
 
-  bool BeingDestroyed() const { return bitfields_.BeingDestroyed(); }
+  bool BeingDestroyed() const {
+    CheckIsNotDestroyed();
+    return bitfields_.BeingDestroyed();
+  }
 
   DisplayLockContext* GetDisplayLockContext() const {
+    CheckIsNotDestroyed();
     if (!RuntimeEnabledFeatures::CSSContentVisibilityEnabled())
       return nullptr;
     auto* element = DynamicTo<Element>(GetNode());
@@ -2571,25 +3192,32 @@
   }
 
   void SetDocumentForAnonymous(Document* document) {
+    CheckIsNotDestroyed();
     DCHECK(IsAnonymous());
     node_ = document;
   }
 
   bool IsLayoutNGObjectForListMarkerImage() const {
+    CheckIsNotDestroyed();
     DCHECK(IsListMarkerImage());
     return bitfields_.IsLayoutNGObjectForListMarkerImage();
   }
   void SetIsLayoutNGObjectForListMarkerImage(bool b) {
+    CheckIsNotDestroyed();
     DCHECK(IsListMarkerImage());
     bitfields_.SetIsLayoutNGObjectForListMarkerImage(b);
   }
 
   bool PreviousVisibilityVisible() const {
+    CheckIsNotDestroyed();
     return bitfields_.PreviousVisibilityVisible();
   }
 
   // See LocalVisualRect().
-  virtual bool VisualRectRespectsVisibility() const { return true; }
+  virtual bool VisualRectRespectsVisibility() const {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
  protected:
   enum LayoutObjectType {
@@ -2670,7 +3298,10 @@
     kLayoutObjectSVGResourceContainer,
     kLayoutObjectSVGFilterPrimitive,
   };
-  virtual bool IsOfType(LayoutObjectType type) const { return false; }
+  virtual bool IsOfType(LayoutObjectType type) const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   // While the |DeleteThis()| method is virtual, this should only be overridden
   // in very rare circumstances.
@@ -2679,7 +3310,10 @@
   // |LayoutEmbeddedContent| overrides |DeleteThis()| for this purpose).
   virtual void DeleteThis();
 
-  void SetBeingDestroyedForTesting() { bitfields_.SetBeingDestroyed(true); }
+  void SetBeingDestroyedForTesting() {
+    CheckIsNotDestroyed();
+    bitfields_.SetBeingDestroyed(true);
+  }
 
   const ComputedStyle& SlowEffectiveStyle(NGStyleVariant style_variant) const;
 
@@ -2687,6 +3321,7 @@
   // of the object, and so only should be called when the style is known not to
   // have changed (or from SetStyle).
   void SetStyleInternal(scoped_refptr<const ComputedStyle> style) {
+    CheckIsNotDestroyed();
     style_ = std::move(style);
   }
   // Overrides should call the superclass at the end. style_ will be 0 the
@@ -2700,9 +3335,14 @@
   // propagated via propagateStyleToAnonymousChildren(), but rather rely on
   // other custom mechanisms (if they need to be notified of parent style
   // changes at all).
-  virtual bool AnonymousHasStylePropagationOverride() { return false; }
+  virtual bool AnonymousHasStylePropagationOverride() {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
-  virtual void InLayoutNGInlineFormattingContextWillChange(bool) {}
+  virtual void InLayoutNGInlineFormattingContextWillChange(bool) {
+    CheckIsNotDestroyed();
+  }
 
   // A fast path for MapToVisualRectInAncestorSpace for when GeometryMapper
   // can be used. |intersects| is set to whether the input rect intersected
@@ -2743,7 +3383,10 @@
 
   void SetIsBackgroundAttachmentFixedObject(bool);
 
-  void SetEverHadLayout() { bitfields_.SetEverHadLayout(true); }
+  void SetEverHadLayout() {
+    CheckIsNotDestroyed();
+    bitfields_.SetEverHadLayout(true);
+  }
 
   // Remove this object and all descendants from the containing
   // LayoutFlowThread.
@@ -2752,7 +3395,10 @@
   // See LocalVisualRect().
   virtual PhysicalRect LocalVisualRectIgnoringVisibility() const;
 
-  virtual bool CanBeSelectionLeafInternal() const { return false; }
+  virtual bool CanBeSelectionLeafInternal() const {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   virtual PhysicalOffset OffsetFromContainerInternal(
       const LayoutObject*,
@@ -2761,16 +3407,19 @@
                                                bool ignore_scroll_offset) const;
 
   void NotifyDisplayLockDidLayoutChildren() {
+    CheckIsNotDestroyed();
     if (auto* context = GetDisplayLockContext())
       context->DidLayoutChildren();
   }
 
   bool BackgroundIsKnownToBeObscured() const {
+    CheckIsNotDestroyed();
     DCHECK_GE(GetDocument().Lifecycle().GetState(),
               DocumentLifecycle::kInPrePaint);
     return bitfields_.BackgroundIsKnownToBeObscured();
   }
   void SetBackgroundIsKnownToBeObscured(bool b) {
+    CheckIsNotDestroyed();
     DCHECK_EQ(GetDocument().Lifecycle().GetState(),
               DocumentLifecycle::kInPrePaint);
     bitfields_.SetBackgroundIsKnownToBeObscured(b);
@@ -2792,6 +3441,12 @@
   // object is really in the first line which is unknown before layout.
   const ComputedStyle* FirstLineStyleWithoutFallback() const;
 
+  // Should be called at the beginning of every method to ensure we are not
+  // accessing a LayoutObject after the Desroy() call.
+  void CheckIsNotDestroyed() const {
+    // TODO(keishi): Implement once LayoutObject is GCed.
+  }
+
  private:
   bool LocalToAncestorRectFastPath(const PhysicalRect& rect,
                                    const LayoutBoxModelObject* ancestor,
@@ -2844,7 +3499,10 @@
   void CheckBlockPositionedObjectsNeedLayout();
 #endif
 
-  bool IsTextOrSVGChild() const { return IsText() || IsSVGChild(); }
+  bool IsTextOrSVGChild() const {
+    CheckIsNotDestroyed();
+    return IsText() || IsSVGChild();
+  }
 
   static bool IsAllowedToModifyLayoutTreeStructure(Document&);
 
@@ -3368,16 +4026,23 @@
   LayoutObjectBitfields bitfields_;
 
   void SetSelfNeedsLayoutForStyle(bool b) {
+    CheckIsNotDestroyed();
     bitfields_.SetSelfNeedsLayoutForStyle(b);
   }
   void SetNeedsPositionedMovementLayout(bool b) {
+    CheckIsNotDestroyed();
     bitfields_.SetNeedsPositionedMovementLayout(b);
   }
   void SetNormalChildNeedsLayout(bool b) {
+    CheckIsNotDestroyed();
     bitfields_.SetNormalChildNeedsLayout(b);
   }
-  void SetPosChildNeedsLayout(bool b) { bitfields_.SetPosChildNeedsLayout(b); }
+  void SetPosChildNeedsLayout(bool b) {
+    CheckIsNotDestroyed();
+    bitfields_.SetPosChildNeedsLayout(b);
+  }
   void SetNeedsSimplifiedNormalFlowLayout(bool b) {
+    CheckIsNotDestroyed();
     bitfields_.SetNeedsSimplifiedNormalFlowLayout(b);
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_outside_list_marker.cc b/third_party/blink/renderer/core/layout/layout_outside_list_marker.cc
index 812b3fa..521ae89 100644
--- a/third_party/blink/renderer/core/layout/layout_outside_list_marker.cc
+++ b/third_party/blink/renderer/core/layout/layout_outside_list_marker.cc
@@ -12,10 +12,12 @@
 LayoutOutsideListMarker::~LayoutOutsideListMarker() = default;
 
 bool LayoutOutsideListMarker::IsMarkerImage() const {
+  CheckIsNotDestroyed();
   return list_marker_.IsMarkerImage(*this);
 }
 
 void LayoutOutsideListMarker::UpdateLayout() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::UpdateLayout();
 
   LayoutUnit block_offset = LogicalTop();
@@ -34,6 +36,7 @@
 }
 
 void LayoutOutsideListMarker::UpdateMargins() {
+  CheckIsNotDestroyed();
   LayoutUnit margin_start;
   LayoutUnit margin_end;
   std::tie(margin_start, margin_end) = ListMarker::InlineMarginsForOutside(
@@ -47,6 +50,7 @@
     bool first_line,
     LineDirectionMode direction,
     LinePositionMode line_position_mode) const {
+  CheckIsNotDestroyed();
   if (line_position_mode == kPositionOfInteriorLineBoxes) {
     return list_marker_.ListItemBlockFlow(*this)->LineHeight(
         first_line, direction, line_position_mode);
@@ -59,6 +63,7 @@
     bool first_line,
     LineDirectionMode direction,
     LinePositionMode line_position_mode) const {
+  CheckIsNotDestroyed();
   if (line_position_mode == kPositionOfInteriorLineBoxes) {
     return list_marker_.ListItemBlockFlow(*this)->BaselinePosition(
         baseline_type, first_line, direction, line_position_mode);
diff --git a/third_party/blink/renderer/core/layout/layout_outside_list_marker.h b/third_party/blink/renderer/core/layout/layout_outside_list_marker.h
index 210bf25..ce32449 100644
--- a/third_party/blink/renderer/core/layout/layout_outside_list_marker.h
+++ b/third_party/blink/renderer/core/layout/layout_outside_list_marker.h
@@ -18,19 +18,30 @@
   explicit LayoutOutsideListMarker(Element*);
   ~LayoutOutsideListMarker() override;
 
-  const char* GetName() const override { return "LayoutOutsideListMarker"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutOutsideListMarker";
+  }
 
   bool IsMarkerImage() const;
   LayoutUnit ListItemInlineStartOffset() const {
+    CheckIsNotDestroyed();
     return list_item_inline_start_offset_;
   }
   void UpdateMargins();
 
-  const ListMarker& Marker() const { return list_marker_; }
-  ListMarker& Marker() { return list_marker_; }
+  const ListMarker& Marker() const {
+    CheckIsNotDestroyed();
+    return list_marker_;
+  }
+  ListMarker& Marker() {
+    CheckIsNotDestroyed();
+    return list_marker_;
+  }
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectOutsideListMarker ||
            LayoutBlockFlow::IsOfType(type);
   }
diff --git a/third_party/blink/renderer/core/layout/layout_progress.cc b/third_party/blink/renderer/core/layout/layout_progress.cc
index 62d8d54..b936dfa8b 100644
--- a/third_party/blink/renderer/core/layout/layout_progress.cc
+++ b/third_party/blink/renderer/core/layout/layout_progress.cc
@@ -49,6 +49,7 @@
 LayoutProgress::~LayoutProgress() = default;
 
 void LayoutProgress::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   if (animating_) {
     animation_timer_.Stop();
     animating_ = false;
@@ -57,6 +58,7 @@
 }
 
 void LayoutProgress::UpdateFromElement() {
+  CheckIsNotDestroyed();
   HTMLProgressElement* element = ProgressElement();
   if (position_ == element->position())
     return;
@@ -68,6 +70,7 @@
 }
 
 double LayoutProgress::AnimationProgress() const {
+  CheckIsNotDestroyed();
   if (!animating_)
     return 0;
   const base::TimeDelta elapsed =
@@ -76,25 +79,30 @@
 }
 
 bool LayoutProgress::IsDeterminate() const {
+  CheckIsNotDestroyed();
   return (HTMLProgressElement::kIndeterminatePosition != GetPosition() &&
           HTMLProgressElement::kInvalidPosition != GetPosition());
 }
 
 bool LayoutProgress::IsAnimationTimerActive() const {
+  CheckIsNotDestroyed();
   return animation_timer_.IsActive();
 }
 
 bool LayoutProgress::IsAnimating() const {
+  CheckIsNotDestroyed();
   return animating_;
 }
 
 void LayoutProgress::AnimationTimerFired(TimerBase*) {
+  CheckIsNotDestroyed();
   SetShouldDoFullPaintInvalidation();
   if (!animation_timer_.IsActive() && animating_)
     animation_timer_.StartOneShot(kAnimationInterval, FROM_HERE);
 }
 
 void LayoutProgress::UpdateAnimationState() {
+  CheckIsNotDestroyed();
   bool animating = !IsDeterminate() && StyleRef().HasEffectiveAppearance();
   if (animating == animating_)
     return;
@@ -109,6 +117,7 @@
 }
 
 HTMLProgressElement* LayoutProgress::ProgressElement() const {
+  CheckIsNotDestroyed();
   return To<HTMLProgressElement>(GetNode());
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_progress.h b/third_party/blink/renderer/core/layout/layout_progress.h
index 8aaa11a..cb92bf8 100644
--- a/third_party/blink/renderer/core/layout/layout_progress.h
+++ b/third_party/blink/renderer/core/layout/layout_progress.h
@@ -33,7 +33,10 @@
   explicit LayoutProgress(Element* element);
   ~LayoutProgress() override;
 
-  double GetPosition() const { return position_; }
+  double GetPosition() const {
+    CheckIsNotDestroyed();
+    return position_;
+  }
   double AnimationProgress() const;
 
   bool IsDeterminate() const;
@@ -41,11 +44,15 @@
 
   HTMLProgressElement* ProgressElement() const;
 
-  const char* GetName() const override { return "LayoutProgress"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutProgress";
+  }
 
  protected:
   void WillBeDestroyed() override;
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectProgress || LayoutBlockFlow::IsOfType(type);
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_quote.cc b/third_party/blink/renderer/core/layout/layout_quote.cc
index 7d50dce..88e1005 100644
--- a/third_party/blink/renderer/core/layout/layout_quote.cc
+++ b/third_party/blink/renderer/core/layout/layout_quote.cc
@@ -50,17 +50,20 @@
 }
 
 void LayoutQuote::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   DetachQuote();
   LayoutInline::WillBeDestroyed();
 }
 
 void LayoutQuote::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   LayoutInline::WillBeRemovedFromTree();
   DetachQuote();
 }
 
 void LayoutQuote::StyleDidChange(StyleDifference diff,
                                  const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutInline::StyleDidChange(diff, old_style);
   UpdateText();
 }
@@ -275,6 +278,7 @@
 }
 
 void LayoutQuote::UpdateText() {
+  CheckIsNotDestroyed();
   String text = ComputeText();
   if (text_ == text)
     return;
@@ -296,6 +300,7 @@
 }
 
 LayoutTextFragment* LayoutQuote::FindFragmentChild() const {
+  CheckIsNotDestroyed();
   // We walk from the end of the child list because, if we've had a first-letter
   // LayoutObject inserted then the remaining text will be at the end.
   while (LayoutObject* child = LastChild()) {
@@ -307,6 +312,7 @@
 }
 
 String LayoutQuote::ComputeText() const {
+  CheckIsNotDestroyed();
   switch (type_) {
     case QuoteType::kNoOpen:
     case QuoteType::kNoClose:
@@ -321,6 +327,7 @@
 }
 
 const QuotesData* LayoutQuote::GetQuotesData() const {
+  CheckIsNotDestroyed();
   if (const QuotesData* custom_quotes = StyleRef().Quotes())
     return custom_quotes;
 
@@ -331,6 +338,7 @@
 }
 
 void LayoutQuote::AttachQuote() {
+  CheckIsNotDestroyed();
   DCHECK(View());
   DCHECK(!attached_);
   DCHECK(!next_);
@@ -375,6 +383,7 @@
 }
 
 void LayoutQuote::DetachQuote() {
+  CheckIsNotDestroyed();
   DCHECK(!next_ || next_->attached_);
   DCHECK(!previous_ || previous_->attached_);
   if (!attached_)
@@ -401,6 +410,7 @@
 }
 
 void LayoutQuote::UpdateDepth() {
+  CheckIsNotDestroyed();
   DCHECK(attached_);
   int old_depth = depth_;
   depth_ = 0;
diff --git a/third_party/blink/renderer/core/layout/layout_quote.h b/third_party/blink/renderer/core/layout/layout_quote.h
index 1852f6e..dac6e6b 100644
--- a/third_party/blink/renderer/core/layout/layout_quote.h
+++ b/third_party/blink/renderer/core/layout/layout_quote.h
@@ -44,13 +44,17 @@
   ~LayoutQuote() override;
   void AttachQuote();
 
-  const char* GetName() const override { return "LayoutQuote"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutQuote";
+  }
 
  private:
   void DetachQuote();
 
   void WillBeDestroyed() override;
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectQuote || LayoutInline::IsOfType(type);
   }
   void StyleDidChange(StyleDifference, const ComputedStyle*) override;
@@ -60,7 +64,10 @@
   void UpdateText();
   const QuotesData* GetQuotesData() const;
   void UpdateDepth();
-  bool IsAttached() { return attached_; }
+  bool IsAttached() {
+    CheckIsNotDestroyed();
+    return attached_;
+  }
 
   LayoutTextFragment* FindFragmentChild() const;
 
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.cc b/third_party/blink/renderer/core/layout/layout_replaced.cc
index 652452e7..59f2a90 100644
--- a/third_party/blink/renderer/core/layout/layout_replaced.cc
+++ b/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -66,6 +66,7 @@
 LayoutReplaced::~LayoutReplaced() = default;
 
 void LayoutReplaced::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   if (!DocumentBeingDestroyed() && Parent())
     Parent()->DirtyLinesFromChangedChild(this);
 
@@ -74,6 +75,7 @@
 
 void LayoutReplaced::StyleDidChange(StyleDifference diff,
                                     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutBox::StyleDidChange(diff, old_style);
 
   // Replaced elements can have border-radius clips without clipping overflow;
@@ -92,6 +94,7 @@
 }
 
 void LayoutReplaced::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
 
@@ -112,6 +115,7 @@
 }
 
 void LayoutReplaced::IntrinsicSizeChanged() {
+  CheckIsNotDestroyed();
   int scaled_width =
       static_cast<int>(kDefaultWidth * StyleRef().EffectiveZoom());
   int scaled_height =
@@ -122,10 +126,12 @@
 }
 
 void LayoutReplaced::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   ReplacedPainter(*this).Paint(paint_info);
 }
 
 bool LayoutReplaced::HasReplacedLogicalHeight() const {
+  CheckIsNotDestroyed();
   if (StyleRef().LogicalHeight().IsAuto())
     return false;
 
@@ -142,6 +148,7 @@
 }
 
 bool LayoutReplaced::NeedsPreferredWidthsRecalculation() const {
+  CheckIsNotDestroyed();
   // If the height is a percentage and the width is auto, then the
   // containingBlocks's height changing can cause this node to change it's
   // preferred width because it maintains aspect ratio.
@@ -156,6 +163,7 @@
 }
 
 void LayoutReplaced::RecalcVisualOverflow() {
+  CheckIsNotDestroyed();
   ClearVisualOverflow();
   LayoutObject::RecalcVisualOverflow();
   AddVisualEffectOverflow();
@@ -163,6 +171,7 @@
 
 void LayoutReplaced::ComputeIntrinsicSizingInfoForReplacedContent(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  CheckIsNotDestroyed();
   // In cases where we apply size containment we don't need to compute sizing
   // information, since the final result does not depend on it.
   if (ShouldApplySizeContainment()) {
@@ -202,6 +211,7 @@
 
 FloatSize LayoutReplaced::ConstrainIntrinsicSizeToMinMax(
     const IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  CheckIsNotDestroyed();
   // Constrain the intrinsic size along each axis according to minimum and
   // maximum width/heights along the opposite axis. So for example a maximum
   // width that shrinks our width will result in the height we compute here
@@ -230,6 +240,7 @@
 
 void LayoutReplaced::ComputePositionedLogicalWidth(
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   // The following is based off of the W3C Working Draft from April 11, 2006 of
   // CSS 2.1: Section 10.3.8 "Absolutely positioned, replaced elements"
   // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-width>
@@ -449,6 +460,7 @@
 
 void LayoutReplaced::ComputePositionedLogicalHeight(
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   // The following is based off of the W3C Working Draft from April 11, 2006 of
   // CSS 2.1: Section 10.6.5 "Absolutely positioned, replaced elements"
   // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-height>
@@ -607,6 +619,7 @@
 
 PhysicalRect LayoutReplaced::ComputeObjectFit(
     const LayoutSize* overridden_intrinsic_size) const {
+  CheckIsNotDestroyed();
   PhysicalRect content_rect = PhysicalContentBoxRect();
   EObjectFit object_fit = StyleRef().GetObjectFit();
 
@@ -669,6 +682,7 @@
 }
 
 PhysicalRect LayoutReplaced::ReplacedContentRect() const {
+  CheckIsNotDestroyed();
   return ComputeObjectFit();
 }
 
@@ -679,6 +693,7 @@
 
 void LayoutReplaced::ComputeIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  CheckIsNotDestroyed();
   DCHECK(!ShouldApplySizeContainment());
   intrinsic_sizing_info.size = FloatSize(IntrinsicLogicalWidth().ToFloat(),
                                          IntrinsicLogicalHeight().ToFloat());
@@ -729,6 +744,7 @@
 
 LayoutUnit LayoutReplaced::ComputeConstrainedLogicalWidth(
     ShouldComputePreferred should_compute_preferred) const {
+  CheckIsNotDestroyed();
   if (should_compute_preferred == kComputePreferred)
     return ComputeReplacedLogicalWidthRespectingMinMaxWidth(LayoutUnit(),
                                                             kComputePreferred);
@@ -753,6 +769,7 @@
 
 LayoutUnit LayoutReplaced::ComputeReplacedLogicalWidth(
     ShouldComputePreferred should_compute_preferred) const {
+  CheckIsNotDestroyed();
   if (StyleRef().LogicalWidth().IsSpecified() ||
       StyleRef().LogicalWidth().IsIntrinsic())
     return ComputeReplacedLogicalWidthRespectingMinMaxWidth(
@@ -838,6 +855,7 @@
 
 LayoutUnit LayoutReplaced::ComputeReplacedLogicalHeight(
     LayoutUnit estimated_used_width) const {
+  CheckIsNotDestroyed();
   // 10.5 Content height: the 'height' property:
   // http://www.w3.org/TR/CSS21/visudet.html#propdef-height
   if (HasReplacedLogicalHeight()) {
@@ -889,12 +907,14 @@
 }
 
 MinMaxSizes LayoutReplaced::ComputeIntrinsicLogicalWidths() const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes;
   sizes += BorderAndPaddingLogicalWidth() + IntrinsicLogicalWidth();
   return sizes;
 }
 
 MinMaxSizes LayoutReplaced::PreferredLogicalWidths() const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes;
 
   // We cannot resolve some logical width here (i.e. percent, fill-available or
@@ -980,6 +1000,7 @@
 
 PositionWithAffinity LayoutReplaced::PositionForPoint(
     const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   LayoutUnit top;
   LayoutUnit bottom;
   std::tie(top, bottom) = SelectionTopAndBottom(*this);
@@ -1014,6 +1035,7 @@
 }
 
 PhysicalRect LayoutReplaced::LocalSelectionVisualRect() const {
+  CheckIsNotDestroyed();
   if (GetSelectionState() == SelectionState::kNone ||
       GetSelectionState() == SelectionState::kContain) {
     return PhysicalRect();
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.h b/third_party/blink/renderer/core/layout/layout_replaced.h
index d501a40..e3e056f 100644
--- a/third_party/blink/renderer/core/layout/layout_replaced.h
+++ b/third_party/blink/renderer/core/layout/layout_replaced.h
@@ -77,13 +77,19 @@
   // http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width
   static const int kDefaultWidth;
   static const int kDefaultHeight;
-  bool CanHaveChildren() const override { return false; }
+  bool CanHaveChildren() const override {
+    CheckIsNotDestroyed();
+    return false;
+  }
   virtual void PaintReplaced(const PaintInfo&,
-                             const PhysicalOffset& paint_offset) const {}
+                             const PhysicalOffset& paint_offset) const {
+    CheckIsNotDestroyed();
+  }
 
   PhysicalRect LocalSelectionVisualRect() const final;
 
   bool HasObjectFit() const {
+    CheckIsNotDestroyed();
     return StyleRef().GetObjectFit() !=
            ComputedStyleInitialValues::InitialObjectFit();
   }
@@ -108,10 +114,12 @@
   void UpdateLayout() override;
 
   LayoutSize IntrinsicSize() const final {
+    CheckIsNotDestroyed();
     return LayoutSize(IntrinsicWidth(), IntrinsicHeight());
   }
 
   LayoutUnit IntrinsicWidth() const {
+    CheckIsNotDestroyed();
     if (HasOverrideIntrinsicContentWidth())
       return OverrideIntrinsicContentWidth();
     else if (ShouldApplySizeContainment())
@@ -119,6 +127,7 @@
     return intrinsic_size_.Width();
   }
   LayoutUnit IntrinsicHeight() const {
+    CheckIsNotDestroyed();
     if (HasOverrideIntrinsicContentHeight())
       return OverrideIntrinsicContentHeight();
     else if (ShouldApplySizeContainment())
@@ -140,20 +149,26 @@
       const LayoutSize* overridden_intrinsic_size = nullptr) const;
 
   LayoutUnit IntrinsicContentLogicalHeight() const override {
+    CheckIsNotDestroyed();
     return IntrinsicLogicalHeight();
   }
 
-  virtual LayoutUnit MinimumReplacedHeight() const { return LayoutUnit(); }
+  virtual LayoutUnit MinimumReplacedHeight() const {
+    CheckIsNotDestroyed();
+    return LayoutUnit();
+  }
 
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
 
   void SetIntrinsicSize(const LayoutSize& intrinsic_size) {
+    CheckIsNotDestroyed();
     intrinsic_size_ = intrinsic_size;
   }
 
   PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectLayoutReplaced || LayoutBox::IsOfType(type);
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_ruby.cc b/third_party/blink/renderer/core/layout/layout_ruby.cc
index 61ea140..c74dc4c 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby.cc
+++ b/third_party/blink/renderer/core/layout/layout_ruby.cc
@@ -61,12 +61,14 @@
 
 void LayoutRubyAsInline::StyleDidChange(StyleDifference diff,
                                         const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutInline::StyleDidChange(diff, old_style);
   PropagateStyleToAnonymousChildren();
 }
 
 void LayoutRubyAsInline::AddChild(LayoutObject* child,
                                   LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   // If the child is a ruby run, just add it normally.
   if (child->IsRubyRun()) {
     LayoutInline::AddChild(child, before_child);
@@ -101,6 +103,7 @@
 }
 
 void LayoutRubyAsInline::RemoveChild(LayoutObject* child) {
+  CheckIsNotDestroyed();
   // If the child's parent is *this (must be a ruby run), just use the normal
   // remove method.
   if (child->Parent() == this) {
@@ -126,12 +129,14 @@
 
 void LayoutRubyAsBlock::StyleDidChange(StyleDifference diff,
                                        const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::StyleDidChange(diff, old_style);
   PropagateStyleToAnonymousChildren();
 }
 
 void LayoutRubyAsBlock::AddChild(LayoutObject* child,
                                  LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   // If the child is a ruby run, just add it normally.
   if (child->IsRubyRun()) {
     LayoutBlockFlow::AddChild(child, before_child);
@@ -166,6 +171,7 @@
 }
 
 void LayoutRubyAsBlock::RemoveChild(LayoutObject* child) {
+  CheckIsNotDestroyed();
   // If the child's parent is *this (must be a ruby run), just use the normal
   // remove method.
   if (child->Parent() == this) {
diff --git a/third_party/blink/renderer/core/layout/layout_ruby.h b/third_party/blink/renderer/core/layout/layout_ruby.h
index 66747efa..76a7ef5b 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby.h
+++ b/third_party/blink/renderer/core/layout/layout_ruby.h
@@ -64,16 +64,23 @@
                 LayoutObject* before_child = nullptr) override;
   void RemoveChild(LayoutObject* child) override;
 
-  const char* GetName() const override { return "LayoutRuby (inline)"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutRuby (inline)";
+  }
 
  protected:
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectRuby || LayoutInline::IsOfType(type);
   }
-  bool CreatesAnonymousWrapper() const override { return true; }
+  bool CreatesAnonymousWrapper() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
 };
 
 // <ruby> when used as 'display:block' or 'display:inline-block'
@@ -86,17 +93,27 @@
                 LayoutObject* before_child = nullptr) override;
   void RemoveChild(LayoutObject* child) override;
 
-  const char* GetName() const override { return "LayoutRuby (block)"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutRuby (block)";
+  }
 
  protected:
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectRuby || LayoutBlockFlow::IsOfType(type);
   }
 
  private:
-  bool CreatesAnonymousWrapper() const override { return true; }
-  void RemoveLeftoverAnonymousBlock(LayoutBlock*) override { NOTREACHED(); }
+  bool CreatesAnonymousWrapper() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
+  void RemoveLeftoverAnonymousBlock(LayoutBlock*) override {
+    CheckIsNotDestroyed();
+    NOTREACHED();
+  }
 };
 
 }  // namespace blink
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 6418d0a3..32e173f3 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby_base.cc
+++ b/third_party/blink/renderer/core/layout/layout_ruby_base.cc
@@ -57,11 +57,13 @@
 
 bool LayoutRubyBase::IsChildAllowed(LayoutObject* child,
                                     const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   return child->IsInline();
 }
 
 void LayoutRubyBase::MoveChildren(LayoutRubyBase* to_base,
                                   LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   // This function removes all children that are before (!) beforeChild
   // and appends them to toBase.
   DCHECK(to_base);
@@ -84,6 +86,7 @@
 
 void LayoutRubyBase::MoveInlineChildren(LayoutRubyBase* to_base,
                                         LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   DCHECK(ChildrenInline());
   DCHECK(to_base);
 
@@ -112,6 +115,7 @@
 
 void LayoutRubyBase::MoveBlockChildren(LayoutRubyBase* to_base,
                                        LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   DCHECK(!ChildrenInline());
   DCHECK(to_base);
 
@@ -163,6 +167,7 @@
     unsigned expansion_opportunity_count,
     LayoutUnit& logical_left,
     LayoutUnit& logical_width) const {
+  CheckIsNotDestroyed();
   int max_preferred_logical_width = PreferredLogicalWidths().max_size.ToInt();
   if (max_preferred_logical_width >= logical_width)
     return;
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 6e474be..b4d85ca 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby_base.h
+++ b/third_party/blink/renderer/core/layout/layout_ruby_base.h
@@ -45,9 +45,13 @@
   static LayoutRubyBase* CreateAnonymous(Document*,
                                          const LayoutRubyRun& ruby_run);
 
-  const char* GetName() const override { return "LayoutRubyBase"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutRubyBase";
+  }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectRubyBase || LayoutBlockFlow::IsOfType(type);
   }
 
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 99a1658..49a3d78a 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby_run.cc
+++ b/third_party/blink/renderer/core/layout/layout_ruby_run.cc
@@ -46,6 +46,7 @@
 LayoutRubyRun::~LayoutRubyRun() = default;
 
 bool LayoutRubyRun::HasRubyText() const {
+  CheckIsNotDestroyed();
   // The only place where a ruby text can be is in the first position
   // Note: As anonymous blocks, ruby runs do not have ':before' or ':after'
   // content themselves.
@@ -53,6 +54,7 @@
 }
 
 bool LayoutRubyRun::HasRubyBase() const {
+  CheckIsNotDestroyed();
   // The only place where a ruby base can be is in the last position
   // Note: As anonymous blocks, ruby runs do not have ':before' or ':after'
   // content themselves.
@@ -60,6 +62,7 @@
 }
 
 LayoutRubyText* LayoutRubyRun::RubyText() const {
+  CheckIsNotDestroyed();
   LayoutObject* child = FirstChild();
   // If in future it becomes necessary to support floating or positioned ruby
   // text, layout will have to be changed to handle them properly.
@@ -70,12 +73,14 @@
 }
 
 LayoutRubyBase* LayoutRubyRun::RubyBase() const {
+  CheckIsNotDestroyed();
   LayoutObject* child = LastChild();
   return child && child->IsRubyBase() ? static_cast<LayoutRubyBase*>(child)
                                       : nullptr;
 }
 
 LayoutRubyBase* LayoutRubyRun::RubyBaseSafe() {
+  CheckIsNotDestroyed();
   LayoutRubyBase* base = RubyBase();
   if (!base) {
     base = CreateRubyBase();
@@ -86,10 +91,12 @@
 
 bool LayoutRubyRun::IsChildAllowed(LayoutObject* child,
                                    const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   return child->IsRubyText() || child->IsInline();
 }
 
 void LayoutRubyRun::AddChild(LayoutObject* child, LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   DCHECK(child);
 
   if (child->IsRubyText()) {
@@ -143,6 +150,7 @@
 }
 
 void LayoutRubyRun::RemoveChild(LayoutObject* child) {
+  CheckIsNotDestroyed();
   // If the child is a ruby text, then merge the ruby base with the base of
   // the right sibling run, if possible.
   if (!BeingDestroyed() && !DocumentBeingDestroyed() && child->IsRubyText()) {
@@ -183,6 +191,7 @@
 }
 
 LayoutRubyBase* LayoutRubyRun::CreateRubyBase() const {
+  CheckIsNotDestroyed();
   LayoutRubyBase* layout_object =
       LayoutRubyBase::CreateAnonymous(&GetDocument(), *this);
   scoped_refptr<ComputedStyle> new_style =
@@ -216,6 +225,7 @@
 LayoutObject* LayoutRubyRun::LayoutSpecialExcludedChild(
     bool relayout_children,
     SubtreeLayoutScope& layout_scope) {
+  CheckIsNotDestroyed();
   // Don't bother positioning the LayoutRubyRun yet.
   LayoutRubyText* rt = RubyText();
   if (!rt)
@@ -227,6 +237,7 @@
 }
 
 void LayoutRubyRun::UpdateLayout() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::UpdateLayout();
 
   LayoutRubyText* rt = RubyText();
@@ -280,6 +291,7 @@
                                 LayoutObject* end_layout_object,
                                 int& start_overhang,
                                 int& end_overhang) const {
+  CheckIsNotDestroyed();
   DCHECK(!NeedsLayout());
 
   start_overhang = 0;
@@ -339,6 +351,7 @@
 
 bool LayoutRubyRun::CanBreakBefore(
     const LazyLineBreakIterator& iterator) const {
+  CheckIsNotDestroyed();
   // TODO(kojii): It would be nice to improve this so that it isn't just
   // hard-coded, but lookahead in this case is particularly problematic.
   // See crbug.com/522826.
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 163a978..a54dda3 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby_run.h
+++ b/third_party/blink/renderer/core/layout/layout_ruby_run.h
@@ -77,7 +77,10 @@
 
   bool CanBreakBefore(const LazyLineBreakIterator&) const;
 
-  const char* GetName() const override { return "LayoutRubyRun"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutRubyRun";
+  }
 
  protected:
   LayoutRubyBase* CreateRubyBase() const;
@@ -87,10 +90,16 @@
   explicit LayoutRubyRun(Element*);
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectRubyRun || LayoutBlockFlow::IsOfType(type);
   }
-  bool CreatesAnonymousWrapper() const override { return true; }
-  void RemoveLeftoverAnonymousBlock(LayoutBlock*) override {}
+  bool CreatesAnonymousWrapper() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
+  void RemoveLeftoverAnonymousBlock(LayoutBlock*) override {
+    CheckIsNotDestroyed();
+  }
 
   friend class LayoutNGMixin<LayoutRubyRun>;
 };
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 7c304fd..ed5f809 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_ruby_text.cc
@@ -39,11 +39,13 @@
 
 bool LayoutRubyText::IsChildAllowed(LayoutObject* child,
                                     const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   return child->IsInline();
 }
 
 void LayoutRubyText::StyleDidChange(StyleDifference diff,
                                     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   if (StyleRef().GetTextAlign() !=
       ComputedStyleInitialValues::InitialTextAlign()) {
     UseCounter::Count(GetDocument(),
@@ -54,6 +56,7 @@
 
 ETextAlign LayoutRubyText::TextAlignmentForLine(
     bool ends_with_soft_break) const {
+  CheckIsNotDestroyed();
   ETextAlign text_align = StyleRef().GetTextAlign();
   // FIXME: This check is bogus since user can set the initial value.
   if (text_align != ComputedStyleInitialValues::InitialTextAlign())
@@ -68,6 +71,7 @@
     unsigned expansion_opportunity_count,
     LayoutUnit& logical_left,
     LayoutUnit& logical_width) const {
+  CheckIsNotDestroyed();
   ETextAlign text_align = StyleRef().GetTextAlign();
   // FIXME: This check is bogus since user can set the initial value.
   if (text_align != ComputedStyleInitialValues::InitialTextAlign()) {
diff --git a/third_party/blink/renderer/core/layout/layout_ruby_text.h b/third_party/blink/renderer/core/layout/layout_ruby_text.h
index c2f43d6..e95b32b 100644
--- a/third_party/blink/renderer/core/layout/layout_ruby_text.h
+++ b/third_party/blink/renderer/core/layout/layout_ruby_text.h
@@ -40,9 +40,13 @@
   LayoutRubyText(Element*);
   ~LayoutRubyText() override;
 
-  const char* GetName() const override { return "LayoutRubyText"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutRubyText";
+  }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectRubyText || LayoutBlockFlow::IsOfType(type);
   }
 
@@ -52,6 +56,7 @@
                       const ComputedStyle* old_style) override;
 
   bool CreatesNewFormattingContext() const final {
+    CheckIsNotDestroyed();
     // Ruby text objects are pushed around after layout, to become flush with
     // the associated ruby base. As such, we cannot let floats leak out from
     // ruby text objects.
diff --git a/third_party/blink/renderer/core/layout/layout_slider_track.cc b/third_party/blink/renderer/core/layout/layout_slider_track.cc
index ad86503..46e121c6 100644
--- a/third_party/blink/renderer/core/layout/layout_slider_track.cc
+++ b/third_party/blink/renderer/core/layout/layout_slider_track.cc
@@ -41,6 +41,7 @@
     : LayoutBlockFlow(element) {}
 
 void LayoutSliderTrack::UpdateLayout() {
+  CheckIsNotDestroyed();
   auto* input = To<HTMLInputElement>(GetNode()->OwnerShadowHost());
   const bool is_vertical = !StyleRef().IsHorizontalWritingMode();
 
diff --git a/third_party/blink/renderer/core/layout/layout_table.cc b/third_party/blink/renderer/core/layout/layout_table.cc
index bb36cba..c1f97d6 100644
--- a/third_party/blink/renderer/core/layout/layout_table.cc
+++ b/third_party/blink/renderer/core/layout/layout_table.cc
@@ -83,6 +83,7 @@
 
 void LayoutTable::StyleDidChange(StyleDifference diff,
                                  const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutBlock::StyleDidChange(diff, old_style);
 
   if (ShouldCollapseBorders())
@@ -148,6 +149,7 @@
 }
 
 void LayoutTable::AddChild(LayoutObject* child, LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   bool wrap_in_anonymous_section = !child->IsOutOfFlowPositioned();
 
   if (child->IsTableCaption()) {
@@ -238,11 +240,13 @@
 }
 
 void LayoutTable::AddCaption(const LayoutTableCaption* caption) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(captions_.Find(caption), kNotFound);
   captions_.push_back(const_cast<LayoutTableCaption*>(caption));
 }
 
 void LayoutTable::RemoveCaption(const LayoutTableCaption* old_caption) {
+  CheckIsNotDestroyed();
   wtf_size_t index = captions_.Find(old_caption);
   DCHECK_NE(index, kNotFound);
   if (index == kNotFound)
@@ -252,11 +256,13 @@
 }
 
 void LayoutTable::InvalidateCachedColumns() {
+  CheckIsNotDestroyed();
   column_layout_objects_valid_ = false;
   column_layout_objects_.resize(0);
 }
 
 void LayoutTable::ColumnStructureChanged() {
+  CheckIsNotDestroyed();
   column_structure_changed_ = true;
   InvalidateCachedColumns();
   // We don't really need to recompute our sections, but we do need to update
@@ -266,41 +272,50 @@
 }
 
 void LayoutTable::AddColumn(const LayoutTableCol*) {
+  CheckIsNotDestroyed();
   ColumnStructureChanged();
 }
 
 void LayoutTable::RemoveColumn(const LayoutTableCol*) {
+  CheckIsNotDestroyed();
   ColumnStructureChanged();
 }
 
 LayoutNGTableSectionInterface* LayoutTable::FirstBodyInterface() const {
+  CheckIsNotDestroyed();
   return FirstBody();
 }
 
 LayoutNGTableSectionInterface* LayoutTable::TopSectionInterface() const {
+  CheckIsNotDestroyed();
   return TopSection();
 }
 
 LayoutNGTableSectionInterface* LayoutTable::BottomSectionInterface() const {
+  CheckIsNotDestroyed();
   return BottomSection();
 }
 
 LayoutNGTableSectionInterface* LayoutTable::TopNonEmptySectionInterface()
     const {
+  CheckIsNotDestroyed();
   return TopNonEmptySection();
 }
 
 LayoutNGTableSectionInterface* LayoutTable::SectionBelowInterface(
     const LayoutNGTableSectionInterface* section,
     SkipEmptySectionsValue skip_empty_sections) const {
+  CheckIsNotDestroyed();
   return SectionBelow(section->ToLayoutTableSection(), skip_empty_sections);
 }
 LayoutNGTableSectionInterface* LayoutTable::BottomNonEmptySectionInterface()
     const {
+  CheckIsNotDestroyed();
   return BottomNonEmptySection();
 }
 
 bool LayoutTable::IsLogicalWidthAuto() const {
+  CheckIsNotDestroyed();
   const Length& style_logical_width = StyleRef().LogicalWidth();
   return (!style_logical_width.IsSpecified() ||
           !style_logical_width.IsPositive()) &&
@@ -308,6 +323,7 @@
 }
 
 void LayoutTable::UpdateLogicalWidth() {
+  CheckIsNotDestroyed();
   RecalcSectionsIfNeeded();
 
   // Recalculate the intrinsic logical widths now, rather than relying on them
@@ -442,6 +458,7 @@
 LayoutUnit LayoutTable::ConvertStyleLogicalWidthToComputedWidth(
     const Length& style_logical_width,
     LayoutUnit available_width) const {
+  CheckIsNotDestroyed();
   if (style_logical_width.IsIntrinsic()) {
     return ComputeIntrinsicLogicalWidthUsing(style_logical_width,
                                              available_width);
@@ -464,6 +481,7 @@
 
 LayoutUnit LayoutTable::ConvertStyleLogicalHeightToComputedHeight(
     const Length& style_logical_height) const {
+  CheckIsNotDestroyed();
   LayoutUnit border_and_padding_before =
       BorderBefore() +
       (ShouldCollapseBorders() ? LayoutUnit() : PaddingBefore());
@@ -499,6 +517,7 @@
 
 void LayoutTable::LayoutCaption(LayoutTableCaption& caption,
                                 SubtreeLayoutScope& layouter) {
+  CheckIsNotDestroyed();
   if (!caption.NeedsLayout())
     MarkChildForPaginationRelayoutIfNeeded(caption, layouter);
   if (caption.NeedsLayout()) {
@@ -533,6 +552,7 @@
     SubtreeLayoutScope& layouter,
     LayoutUnit logical_left,
     TableHeightChangingValue table_height_changing) {
+  CheckIsNotDestroyed();
   section.SetLogicalLocation(LayoutPoint(logical_left, LogicalHeight()));
   if (column_logical_width_changed_)
     layouter.SetChildNeedsLayout(&section);
@@ -552,6 +572,7 @@
 }
 
 LayoutUnit LayoutTable::LogicalHeightFromStyle() const {
+  CheckIsNotDestroyed();
   LayoutUnit computed_logical_height;
   const Length& logical_height_length = StyleRef().LogicalHeight();
   if (logical_height_length.IsIntrinsic() ||
@@ -595,6 +616,7 @@
 }
 
 void LayoutTable::DistributeExtraLogicalHeight(int extra_logical_height) {
+  CheckIsNotDestroyed();
   if (extra_logical_height <= 0)
     return;
 
@@ -608,6 +630,7 @@
 }
 
 void LayoutTable::SimplifiedNormalFlowLayout() {
+  CheckIsNotDestroyed();
   // 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
@@ -624,6 +647,7 @@
 }
 
 bool LayoutTable::RecalcLayoutOverflow() {
+  CheckIsNotDestroyed();
   RecalcSelfLayoutOverflow();
 
   if (!ChildNeedsLayoutOverflowRecalc())
@@ -646,6 +670,7 @@
 }
 
 void LayoutTable::RecalcVisualOverflow() {
+  CheckIsNotDestroyed();
   for (auto* caption : captions_) {
     if (!caption->HasSelfPaintingLayer())
       caption->RecalcVisualOverflow();
@@ -662,6 +687,7 @@
 }
 
 void LayoutTable::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
 
@@ -893,6 +919,7 @@
 
 void LayoutTable::AdjustWidthsForCollapsedColumns(
     Vector<int>& col_collapsed_width) {
+  CheckIsNotDestroyed();
   DCHECK(!col_collapsed_width.size());
   if (!RuntimeEnabledFeatures::VisibilityCollapseColumnEnabled())
     return;
@@ -931,6 +958,7 @@
 
 bool LayoutTable::IsAbsoluteColumnCollapsed(
     unsigned absolute_column_index) const {
+  CheckIsNotDestroyed();
   ColAndColGroup colElement = ColElementAtAbsoluteColumn(absolute_column_index);
   LayoutTableCol* col = colElement.col;
   LayoutTableCol* colgroup = colElement.colgroup;
@@ -940,6 +968,7 @@
 }
 
 void LayoutTable::InvalidateCollapsedBorders() {
+  CheckIsNotDestroyed();
   collapsed_borders_valid_ = false;
   needs_invalidate_collapsed_borders_for_all_cells_ = true;
   collapsed_outer_borders_valid_ = false;
@@ -947,6 +976,7 @@
 }
 
 void LayoutTable::InvalidateCollapsedBordersForAllCellsIfNeeded() {
+  CheckIsNotDestroyed();
   DCHECK(ShouldCollapseBorders());
 
   if (!needs_invalidate_collapsed_borders_for_all_cells_)
@@ -971,6 +1001,7 @@
 }
 
 void LayoutTable::ComputeVisualOverflow(bool) {
+  CheckIsNotDestroyed();
   LayoutRect previous_visual_overflow_rect = VisualOverflowRect();
   ClearVisualOverflow();
   AddVisualOverflowFromChildren();
@@ -984,6 +1015,7 @@
 }
 
 void LayoutTable::AddVisualOverflowFromChildren() {
+  CheckIsNotDestroyed();
   // Add overflow from borders.
   // Technically it's odd that we are incorporating the borders into layout
   // overflow, which is only supposed to be about overflow from our
@@ -1015,6 +1047,7 @@
 }
 
 void LayoutTable::AddLayoutOverflowFromChildren() {
+  CheckIsNotDestroyed();
   // Add overflow from borders.
   // Technically it's odd that we are incorporating the borders into layout
   // overflow, which is only supposed to be about overflow from our
@@ -1047,10 +1080,12 @@
 
 void LayoutTable::PaintObject(const PaintInfo& paint_info,
                               const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   TablePainter(*this).PaintObject(paint_info, paint_offset);
 }
 
 void LayoutTable::SubtractCaptionRect(PhysicalRect& rect) const {
+  CheckIsNotDestroyed();
   for (unsigned i = 0; i < captions_.size(); i++) {
     LayoutUnit caption_logical_height = captions_[i]->LogicalHeight() +
                                         captions_[i]->MarginBefore() +
@@ -1072,6 +1107,7 @@
 
 void LayoutTable::MarkAllCellsWidthsDirtyAndOrNeedsLayout(
     WhatToMarkAllCells what_to_mark) {
+  CheckIsNotDestroyed();
   for (LayoutObject* child = Children()->FirstChild(); child;
        child = child->NextSibling()) {
     if (!child->IsTableSection())
@@ -1084,15 +1120,18 @@
 void LayoutTable::PaintBoxDecorationBackground(
     const PaintInfo& paint_info,
     const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   TablePainter(*this).PaintBoxDecorationBackground(paint_info, paint_offset);
 }
 
 void LayoutTable::PaintMask(const PaintInfo& paint_info,
                             const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   TablePainter(*this).PaintMask(paint_info, paint_offset);
 }
 
 MinMaxSizes LayoutTable::ComputeIntrinsicLogicalWidths() const {
+  CheckIsNotDestroyed();
   RecalcSectionsIfNeeded();
   // FIXME: Restructure the table layout code so that we can make this method
   // const.
@@ -1107,6 +1146,7 @@
 }
 
 MinMaxSizes LayoutTable::PreferredLogicalWidths() const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes = IntrinsicLogicalWidths();
 
   table_layout_->ApplyPreferredLogicalWidthQuirks(sizes.min_size,
@@ -1148,6 +1188,7 @@
 }
 
 LayoutTableSection* LayoutTable::TopNonEmptySection() const {
+  CheckIsNotDestroyed();
   LayoutTableSection* section = TopSection();
   if (section && !section->NumRows())
     section = SectionBelow(section, kSkipEmptySections);
@@ -1155,6 +1196,7 @@
 }
 
 LayoutTableSection* LayoutTable::BottomNonEmptySection() const {
+  CheckIsNotDestroyed();
   LayoutTableSection* section = BottomSection();
   if (section && !section->NumRows())
     section = SectionAbove(section, kSkipEmptySections);
@@ -1162,6 +1204,7 @@
 }
 
 void LayoutTable::SplitEffectiveColumn(unsigned index, unsigned first_span) {
+  CheckIsNotDestroyed();
   // We split the column at |index|, taking |firstSpan| cells from the span.
   DCHECK_GT(effective_columns_[index].span, first_span);
   effective_columns_.insert(index, first_span);
@@ -1186,6 +1229,7 @@
 }
 
 void LayoutTable::AppendEffectiveColumn(unsigned span) {
+  CheckIsNotDestroyed();
   unsigned new_column_index = effective_columns_.size();
   effective_columns_.push_back(span);
 
@@ -1215,6 +1259,7 @@
 }
 
 LayoutTableCol* LayoutTable::FirstColumn() const {
+  CheckIsNotDestroyed();
   for (LayoutObject* child = FirstChild(); child;
        child = child->NextSibling()) {
     if (child->IsLayoutTableCol())
@@ -1225,6 +1270,7 @@
 }
 
 void LayoutTable::UpdateColumnCache() const {
+  CheckIsNotDestroyed();
   DCHECK(has_col_elements_);
   DCHECK(column_layout_objects_.IsEmpty());
   DCHECK(!column_layout_objects_valid_);
@@ -1243,6 +1289,7 @@
 
 LayoutTable::ColAndColGroup LayoutTable::SlowColElementAtAbsoluteColumn(
     unsigned absolute_column_index) const {
+  CheckIsNotDestroyed();
   DCHECK(has_col_elements_);
 
   if (!column_layout_objects_valid_)
@@ -1283,6 +1330,7 @@
 }
 
 void LayoutTable::RecalcSections() const {
+  CheckIsNotDestroyed();
   DCHECK(needs_section_recalc_);
 
   head_ = nullptr;
@@ -1360,6 +1408,7 @@
 }
 
 LayoutUnit LayoutTable::BorderLeft() const {
+  CheckIsNotDestroyed();
   if (ShouldCollapseBorders()) {
     UpdateCollapsedOuterBorders();
     return LayoutUnit(LogicalCollapsedOuterBorderToPhysical().Left());
@@ -1368,6 +1417,7 @@
 }
 
 LayoutUnit LayoutTable::BorderRight() const {
+  CheckIsNotDestroyed();
   if (ShouldCollapseBorders()) {
     UpdateCollapsedOuterBorders();
     return LayoutUnit(LogicalCollapsedOuterBorderToPhysical().Right());
@@ -1376,6 +1426,7 @@
 }
 
 LayoutUnit LayoutTable::BorderTop() const {
+  CheckIsNotDestroyed();
   if (ShouldCollapseBorders()) {
     UpdateCollapsedOuterBorders();
     return LayoutUnit(LogicalCollapsedOuterBorderToPhysical().Top());
@@ -1384,6 +1435,7 @@
 }
 
 LayoutUnit LayoutTable::BorderBottom() const {
+  CheckIsNotDestroyed();
   if (ShouldCollapseBorders()) {
     UpdateCollapsedOuterBorders();
     return LayoutUnit(LogicalCollapsedOuterBorderToPhysical().Bottom());
@@ -1394,6 +1446,7 @@
 LayoutTableSection* LayoutTable::SectionAbove(
     const LayoutTableSection* section,
     SkipEmptySectionsValue skip_empty_sections) const {
+  CheckIsNotDestroyed();
   RecalcSectionsIfNeeded();
 
   if (section == head_)
@@ -1418,6 +1471,7 @@
 LayoutTableSection* LayoutTable::SectionBelow(
     const LayoutTableSection* section,
     SkipEmptySectionsValue skip_empty_sections) const {
+  CheckIsNotDestroyed();
   RecalcSectionsIfNeeded();
 
   if (section == foot_)
@@ -1440,6 +1494,7 @@
 }
 
 LayoutTableSection* LayoutTable::BottomSection() const {
+  CheckIsNotDestroyed();
   RecalcSectionsIfNeeded();
 
   if (foot_)
@@ -1460,6 +1515,7 @@
 }
 
 LayoutTableCell* LayoutTable::CellAbove(const LayoutTableCell& cell) const {
+  CheckIsNotDestroyed();
   RecalcSectionsIfNeeded();
 
   // Find the section and row to look in
@@ -1488,6 +1544,7 @@
 }
 
 LayoutTableCell* LayoutTable::CellBelow(const LayoutTableCell& cell) const {
+  CheckIsNotDestroyed();
   RecalcSectionsIfNeeded();
 
   // Find the section and row to look in
@@ -1514,6 +1571,7 @@
 }
 
 LayoutTableCell* LayoutTable::CellPreceding(const LayoutTableCell& cell) const {
+  CheckIsNotDestroyed();
   RecalcSectionsIfNeeded();
 
   LayoutTableSection* section = cell.Section();
@@ -1527,6 +1585,7 @@
 }
 
 LayoutTableCell* LayoutTable::CellFollowing(const LayoutTableCell& cell) const {
+  CheckIsNotDestroyed();
   RecalcSectionsIfNeeded();
 
   unsigned eff_col = AbsoluteColumnToEffectiveColumn(
@@ -1539,6 +1598,7 @@
     bool first_line,
     LineDirectionMode direction,
     LinePositionMode line_position_mode) const {
+  CheckIsNotDestroyed();
   DCHECK_EQ(line_position_mode, kPositionOnContainingLine);
   LayoutUnit baseline = FirstLineBoxBaseline();
   if (baseline != -1) {
@@ -1552,11 +1612,13 @@
 }
 
 LayoutUnit LayoutTable::InlineBlockBaseline(LineDirectionMode) const {
+  CheckIsNotDestroyed();
   // Tables are skipped when computing an inline-block's baseline.
   return LayoutUnit(-1);
 }
 
 LayoutUnit LayoutTable::FirstLineBoxBaseline() const {
+  CheckIsNotDestroyed();
   // The baseline of a 'table' is the same as the 'inline-table' baseline per
   // CSS 3 Flexbox (CSS 2.1 doesn't define the baseline of a 'table' only an
   // 'inline-table'). This is also needed to properly determine the baseline of
@@ -1588,6 +1650,7 @@
 PhysicalRect LayoutTable::OverflowClipRect(
     const PhysicalOffset& location,
     OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior) const {
+  CheckIsNotDestroyed();
   if (ShouldCollapseBorders()) {
     // Though the outer halves of the collapsed borders are considered as the
     // the border area of the table by means of the box model, they are actually
@@ -1623,6 +1686,7 @@
                               const HitTestLocation& hit_test_location,
                               const PhysicalOffset& accumulated_offset,
                               HitTestAction action) {
+  CheckIsNotDestroyed();
   // Check kids first.
   bool skip_children = (result.GetHitTestRequest().GetStopNode() == this);
   if (!skip_children &&
@@ -1661,10 +1725,12 @@
 
 LayoutBox* LayoutTable::CreateAnonymousBoxWithSameTypeAs(
     const LayoutObject* parent) const {
+  CheckIsNotDestroyed();
   return LayoutObjectFactory::CreateAnonymousTableWithParent(*parent);
 }
 
 void LayoutTable::EnsureIsReadyForPaintInvalidation() {
+  CheckIsNotDestroyed();
   LayoutBlock::EnsureIsReadyForPaintInvalidation();
 
   if (collapsed_borders_valid_)
@@ -1709,10 +1775,12 @@
 
 void LayoutTable::InvalidatePaint(
     const PaintInvalidatorContext& context) const {
+  CheckIsNotDestroyed();
   TablePaintInvalidator(*this, context).InvalidatePaint();
 }
 
 LayoutUnit LayoutTable::PaddingTop() const {
+  CheckIsNotDestroyed();
   if (ShouldCollapseBorders())
     return LayoutUnit();
 
@@ -1722,6 +1790,7 @@
 }
 
 LayoutUnit LayoutTable::PaddingBottom() const {
+  CheckIsNotDestroyed();
   if (ShouldCollapseBorders())
     return LayoutUnit();
 
@@ -1731,6 +1800,7 @@
 }
 
 LayoutUnit LayoutTable::PaddingLeft() const {
+  CheckIsNotDestroyed();
   if (ShouldCollapseBorders())
     return LayoutUnit();
 
@@ -1740,6 +1810,7 @@
 }
 
 LayoutUnit LayoutTable::PaddingRight() const {
+  CheckIsNotDestroyed();
   if (ShouldCollapseBorders())
     return LayoutUnit();
 
@@ -1749,6 +1820,7 @@
 }
 
 void LayoutTable::UpdateCollapsedOuterBorders() const {
+  CheckIsNotDestroyed();
   if (collapsed_outer_borders_valid_)
     return;
 
@@ -1830,6 +1902,7 @@
 
 // LayoutNGTableCellInterface API
 bool LayoutTable::IsFirstCell(const LayoutNGTableCellInterface& cell) const {
+  CheckIsNotDestroyed();
   const LayoutTableCell& layout_cell = *cell.ToLayoutTableCell();
   return !(CellPreceding(layout_cell) || CellAbove(layout_cell));
 }
diff --git a/third_party/blink/renderer/core/layout/layout_table.h b/third_party/blink/renderer/core/layout/layout_table.h
index 1f99679..fc2e6dd 100644
--- a/third_party/blink/renderer/core/layout/layout_table.h
+++ b/third_party/blink/renderer/core/layout/layout_table.h
@@ -144,10 +144,17 @@
   // 'border-spacing' property represent spacing between columns and rows
   // respectively, not necessarily the horizontal and vertical spacing
   // respectively".
-  int16_t HBorderSpacing() const final { return h_spacing_; }
-  int16_t VBorderSpacing() const final { return v_spacing_; }
+  int16_t HBorderSpacing() const final {
+    CheckIsNotDestroyed();
+    return h_spacing_;
+  }
+  int16_t VBorderSpacing() const final {
+    CheckIsNotDestroyed();
+    return v_spacing_;
+  }
 
   bool ShouldCollapseBorders() const final {
+    CheckIsNotDestroyed();
     return StyleRef().BorderCollapse() == EBorderCollapse::kCollapse;
   }
 
@@ -167,17 +174,21 @@
   };
 
   void ForceSectionsRecalc() final {
+    CheckIsNotDestroyed();
     SetNeedsSectionRecalc();
     RecalcSections();
   }
 
   const Vector<ColumnStruct>& EffectiveColumns() const {
+    CheckIsNotDestroyed();
     return effective_columns_;
   }
   const Vector<int>& EffectiveColumnPositions() const {
+    CheckIsNotDestroyed();
     return effective_column_positions_;
   }
   void SetEffectiveColumnPosition(unsigned index, int position) {
+    CheckIsNotDestroyed();
     // Note that if our horizontal border-spacing changed, our position will
     // change but not our column's width. In practice, horizontal border-spacing
     // won't change often.
@@ -187,29 +198,36 @@
   }
 
   LayoutTableSection* Header() const {
+    CheckIsNotDestroyed();
     DCHECK(!NeedsSectionRecalc());
     return head_;
   }
   LayoutTableSection* Footer() const {
+    CheckIsNotDestroyed();
     DCHECK(!NeedsSectionRecalc());
     return foot_;
   }
   LayoutTableSection* FirstBody() const {
+    CheckIsNotDestroyed();
     DCHECK(!NeedsSectionRecalc());
     return first_body_;
   }
 
   void SetRowOffsetFromRepeatingHeader(LayoutUnit offset) {
+    CheckIsNotDestroyed();
     row_offset_from_repeating_header_ = offset;
   }
   LayoutUnit RowOffsetFromRepeatingHeader() const final {
+    CheckIsNotDestroyed();
     return row_offset_from_repeating_header_;
   }
 
   void SetRowOffsetFromRepeatingFooter(LayoutUnit offset) {
+    CheckIsNotDestroyed();
     row_offset_from_repeating_footer_ = offset;
   }
   LayoutUnit RowOffsetFromRepeatingFooter() const final {
+    CheckIsNotDestroyed();
     return row_offset_from_repeating_footer_;
   }
 
@@ -222,18 +240,24 @@
   LayoutTableSection* BottomNonEmptySection() const;
 
   unsigned LastEffectiveColumnIndex() const {
+    CheckIsNotDestroyed();
     return NumEffectiveColumns() - 1;
   }
 
   void SplitEffectiveColumn(unsigned index, unsigned first_span);
   void AppendEffectiveColumn(unsigned span);
-  unsigned NumEffectiveColumns() const { return effective_columns_.size(); }
+  unsigned NumEffectiveColumns() const {
+    CheckIsNotDestroyed();
+    return effective_columns_.size();
+  }
   unsigned SpanOfEffectiveColumn(unsigned effective_column_index) const {
+    CheckIsNotDestroyed();
     return effective_columns_[effective_column_index].span;
   }
 
   unsigned AbsoluteColumnToEffectiveColumn(
       unsigned absolute_column_index) const final {
+    CheckIsNotDestroyed();
     if (absolute_column_index < no_cell_colspan_at_least_)
       return absolute_column_index;
 
@@ -250,6 +274,7 @@
 
   unsigned EffectiveColumnToAbsoluteColumn(
       unsigned effective_column_index) const {
+    CheckIsNotDestroyed();
     if (effective_column_index < no_cell_colspan_at_least_)
       return effective_column_index;
 
@@ -261,6 +286,7 @@
   }
 
   LayoutUnit BorderSpacingInRowDirection() const {
+    CheckIsNotDestroyed();
     if (unsigned effective_column_count = NumEffectiveColumns())
       return static_cast<LayoutUnit>(effective_column_count + 1) *
              HBorderSpacing();
@@ -277,6 +303,7 @@
   LayoutUnit PaddingRight() const override;
 
   LayoutUnit BordersPaddingAndSpacingInRowDirection() const {
+    CheckIsNotDestroyed();
     // 'border-spacing' only applies to separate borders (see 17.6.1 The
     // separated borders model).
     return BorderStart() + BorderEnd() +
@@ -302,16 +329,24 @@
   };
   ColAndColGroup ColElementAtAbsoluteColumn(
       unsigned absolute_column_index) const {
+    CheckIsNotDestroyed();
     // The common case is to not have col/colgroup elements, make that case
     // fast.
     if (!has_col_elements_)
       return ColAndColGroup();
     return SlowColElementAtAbsoluteColumn(absolute_column_index);
   }
-  bool HasColElements() const final { return has_col_elements_; }
+  bool HasColElements() const final {
+    CheckIsNotDestroyed();
+    return has_col_elements_;
+  }
 
-  bool NeedsSectionRecalc() const { return needs_section_recalc_; }
+  bool NeedsSectionRecalc() const {
+    CheckIsNotDestroyed();
+    return needs_section_recalc_;
+  }
   void SetNeedsSectionRecalc() {
+    CheckIsNotDestroyed();
     if (DocumentBeingDestroyed())
       return;
     // For all we know, sections may have been deleted at this point. Don't
@@ -351,17 +386,23 @@
   void InvalidateCollapsedBordersForAllCellsIfNeeded();
 
   bool HasCollapsedBorders() const final {
+    CheckIsNotDestroyed();
     DCHECK(collapsed_borders_valid_);
     return has_collapsed_borders_;
   }
   bool NeedsAdjustCollapsedBorderJoints() const {
+    CheckIsNotDestroyed();
     DCHECK(collapsed_borders_valid_);
     return needs_adjust_collapsed_border_joints_;
   }
 
-  bool HasSections() const { return Header() || Footer() || FirstBody(); }
+  bool HasSections() const {
+    CheckIsNotDestroyed();
+    return Header() || Footer() || FirstBody();
+  }
 
   void RecalcSectionsIfNeeded() const final {
+    CheckIsNotDestroyed();
     if (needs_section_recalc_)
       RecalcSections();
   }
@@ -385,13 +426,17 @@
 
   bool IsLogicalWidthAuto() const;
 
-  const char* GetName() const override { return "LayoutTable"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutTable";
+  }
 
   // Whether a table has opaque foreground depends on many factors, e.g. border
   // spacing, missing cells, etc. For simplicity, just conservatively assume
   // foreground of all tables are not opaque.
   bool ForegroundIsKnownToBeOpaqueInRect(const PhysicalRect&,
                                          unsigned) const override {
+    CheckIsNotDestroyed();
     return false;
   }
 
@@ -401,6 +446,7 @@
   bool IsAbsoluteColumnCollapsed(unsigned absolute_column_index) const;
 
   bool IsAnyColumnEverCollapsed() const {
+    CheckIsNotDestroyed();
     return is_any_column_ever_collapsed_;
   }
 
@@ -417,11 +463,19 @@
   // LayoutNGTableInterface methods start.
 
   const LayoutNGTableInterface* ToLayoutNGTableInterface() const final {
+    CheckIsNotDestroyed();
     return this;
   }
-  const LayoutObject* ToLayoutObject() const final { return this; }
-  LayoutObject* ToMutableLayoutObject() final { return this; }
+  const LayoutObject* ToLayoutObject() const final {
+    CheckIsNotDestroyed();
+    return this;
+  }
+  LayoutObject* ToMutableLayoutObject() final {
+    CheckIsNotDestroyed();
+    return this;
+  }
   bool IsFixedTableLayout() const final {
+    CheckIsNotDestroyed();
     return StyleRef().IsFixedTableLayout();
   }
   LayoutNGTableSectionInterface* FirstBodyInterface() const final;
@@ -438,6 +492,7 @@
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectTable || LayoutBlock::IsOfType(type);
   }
 
@@ -502,7 +557,10 @@
 
   void DistributeExtraLogicalHeight(int extra_logical_height);
 
-  void SetIsAnyColumnEverCollapsed() { is_any_column_ever_collapsed_ = true; }
+  void SetIsAnyColumnEverCollapsed() {
+    CheckIsNotDestroyed();
+    is_any_column_ever_collapsed_ = true;
+  }
 
   // TODO(layout-dev): All mutables in this class are lazily updated by
   // recalcSections() which is called by various getter methods (e.g.
@@ -574,6 +632,7 @@
   mutable bool column_layout_objects_valid_ : 1;
   mutable unsigned no_cell_colspan_at_least_;
   unsigned CalcNoCellColspanAtLeast() const {
+    CheckIsNotDestroyed();
     for (unsigned c = 0; c < NumEffectiveColumns(); c++) {
       if (effective_columns_[c].span > 1)
         return c;
@@ -582,6 +641,7 @@
   }
 
   LogicalToPhysical<unsigned> LogicalCollapsedOuterBorderToPhysical() const {
+    CheckIsNotDestroyed();
     return LogicalToPhysical<unsigned>(
         StyleRef().GetWritingMode(), StyleRef().Direction(),
         collapsed_outer_border_start_, collapsed_outer_border_end_,
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 78cca0f..fb63566 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
@@ -38,37 +38,55 @@
         : LayoutObject::MutableForPainting(box) {}
   };
   MutableForPainting GetMutableForPainting() const {
+    CheckIsNotDestroyed();
     return MutableForPainting(*this);
   }
 
   // Should use TableStyle() instead of own style to determine cell order.
-  const ComputedStyle& TableStyle() const { return Table()->StyleRef(); }
+  const ComputedStyle& TableStyle() const {
+    CheckIsNotDestroyed();
+    return Table()->StyleRef();
+  }
 
   BorderValue BorderStartInTableDirection() const {
+    CheckIsNotDestroyed();
     return StyleRef().BorderStartUsing(TableStyle());
   }
   BorderValue BorderEndInTableDirection() const {
+    CheckIsNotDestroyed();
     return StyleRef().BorderEndUsing(TableStyle());
   }
   BorderValue BorderBeforeInTableDirection() const {
+    CheckIsNotDestroyed();
     return StyleRef().BorderBeforeUsing(TableStyle());
   }
   BorderValue BorderAfterInTableDirection() const {
+    CheckIsNotDestroyed();
     return StyleRef().BorderAfterUsing(TableStyle());
   }
 
  protected:
   explicit LayoutTableBoxComponent(Element* element)
-      : LayoutBox(element), last_paint_result_(kFullyPainted) {}
+      : LayoutBox(element), last_paint_result_(kFullyPainted) {
+    CheckIsNotDestroyed();
+  }
 
-  const LayoutObjectChildList* Children() const { return &children_; }
-  LayoutObjectChildList* Children() { return &children_; }
+  const LayoutObjectChildList* Children() const {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
+  LayoutObjectChildList* Children() {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
 
   LayoutObject* FirstChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->FirstChild();
   }
   LayoutObject* LastChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->LastChild();
   }
@@ -78,14 +96,21 @@
   // elements. For example, column's visibility:hidden doesn't apply; row's
   // visibility:hidden shouldn't hide row's background painted behind visible
   // cells, etc.
-  bool VisualRectRespectsVisibility() const final { return false; }
+  bool VisualRectRespectsVisibility() const final {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   // If you have a LayoutTableBoxComponent, use firstChild or lastChild instead.
   void SlowFirstChild() const = delete;
   void SlowLastChild() const = delete;
 
-  LayoutObjectChildList* VirtualChildren() override { return Children(); }
+  LayoutObjectChildList* VirtualChildren() override {
+    CheckIsNotDestroyed();
+    return Children();
+  }
   const LayoutObjectChildList* VirtualChildren() const override {
+    CheckIsNotDestroyed();
     return Children();
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_table_caption.cc b/third_party/blink/renderer/core/layout/layout_table_caption.cc
index 5374d52..8139b497 100644
--- a/third_party/blink/renderer/core/layout/layout_table_caption.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_caption.cc
@@ -29,23 +29,27 @@
 LayoutTableCaption::~LayoutTableCaption() = default;
 
 LayoutUnit LayoutTableCaption::ContainingBlockLogicalWidthForContent() const {
+  CheckIsNotDestroyed();
   LayoutBlock* cb = ContainingBlock();
   return cb->LogicalWidth();
 }
 
 void LayoutTableCaption::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::InsertedIntoTree();
 
   Table()->AddCaption(this);
 }
 
 void LayoutTableCaption::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::WillBeRemovedFromTree();
 
   Table()->RemoveCaption(this);
 }
 
 LayoutTable* LayoutTableCaption::Table() const {
+  CheckIsNotDestroyed();
   return To<LayoutTable>(Parent());
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_table_caption.h b/third_party/blink/renderer/core/layout/layout_table_caption.h
index 5ade10c..369bd9f 100644
--- a/third_party/blink/renderer/core/layout/layout_table_caption.h
+++ b/third_party/blink/renderer/core/layout/layout_table_caption.h
@@ -49,9 +49,13 @@
   LayoutUnit ContainingBlockLogicalWidthForContent() const override;
 
  protected:
-  bool CreatesNewFormattingContext() const final { return true; }
+  bool CreatesNewFormattingContext() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectTableCaption || LayoutBlockFlow::IsOfType(type);
   }
 
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 9963343..3d08771 100644
--- a/third_party/blink/renderer/core/layout/layout_table_cell.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_cell.cc
@@ -76,6 +76,7 @@
 }
 
 void LayoutTableCell::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::WillBeRemovedFromTree();
 
   Section()->SetNeedsCellRecalc();
@@ -101,6 +102,7 @@
 }
 
 unsigned LayoutTableCell::ParseColSpanFromDOM() const {
+  CheckIsNotDestroyed();
   DCHECK(GetNode());
   // TODO(dgrogan): HTMLTableCellElement::colSpan() already clamps to something
   // smaller than maxColumnIndex; can we just DCHECK here?
@@ -110,6 +112,7 @@
 }
 
 unsigned LayoutTableCell::ParseRowSpanFromDOM() const {
+  CheckIsNotDestroyed();
   DCHECK(GetNode());
   if (auto* cell_element = DynamicTo<HTMLTableCellElement>(GetNode()))
     return std::min<unsigned>(cell_element->rowSpan(), kMaxRowIndex);
@@ -117,6 +120,7 @@
 }
 
 void LayoutTableCell::UpdateColAndRowSpanFlags() {
+  CheckIsNotDestroyed();
   // The vast majority of table cells do not have a colspan or rowspan,
   // so we keep a bool to know if we need to bother reading from the DOM.
   has_col_span_ = GetNode() && ParseColSpanFromDOM() != 1;
@@ -124,6 +128,7 @@
 }
 
 void LayoutTableCell::ColSpanOrRowSpanChanged() {
+  CheckIsNotDestroyed();
   DCHECK(GetNode());
   DCHECK(IsA<HTMLTableCellElement>(*GetNode()));
 
@@ -141,6 +146,7 @@
 Length LayoutTableCell::LogicalWidthFromColumns(
     LayoutTableCol* first_col_for_this_cell,
     const Length& width_from_style) const {
+  CheckIsNotDestroyed();
   DCHECK(first_col_for_this_cell);
   DCHECK_EQ(first_col_for_this_cell,
             Table()
@@ -180,6 +186,7 @@
 }
 
 MinMaxSizes LayoutTableCell::PreferredLogicalWidths() const {
+  CheckIsNotDestroyed();
   // The child cells rely on the grids up in the sections to do their
   // computePreferredLogicalWidths work.  Normally the sections are set up
   // early, as table cells are added, but relayout can cause the cells to be
@@ -221,6 +228,7 @@
                                               int row_height,
                                               EVerticalAlign vertical_align,
                                               SubtreeLayoutScope& layouter) {
+  CheckIsNotDestroyed();
   int old_intrinsic_padding_before = IntrinsicPaddingBefore();
   int old_intrinsic_padding_after = IntrinsicPaddingAfter();
   int logical_height_without_intrinsic_padding = PixelSnappedLogicalHeight() -
@@ -271,10 +279,13 @@
     layouter.SetNeedsLayout(this, layout_invalidation_reason::kPaddingChanged);
 }
 
-void LayoutTableCell::UpdateLogicalWidth() {}
+void LayoutTableCell::UpdateLogicalWidth() {
+  CheckIsNotDestroyed();
+}
 
 void LayoutTableCell::SetCellLogicalWidth(int table_layout_logical_width,
                                           SubtreeLayoutScope& layouter) {
+  CheckIsNotDestroyed();
   if (table_layout_logical_width == LogicalWidth())
     return;
 
@@ -285,6 +296,7 @@
 }
 
 void LayoutTableCell::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
 
@@ -298,6 +310,7 @@
 }
 
 LayoutUnit LayoutTableCell::PaddingTop() const {
+  CheckIsNotDestroyed();
   auto result =
       ComputedCSSPaddingTop() + LogicalIntrinsicPaddingToPhysical().Top();
   // TODO(crbug.com/377847): The ToInt call should be removed when Table is
@@ -307,6 +320,7 @@
 }
 
 LayoutUnit LayoutTableCell::PaddingBottom() const {
+  CheckIsNotDestroyed();
   auto result =
       ComputedCSSPaddingBottom() + LogicalIntrinsicPaddingToPhysical().Bottom();
   // TODO(crbug.com/377847): The ToInt call should be removed when Table is
@@ -316,6 +330,7 @@
 }
 
 LayoutUnit LayoutTableCell::PaddingLeft() const {
+  CheckIsNotDestroyed();
   auto result =
       ComputedCSSPaddingLeft() + LogicalIntrinsicPaddingToPhysical().Left();
   // TODO(crbug.com/377847): The ToInt call should be removed when Table is
@@ -325,6 +340,7 @@
 }
 
 LayoutUnit LayoutTableCell::PaddingRight() const {
+  CheckIsNotDestroyed();
   auto result =
       ComputedCSSPaddingRight() + LogicalIntrinsicPaddingToPhysical().Right();
   // TODO(crbug.com/377847): The ToInt call should be removed when Table is
@@ -335,6 +351,7 @@
 
 void LayoutTableCell::SetOverrideLogicalHeightFromRowHeight(
     LayoutUnit row_height) {
+  CheckIsNotDestroyed();
   ClearIntrinsicPadding();
   SetOverrideLogicalHeight(row_height);
 }
@@ -342,6 +359,7 @@
 PhysicalOffset LayoutTableCell::OffsetFromContainerInternal(
     const LayoutObject* o,
     bool ignore_scroll_offset) const {
+  CheckIsNotDestroyed();
   DCHECK_EQ(o, Container());
 
   PhysicalOffset offset =
@@ -353,6 +371,7 @@
 }
 
 void LayoutTableCell::SetIsSpanningCollapsedRow(bool spanning_collapsed_row) {
+  CheckIsNotDestroyed();
   if (is_spanning_collapsed_row_ != spanning_collapsed_row) {
     is_spanning_collapsed_row_ = spanning_collapsed_row;
     SetShouldClipOverflow(ComputeShouldClipOverflow());
@@ -361,14 +380,15 @@
 
 void LayoutTableCell::SetIsSpanningCollapsedColumn(
     bool spanning_collapsed_column) {
+  CheckIsNotDestroyed();
   if (is_spanning_collapsed_column_ != spanning_collapsed_column) {
     is_spanning_collapsed_column_ = spanning_collapsed_column;
     SetShouldClipOverflow(ComputeShouldClipOverflow());
   }
 }
 
-void LayoutTableCell::ComputeVisualOverflow(
-    bool recompute_floats) {
+void LayoutTableCell::ComputeVisualOverflow(bool recompute_floats) {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::ComputeVisualOverflow(recompute_floats);
 
   UpdateCollapsedBorderValues();
@@ -420,11 +440,13 @@
 }
 
 bool LayoutTableCell::ComputeShouldClipOverflow() const {
+  CheckIsNotDestroyed();
   return IsSpanningCollapsedRow() || IsSpanningCollapsedColumn() ||
          LayoutBox::ComputeShouldClipOverflow();
 }
 
 LayoutUnit LayoutTableCell::CellBaselinePosition() const {
+  CheckIsNotDestroyed();
   // <http://www.w3.org/TR/2007/CR-CSS21-20070719/tables.html#height-layout>:
   // The baseline of a cell is the baseline of the first in-flow line box in the
   // cell, or the first in-flow table-row in the cell, whichever comes first. If
@@ -439,6 +461,7 @@
 // Legacy code does not support orthogonal table cells, and must match
 // row's writing mode.
 void LayoutTableCell::UpdateStyleWritingModeFromRow(const LayoutObject* row) {
+  CheckIsNotDestroyed();
   DCHECK_NE(StyleRef().GetWritingMode(), row->StyleRef().GetWritingMode());
   scoped_refptr<ComputedStyle> new_style = ComputedStyle::Clone(StyleRef());
   new_style->SetWritingMode(row->StyleRef().GetWritingMode());
@@ -462,6 +485,7 @@
 
 void LayoutTableCell::StyleDidChange(StyleDifference diff,
                                      const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(StyleRef().Display(), EDisplay::kTableCell);
 
   if (Parent() &&
@@ -526,6 +550,7 @@
 }
 
 bool LayoutTableCell::IsInEndColumn() const {
+  CheckIsNotDestroyed();
   return Table()->AbsoluteColumnToEffectiveColumn(AbsoluteColumnIndex() +
                                                   ColSpan() - 1) ==
          Table()->NumEffectiveColumns() - 1;
@@ -533,11 +558,13 @@
 
 const CSSProperty& LayoutTableCell::ResolveBorderProperty(
     const CSSProperty& property) const {
+  CheckIsNotDestroyed();
   return property.ResolveDirectionAwareProperty(TableStyle().Direction(),
                                                 TableStyle().GetWritingMode());
 }
 
 CollapsedBorderValue LayoutTableCell::ComputeCollapsedStartBorder() const {
+  CheckIsNotDestroyed();
   LayoutTable* table = Table();
   bool in_start_column = IsInStartColumn();
   LayoutTableCell* cell_preceding =
@@ -668,6 +695,7 @@
 }
 
 CollapsedBorderValue LayoutTableCell::ComputeCollapsedEndBorder() const {
+  CheckIsNotDestroyed();
   LayoutTable* table = Table();
   // Note: We have to use the effective column information instead of whether we
   // have a cell after as a table doesn't have to be regular (any row can have
@@ -798,6 +826,7 @@
 }
 
 CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder() const {
+  CheckIsNotDestroyed();
   LayoutTable* table = Table();
   LayoutTableCell* cell_above = table->CellAbove(*this);
   // We can use the border shared with |cell_above| if it is valid.
@@ -929,6 +958,7 @@
 }
 
 CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder() const {
+  CheckIsNotDestroyed();
   LayoutTable* table = Table();
   LayoutTableCell* cell_below = table->CellBelow(*this);
   // We can use the border shared with |cell_below| if it is valid.
@@ -1051,30 +1081,35 @@
 }
 
 LayoutUnit LayoutTableCell::BorderLeft() const {
+  CheckIsNotDestroyed();
   return Table()->ShouldCollapseBorders()
              ? LayoutUnit(CollapsedBorderHalfLeft(false))
              : LayoutBlockFlow::BorderLeft();
 }
 
 LayoutUnit LayoutTableCell::BorderRight() const {
+  CheckIsNotDestroyed();
   return Table()->ShouldCollapseBorders()
              ? LayoutUnit(CollapsedBorderHalfRight(false))
              : LayoutBlockFlow::BorderRight();
 }
 
 LayoutUnit LayoutTableCell::BorderTop() const {
+  CheckIsNotDestroyed();
   return Table()->ShouldCollapseBorders()
              ? LayoutUnit(CollapsedBorderHalfTop(false))
              : LayoutBlockFlow::BorderTop();
 }
 
 LayoutUnit LayoutTableCell::BorderBottom() const {
+  CheckIsNotDestroyed();
   return Table()->ShouldCollapseBorders()
              ? LayoutUnit(CollapsedBorderHalfBottom(false))
              : LayoutBlockFlow::BorderBottom();
 }
 
 bool LayoutTableCell::IsFirstColumnCollapsed() const {
+  CheckIsNotDestroyed();
   if (!RuntimeEnabledFeatures::VisibilityCollapseColumnEnabled())
     return false;
   if (!HasSetAbsoluteColumnIndex())
@@ -1083,6 +1118,7 @@
 }
 
 void LayoutTableCell::UpdateCollapsedBorderValues() const {
+  CheckIsNotDestroyed();
   bool changed = false;
 
   if (!Table()->ShouldCollapseBorders()) {
@@ -1132,18 +1168,21 @@
 void LayoutTableCell::PaintBoxDecorationBackground(
     const PaintInfo& paint_info,
     const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   TableCellPainter(*this).PaintBoxDecorationBackground(paint_info,
                                                        paint_offset);
 }
 
 void LayoutTableCell::PaintMask(const PaintInfo& paint_info,
                                 const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   TableCellPainter(*this).PaintMask(paint_info, paint_offset);
 }
 
 void LayoutTableCell::ScrollbarsChanged(bool horizontal_scrollbar_changed,
                                         bool vertical_scrollbar_changed,
                                         ScrollbarChangeContext context) {
+  CheckIsNotDestroyed();
   LayoutBlock::ScrollbarsChanged(horizontal_scrollbar_changed,
                                  vertical_scrollbar_changed);
 
@@ -1196,11 +1235,13 @@
 
 LayoutBox* LayoutTableCell::CreateAnonymousBoxWithSameTypeAs(
     const LayoutObject* parent) const {
+  CheckIsNotDestroyed();
   return LayoutObjectFactory::CreateAnonymousTableCellWithParent(*parent);
 }
 
 bool LayoutTableCell::BackgroundIsKnownToBeOpaqueInRect(
     const PhysicalRect& local_rect) const {
+  CheckIsNotDestroyed();
   // If this object has layer, the area of collapsed borders should be
   // transparent to expose the collapsed borders painted on the underlying
   // layer.
@@ -1210,6 +1251,7 @@
 }
 
 bool LayoutTableCell::HasLineIfEmpty() const {
+  CheckIsNotDestroyed();
   if (GetNode() && HasEditableStyle(*GetNode()))
     return true;
 
@@ -1218,6 +1260,7 @@
 
 void LayoutTableCell::InvalidatePaint(
     const PaintInvalidatorContext& context) const {
+  CheckIsNotDestroyed();
   TableCellPaintInvalidator(*this, context).InvalidatePaint();
 }
 
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 5ede499..f2e5b80f 100644
--- a/third_party/blink/renderer/core/layout/layout_table_cell.h
+++ b/third_party/blink/renderer/core/layout/layout_table_cell.h
@@ -94,16 +94,19 @@
   explicit LayoutTableCell(Element*);
 
   unsigned ColSpan() const final {
+    CheckIsNotDestroyed();
     if (!has_col_span_)
       return 1;
     return ParseColSpanFromDOM();
   }
   unsigned ParsedRowSpan() const {
+    CheckIsNotDestroyed();
     if (!has_row_span_)
       return 1;
     return ParseRowSpanFromDOM();
   }
   unsigned ResolvedRowSpan() const final {
+    CheckIsNotDestroyed();
     unsigned row_span = ParsedRowSpan();
     if (!row_span) {
       DCHECK(!Section()->NeedsCellRecalc());
@@ -116,24 +119,32 @@
   void ColSpanOrRowSpanChanged() final;
 
   void SetAbsoluteColumnIndex(unsigned column) {
+    CheckIsNotDestroyed();
     CHECK_LE(column, kMaxColumnIndex);
     absolute_column_index_ = column;
   }
 
   bool HasSetAbsoluteColumnIndex() const {
+    CheckIsNotDestroyed();
     return absolute_column_index_ != kUnsetColumnIndex;
   }
 
   unsigned AbsoluteColumnIndex() const final {
+    CheckIsNotDestroyed();
     DCHECK(HasSetAbsoluteColumnIndex());
     return absolute_column_index_;
   }
 
-  LayoutTableRow* Row() const { return To<LayoutTableRow>(Parent()); }
+  LayoutTableRow* Row() const {
+    CheckIsNotDestroyed();
+    return To<LayoutTableRow>(Parent());
+  }
   LayoutTableSection* Section() const {
+    CheckIsNotDestroyed();
     return To<LayoutTableSection>(Parent()->Parent());
   }
   LayoutTable* Table() const {
+    CheckIsNotDestroyed();
     return To<LayoutTable>(Parent()->Parent()->Parent());
   }
 
@@ -141,12 +152,14 @@
   LayoutTableCell* NextCell() const;
 
   unsigned RowIndex() const final {
+    CheckIsNotDestroyed();
     // This function shouldn't be called on a detached cell.
     DCHECK(Row());
     return Row()->RowIndex();
   }
 
   Length StyleOrColLogicalWidth() const final {
+    CheckIsNotDestroyed();
     const Length& style_width = StyleRef().LogicalWidth();
     if (!style_width.IsAuto())
       return style_width;
@@ -159,6 +172,7 @@
   }
 
   int LogicalHeightFromStyle() const {
+    CheckIsNotDestroyed();
     const Length& height = StyleRef().LogicalHeight();
     int style_logical_height =
         height.IsIntrinsicOrAuto()
@@ -178,6 +192,7 @@
   }
 
   int LogicalHeightForRowSizing() const {
+    CheckIsNotDestroyed();
     // FIXME: This function does too much work, and is very hot during table
     // layout!
     int adjusted_logical_height =
@@ -202,6 +217,7 @@
 
   LayoutUnit CellBaselinePosition() const;
   bool IsBaselineAligned() const {
+    CheckIsNotDestroyed();
     EVerticalAlign va = StyleRef().VerticalAlign();
     return va == EVerticalAlign::kBaseline ||
            va == EVerticalAlign::kTextBottom ||
@@ -217,10 +233,19 @@
                                EVerticalAlign,
                                SubtreeLayoutScope&);
 
-  void ClearIntrinsicPadding() { SetIntrinsicPadding(0, 0); }
+  void ClearIntrinsicPadding() {
+    CheckIsNotDestroyed();
+    SetIntrinsicPadding(0, 0);
+  }
 
-  int IntrinsicPaddingBefore() const final { return intrinsic_padding_before_; }
-  int IntrinsicPaddingAfter() const final { return intrinsic_padding_after_; }
+  int IntrinsicPaddingBefore() const final {
+    CheckIsNotDestroyed();
+    return intrinsic_padding_before_;
+  }
+  int IntrinsicPaddingAfter() const final {
+    CheckIsNotDestroyed();
+    return intrinsic_padding_after_;
+  }
 
   LayoutUnit PaddingTop() const override;
   LayoutUnit PaddingBottom() const override;
@@ -233,8 +258,12 @@
                          bool vertical_scrollbar_changed,
                          ScrollbarChangeContext = kLayout) override;
 
-  bool CellChildrenNeedLayout() const { return cell_children_need_layout_; }
+  bool CellChildrenNeedLayout() const {
+    CheckIsNotDestroyed();
+    return cell_children_need_layout_;
+  }
   void SetCellChildrenNeedLayout(bool b = true) {
+    CheckIsNotDestroyed();
     cell_children_need_layout_ = b;
   }
 
@@ -247,35 +276,50 @@
 
   // The table's style determines cell order and cell adjacency in the table.
   // Collapsed borders also use in table's inline and block directions.
-  const ComputedStyle& TableStyle() const { return Table()->StyleRef(); }
+  const ComputedStyle& TableStyle() const {
+    CheckIsNotDestroyed();
+    return Table()->StyleRef();
+  }
 
   BorderValue BorderStartInTableDirection() const {
+    CheckIsNotDestroyed();
     return StyleRef().BorderStartUsing(TableStyle());
   }
   BorderValue BorderEndInTableDirection() const {
+    CheckIsNotDestroyed();
     return StyleRef().BorderEndUsing(TableStyle());
   }
   BorderValue BorderBeforeInTableDirection() const {
+    CheckIsNotDestroyed();
     return StyleRef().BorderBeforeUsing(TableStyle());
   }
   BorderValue BorderAfterInTableDirection() const {
+    CheckIsNotDestroyed();
     return StyleRef().BorderAfterUsing(TableStyle());
   }
 
-  const char* GetName() const override { return "LayoutTableCell"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutTableCell";
+  }
 
   bool BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const override;
 
   const CollapsedBorderValues* GetCollapsedBorderValues() const {
+    CheckIsNotDestroyed();
     UpdateCollapsedBorderValues();
     return collapsed_border_values_.get();
   }
   void InvalidateCollapsedBorderValues() {
+    CheckIsNotDestroyed();
     collapsed_border_values_valid_ = false;
   }
 
   // A table cell's location is relative to its containing section.
-  LayoutBox* LocationContainer() const override { return Section(); }
+  LayoutBox* LocationContainer() const override {
+    CheckIsNotDestroyed();
+    return Section();
+  }
 
   bool HasLineIfEmpty() const override;
 
@@ -290,52 +334,68 @@
   // For the following methods, the 'start', 'end', 'before', 'after' directions
   // are all in the table's inline and block directions.
   unsigned CollapsedOuterBorderBefore() const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalfBefore(true);
   }
   unsigned CollapsedOuterBorderAfter() const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalfAfter(true);
   }
   unsigned CollapsedOuterBorderStart() const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalfStart(true);
   }
   unsigned CollapsedOuterBorderEnd() const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalfEnd(true);
   }
   unsigned CollapsedInnerBorderBefore() const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalfBefore(false);
   }
   unsigned CollapsedInnerBorderAfter() const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalfAfter(false);
   }
   unsigned CollapsedInnerBorderStart() const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalfStart(false);
   }
   unsigned CollapsedInnerBorderEnd() const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalfEnd(false);
   }
 
   bool StartsAtSameColumn(const LayoutTableCell* other) const {
+    CheckIsNotDestroyed();
     return other && AbsoluteColumnIndex() == other->AbsoluteColumnIndex();
   }
   bool EndsAtSameColumn(const LayoutTableCell* other) const {
+    CheckIsNotDestroyed();
     return other && AbsoluteColumnIndex() + ColSpan() ==
                         other->AbsoluteColumnIndex() + other->ColSpan();
   }
   bool StartsAtSameRow(const LayoutTableCell* other) const {
+    CheckIsNotDestroyed();
     return other && RowIndex() == other->RowIndex();
   }
   bool EndsAtSameRow(const LayoutTableCell* other) const {
+    CheckIsNotDestroyed();
     return other && RowIndex() + ResolvedRowSpan() ==
                         other->RowIndex() + other->ResolvedRowSpan();
   }
 
   void SetIsSpanningCollapsedRow(bool spanning_collapsed_row);
 
-  bool IsSpanningCollapsedRow() const { return is_spanning_collapsed_row_; }
+  bool IsSpanningCollapsedRow() const {
+    CheckIsNotDestroyed();
+    return is_spanning_collapsed_row_;
+  }
 
   void SetIsSpanningCollapsedColumn(bool spanningCollapsedColumn);
 
   bool IsSpanningCollapsedColumn() const {
+    CheckIsNotDestroyed();
     return is_spanning_collapsed_column_;
   }
 
@@ -344,18 +404,39 @@
   // LayoutNGTableCellInterface implementation start.
 
   const LayoutNGTableCellInterface* ToLayoutNGTableCellInterface() const final {
+    CheckIsNotDestroyed();
     return this;
   }
-  const LayoutTableCell* ToLayoutTableCell() const final { return this; }
-  const LayoutObject* ToLayoutObject() const final { return this; }
-  LayoutObject* ToMutableLayoutObject() final { return this; }
-  LayoutNGTableInterface* TableInterface() const final { return Table(); }
-  LayoutTableCell* NextCellInterface() const final { return NextCell(); }
+  const LayoutTableCell* ToLayoutTableCell() const final {
+    CheckIsNotDestroyed();
+    return this;
+  }
+  const LayoutObject* ToLayoutObject() const final {
+    CheckIsNotDestroyed();
+    return this;
+  }
+  LayoutObject* ToMutableLayoutObject() final {
+    CheckIsNotDestroyed();
+    return this;
+  }
+  LayoutNGTableInterface* TableInterface() const final {
+    CheckIsNotDestroyed();
+    return Table();
+  }
+  LayoutTableCell* NextCellInterface() const final {
+    CheckIsNotDestroyed();
+    return NextCell();
+  }
   LayoutTableCell* PreviousCellInterface() const final {
+    CheckIsNotDestroyed();
     return PreviousCell();
   }
-  LayoutNGTableRowInterface* RowInterface() const final { return Row(); }
+  LayoutNGTableRowInterface* RowInterface() const final {
+    CheckIsNotDestroyed();
+    return Row();
+  }
   LayoutNGTableSectionInterface* SectionInterface() const final {
+    CheckIsNotDestroyed();
     return Section();
   }
 
@@ -374,10 +455,14 @@
       const LayoutObject*,
       bool ignore_scroll_offset) const override;
 
-  bool CreatesNewFormattingContext() const final { return true; }
+  bool CreatesNewFormattingContext() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
  protected:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectTableCell ||
            type == kLayoutObjectTableCellLegacy ||
            LayoutBlockFlow::IsOfType(type);
@@ -402,6 +487,7 @@
       const CollapsedBorderValue& (CollapsedBorderValues::*)() const;
   LogicalToPhysical<CollapsedBorderValuesMethod>
   CollapsedBorderValuesMethodsPhysical() const {
+    CheckIsNotDestroyed();
     return LogicalToPhysical<CollapsedBorderValuesMethod>(
         // Collapsed border logical directions are in table's directions.
         TableStyle().GetWritingMode(), TableStyle().Direction(),
@@ -417,6 +503,7 @@
   static constexpr bool kInnerHalfPixelAsOneLeft = true;
 
   PhysicalToLogical<bool> InnerHalfPixelAsOneLogical() const {
+    CheckIsNotDestroyed();
     return PhysicalToLogical<bool>(
         // Collapsed border logical directions are in table's directions.
         TableStyle().GetWritingMode(), TableStyle().Direction(),
@@ -425,18 +512,22 @@
   }
 
   unsigned CollapsedBorderHalfLeft(bool outer) const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalf(kInnerHalfPixelAsOneLeft ^ outer,
                                CollapsedBorderValuesMethodsPhysical().Left());
   }
   unsigned CollapsedBorderHalfRight(bool outer) const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalf(kInnerHalfPixelAsOneRight ^ outer,
                                CollapsedBorderValuesMethodsPhysical().Right());
   }
   unsigned CollapsedBorderHalfTop(bool outer) const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalf(kInnerHalfPixelAsOneTop ^ outer,
                                CollapsedBorderValuesMethodsPhysical().Top());
   }
   unsigned CollapsedBorderHalfBottom(bool outer) const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalf(kInnerHalfPixelAsOneBottom ^ outer,
                                CollapsedBorderValuesMethodsPhysical().Bottom());
   }
@@ -444,24 +535,29 @@
   // For the following methods, the 'start', 'end', 'before', 'after' directions
   // are all in the table's inline and block directions.
   unsigned CollapsedBorderHalfStart(bool outer) const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalf(InnerHalfPixelAsOneLogical().Start() ^ outer,
                                &CollapsedBorderValues::StartBorder);
   }
   unsigned CollapsedBorderHalfEnd(bool outer) const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalf(InnerHalfPixelAsOneLogical().End() ^ outer,
                                &CollapsedBorderValues::EndBorder);
   }
   unsigned CollapsedBorderHalfBefore(bool outer) const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalf(InnerHalfPixelAsOneLogical().Before() ^ outer,
                                &CollapsedBorderValues::BeforeBorder);
   }
   unsigned CollapsedBorderHalfAfter(bool outer) const {
+    CheckIsNotDestroyed();
     return CollapsedBorderHalf(InnerHalfPixelAsOneLogical().After() ^ outer,
                                &CollapsedBorderValues::AfterBorder);
   }
 
   unsigned CollapsedBorderHalf(bool half_pixel_as_one,
                                CollapsedBorderValuesMethod m) const {
+    CheckIsNotDestroyed();
     UpdateCollapsedBorderValues();
     if (const auto* values = GetCollapsedBorderValues())
       return ((values->*m)().Width() + (half_pixel_as_one ? 1 : 0)) / 2;
@@ -469,18 +565,29 @@
   }
 
   LogicalToPhysical<int> LogicalIntrinsicPaddingToPhysical() const {
+    CheckIsNotDestroyed();
     return LogicalToPhysical<int>(
         StyleRef().GetWritingMode(), StyleRef().Direction(), 0, 0,
         intrinsic_padding_before_, intrinsic_padding_after_);
   }
-  void SetIntrinsicPaddingBefore(int p) { intrinsic_padding_before_ = p; }
-  void SetIntrinsicPaddingAfter(int p) { intrinsic_padding_after_ = p; }
+  void SetIntrinsicPaddingBefore(int p) {
+    CheckIsNotDestroyed();
+    intrinsic_padding_before_ = p;
+  }
+  void SetIntrinsicPaddingAfter(int p) {
+    CheckIsNotDestroyed();
+    intrinsic_padding_after_ = p;
+  }
   void SetIntrinsicPadding(int before, int after) {
+    CheckIsNotDestroyed();
     SetIntrinsicPaddingBefore(before);
     SetIntrinsicPaddingAfter(after);
   }
 
-  bool IsInStartColumn() const { return AbsoluteColumnIndex() == 0; }
+  bool IsInStartColumn() const {
+    CheckIsNotDestroyed();
+    return AbsoluteColumnIndex() == 0;
+  }
   bool IsInEndColumn() const;
 
   // These functions implement the CSS collapsing border conflict resolution
diff --git a/third_party/blink/renderer/core/layout/layout_table_col.cc b/third_party/blink/renderer/core/layout/layout_table_col.cc
index e2286b94..582e8bf8 100644
--- a/third_party/blink/renderer/core/layout/layout_table_col.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_col.cc
@@ -41,6 +41,7 @@
 
 void LayoutTableCol::StyleDidChange(StyleDifference diff,
                                     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   DCHECK(StyleRef().Display() == EDisplay::kTableColumn ||
          StyleRef().Display() == EDisplay::kTableColumnGroup);
 
@@ -71,6 +72,7 @@
 }
 
 void LayoutTableCol::UpdateFromElement() {
+  CheckIsNotDestroyed();
   unsigned old_span = span_;
 
   if (auto* tc = DynamicTo<HTMLTableColElement>(GetNode())) {
@@ -85,28 +87,33 @@
 }
 
 void LayoutTableCol::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   LayoutTableBoxComponent::InsertedIntoTree();
   Table()->AddColumn(this);
 }
 
 void LayoutTableCol::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   LayoutTableBoxComponent::WillBeRemovedFromTree();
   Table()->RemoveColumn(this);
 }
 
 bool LayoutTableCol::IsChildAllowed(LayoutObject* child,
                                     const ComputedStyle& style) const {
+  CheckIsNotDestroyed();
   // We cannot use isTableColumn here as style() may return 0.
   return child->IsLayoutTableCol() && style.Display() == EDisplay::kTableColumn;
 }
 
 bool LayoutTableCol::CanHaveChildren() const {
+  CheckIsNotDestroyed();
   // Cols cannot have children. This is actually necessary to fix a bug
   // with libraries.uc.edu, which makes a <p> be a table-column.
   return IsTableColumnGroup();
 }
 
 void LayoutTableCol::ClearIntrinsicLogicalWidthsDirtyBits() {
+  CheckIsNotDestroyed();
   ClearIntrinsicLogicalWidthsDirty();
 
   for (LayoutObject* child = FirstChild(); child; child = child->NextSibling())
@@ -114,6 +121,7 @@
 }
 
 LayoutTable* LayoutTableCol::Table() const {
+  CheckIsNotDestroyed();
   LayoutObject* table = Parent();
   if (table && !table->IsTable())
     table = table->Parent();
@@ -121,6 +129,7 @@
 }
 
 LayoutTableCol* LayoutTableCol::EnclosingColumnGroup() const {
+  CheckIsNotDestroyed();
   if (!Parent()->IsLayoutTableCol())
     return nullptr;
 
@@ -131,6 +140,7 @@
 }
 
 LayoutTableCol* LayoutTableCol::NextColumn() const {
+  CheckIsNotDestroyed();
   // If |this| is a column-group, the next column is the colgroup's first child
   // column.
   if (LayoutObject* first_child = FirstChild())
diff --git a/third_party/blink/renderer/core/layout/layout_table_col.h b/third_party/blink/renderer/core/layout/layout_table_col.h
index cd905f20..394fffe 100644
--- a/third_party/blink/renderer/core/layout/layout_table_col.h
+++ b/third_party/blink/renderer/core/layout/layout_table_col.h
@@ -64,13 +64,21 @@
 
   // The 'span' attribute in HTML.
   // For CSS table columns or colgroups, this is always 1.
-  unsigned Span() const { return span_; }
+  unsigned Span() const {
+    CheckIsNotDestroyed();
+    return span_;
+  }
 
-  bool IsTableColumnGroupWithColumnChildren() { return FirstChild(); }
+  bool IsTableColumnGroupWithColumnChildren() {
+    CheckIsNotDestroyed();
+    return FirstChild();
+  }
   bool IsTableColumn() const {
+    CheckIsNotDestroyed();
     return StyleRef().Display() == EDisplay::kTableColumn;
   }
   bool IsTableColumnGroup() const {
+    CheckIsNotDestroyed();
     return StyleRef().Display() == EDisplay::kTableColumnGroup;
   }
 
@@ -79,19 +87,25 @@
   // Returns the next column or column-group.
   LayoutTableCol* NextColumn() const;
 
-  const char* GetName() const override { return "LayoutTableCol"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutTableCol";
+  }
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectLayoutTableCol || LayoutBox::IsOfType(type);
   }
   void UpdateFromElement() override;
 
   MinMaxSizes PreferredLogicalWidths() const override {
+    CheckIsNotDestroyed();
     NOTREACHED();
     return MinMaxSizes();
   }
   MinMaxSizes ComputeIntrinsicLogicalWidths() const final {
+    CheckIsNotDestroyed();
     NOTREACHED();
     return MinMaxSizes();
   }
@@ -101,7 +115,10 @@
 
   bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
   bool CanHaveChildren() const override;
-  PaintLayerType LayerTypeRequired() const override { return kNoPaintLayer; }
+  PaintLayerType LayerTypeRequired() const override {
+    CheckIsNotDestroyed();
+    return kNoPaintLayer;
+  }
 
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
 
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 fbb3ffc..0d3bc91 100644
--- a/third_party/blink/renderer/core/layout/layout_table_row.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_row.cc
@@ -47,21 +47,25 @@
 }
 
 void LayoutTableRow::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   LayoutTableBoxComponent::WillBeRemovedFromTree();
 
   Section()->SetNeedsCellRecalc();
 }
 
 LayoutNGTableCellInterface* LayoutTableRow::FirstCellInterface() const {
+  CheckIsNotDestroyed();
   return FirstCell();
 }
 
 LayoutNGTableCellInterface* LayoutTableRow::LastCellInterface() const {
+  CheckIsNotDestroyed();
   return LastCell();
 }
 
 void LayoutTableRow::StyleDidChange(StyleDifference diff,
                                     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(StyleRef().Display(), EDisplay::kTableRow);
 
   // Legacy tables cannont handle relative/fixed rows.
@@ -136,6 +140,7 @@
 
 void LayoutTableRow::InvalidatePaint(
     const PaintInvalidatorContext& context) const {
+  CheckIsNotDestroyed();
   LayoutTableBoxComponent::InvalidatePaint(context);
   if (Table()->HasCollapsedBorders()) {
     // Repaint the painting layer of the table. The table's composited backing
@@ -146,6 +151,7 @@
 }
 
 void LayoutTableRow::AddChild(LayoutObject* child, LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   if (!child->IsTableCell()) {
     LayoutObject* last = before_child;
     if (!last)
@@ -222,6 +228,7 @@
 }
 
 void LayoutTableRow::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
   bool paginated = View()->GetLayoutState()->IsPaginated();
@@ -267,6 +274,7 @@
                                  const HitTestLocation& hit_test_location,
                                  const PhysicalOffset& accumulated_offset,
                                  HitTestAction action) {
+  CheckIsNotDestroyed();
   // The row and the cells are all located in the section.
   const auto* section = Section();
   PhysicalOffset section_accumulated_offset =
@@ -292,6 +300,7 @@
 
 LayoutBox::PaginationBreakability LayoutTableRow::GetPaginationBreakability(
     FragmentationEngine engine) const {
+  CheckIsNotDestroyed();
   PaginationBreakability breakability =
       LayoutTableBoxComponent::GetPaginationBreakability(engine);
   if (breakability == kAllowAnyBreaks) {
@@ -304,6 +313,7 @@
 }
 
 void LayoutTableRow::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   TableRowPainter(*this).Paint(paint_info);
 }
 
@@ -315,16 +325,19 @@
 
 LayoutBox* LayoutTableRow::CreateAnonymousBoxWithSameTypeAs(
     const LayoutObject* parent) const {
+  CheckIsNotDestroyed();
   return LayoutObjectFactory::CreateAnonymousTableRowWithParent(*parent);
 }
 
 void LayoutTableRow::ComputeLayoutOverflow() {
+  CheckIsNotDestroyed();
   ClearLayoutOverflow();
   for (LayoutTableCell* cell = FirstCell(); cell; cell = cell->NextCell())
     AddLayoutOverflowFromCell(cell);
 }
 
 void LayoutTableRow::RecalcVisualOverflow() {
+  CheckIsNotDestroyed();
   unsigned n_cols = Section()->NumCols(RowIndex());
   for (unsigned c = 0; c < n_cols; c++) {
     auto* cell = Section()->OriginatingCellAt(RowIndex(), c);
@@ -338,6 +351,7 @@
 }
 
 void LayoutTableRow::ComputeVisualOverflow() {
+  CheckIsNotDestroyed();
   const auto& old_visual_rect = VisualOverflowRect();
   ClearVisualOverflow();
   AddVisualEffectOverflow();
@@ -350,6 +364,7 @@
 }
 
 void LayoutTableRow::AddLayoutOverflowFromCell(const LayoutTableCell* cell) {
+  CheckIsNotDestroyed();
   LayoutRect cell_layout_overflow_rect =
       cell->LayoutOverflowRectForPropagation(this);
 
@@ -363,6 +378,7 @@
 }
 
 void LayoutTableRow::AddVisualOverflowFromCell(const LayoutTableCell* cell) {
+  CheckIsNotDestroyed();
   // Note: we include visual overflow of even self-painting cells,
   // because the row needs to expand to contain their area in order to paint
   // background and collapsed borders. This is different than any other
diff --git a/third_party/blink/renderer/core/layout/layout_table_row.h b/third_party/blink/renderer/core/layout/layout_table_row.h
index 82b2447e..00e8fe8 100644
--- a/third_party/blink/renderer/core/layout/layout_table_row.h
+++ b/third_party/blink/renderer/core/layout/layout_table_row.h
@@ -77,9 +77,11 @@
   LayoutTableRow* NextRow() const;
 
   LayoutTableSection* Section() const {
+    CheckIsNotDestroyed();
     return To<LayoutTableSection>(Parent());
   }
   LayoutTable* Table() const final {
+    CheckIsNotDestroyed();
     return To<LayoutTable>(Parent()->Parent());
   }
 
@@ -88,12 +90,17 @@
       const LayoutObject* parent) const override;
 
   void SetRowIndex(unsigned row_index) {
+    CheckIsNotDestroyed();
     CHECK_LE(row_index, kMaxRowIndex);
     row_index_ = row_index;
   }
 
-  bool RowIndexWasSet() const { return row_index_ != kUnsetRowIndex; }
+  bool RowIndexWasSet() const {
+    CheckIsNotDestroyed();
+    return row_index_ != kUnsetRowIndex;
+  }
   unsigned RowIndex() const final {
+    CheckIsNotDestroyed();
     DCHECK(RowIndexWasSet());
     DCHECK(
         !Section() ||
@@ -114,16 +121,21 @@
 
   void RecalcVisualOverflow() override;
 
-  const char* GetName() const override { return "LayoutTableRow"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutTableRow";
+  }
 
   // Whether a row has opaque background depends on many factors, e.g. border
   // spacing, border collapsing, missing cells, etc.
   // For simplicity, just conservatively assume all table rows are not opaque.
   bool ForegroundIsKnownToBeOpaqueInRect(const PhysicalRect&,
                                          unsigned) const override {
+    CheckIsNotDestroyed();
     return false;
   }
   bool BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const override {
+    CheckIsNotDestroyed();
     return false;
   }
 
@@ -132,18 +144,31 @@
   // LayoutNGTableRowInterface methods start.
 
   const LayoutNGTableRowInterface* ToLayoutNGTableRowInterface() const final {
+    CheckIsNotDestroyed();
     return this;
   }
-  const LayoutObject* ToLayoutObject() const final { return this; }
-  const LayoutTableRow* ToLayoutTableRow() const final { return this; }
-  LayoutNGTableInterface* TableInterface() const final { return Table(); }
+  const LayoutObject* ToLayoutObject() const final {
+    CheckIsNotDestroyed();
+    return this;
+  }
+  const LayoutTableRow* ToLayoutTableRow() const final {
+    CheckIsNotDestroyed();
+    return this;
+  }
+  LayoutNGTableInterface* TableInterface() const final {
+    CheckIsNotDestroyed();
+    return Table();
+  }
   LayoutNGTableSectionInterface* SectionInterface() const final {
+    CheckIsNotDestroyed();
     return Section();
   }
   LayoutNGTableRowInterface* NextRowInterface() const final {
+    CheckIsNotDestroyed();
     return NextRow();
   }
   LayoutNGTableRowInterface* PreviousRowInterface() const final {
+    CheckIsNotDestroyed();
     return PreviousRow();
   }
   LayoutNGTableCellInterface* FirstCellInterface() const final;
@@ -153,6 +178,7 @@
 
  private:
   MinMaxSizes ComputeIntrinsicLogicalWidths() const final {
+    CheckIsNotDestroyed();
     NOTREACHED();
     return MinMaxSizes();
   }
@@ -162,6 +188,7 @@
   void AddVisualOverflowFromCell(const LayoutTableCell*);
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectTableRow ||
            LayoutTableBoxComponent::IsOfType(type);
   }
@@ -173,6 +200,7 @@
   void UpdateLayout() override;
 
   PaintLayerType LayerTypeRequired() const override {
+    CheckIsNotDestroyed();
     if (HasTransformRelatedProperty() || HasHiddenBackface() ||
         CreatesGroup() || StyleRef().ShouldCompositeForCurrentAnimations() ||
         IsStickyPositioned())
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 28e6cebb..bee35de 100644
--- a/third_party/blink/renderer/core/layout/layout_table_section.cc
+++ b/third_party/blink/renderer/core/layout/layout_table_section.cc
@@ -107,6 +107,7 @@
 
 void LayoutTableSection::StyleDidChange(StyleDifference diff,
                                         const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   DCHECK(StyleRef().Display() == EDisplay::kTableFooterGroup ||
          StyleRef().Display() == EDisplay::kTableRowGroup ||
          StyleRef().Display() == EDisplay::kTableHeaderGroup);
@@ -140,6 +141,7 @@
 }
 
 void LayoutTableSection::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   LayoutTableBoxComponent::WillBeRemovedFromTree();
 
   // Preventively invalidate our cells as we may be re-inserted into
@@ -149,6 +151,7 @@
 
 void LayoutTableSection::AddChild(LayoutObject* child,
                                   LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   if (!child->IsTableRow()) {
     LayoutObject* last = before_child;
     if (!last)
@@ -240,6 +243,7 @@
 }
 
 void LayoutTableSection::AddCell(LayoutTableCell* cell, LayoutTableRow* row) {
+  CheckIsNotDestroyed();
   // We don't insert the cell if we need cell recalc as our internal columns'
   // representation will have drifted from the table's representation. Also
   // recalcCells will call addCell at a later time after sync'ing our columns'
@@ -308,6 +312,7 @@
 }
 
 bool LayoutTableSection::RowHasOnlySpanningCells(unsigned row) {
+  CheckIsNotDestroyed();
   if (grid_[row].grid_cells.IsEmpty())
     return false;
 
@@ -326,6 +331,7 @@
 void LayoutTableSection::PopulateSpanningRowsHeightFromCell(
     LayoutTableCell* cell,
     struct SpanningRowsHeight& spanning_rows_height) {
+  CheckIsNotDestroyed();
   const unsigned row_span = cell->ResolvedRowSpan();
   const unsigned row_index = cell->RowIndex();
 
@@ -360,6 +366,7 @@
     float total_percent,
     int& extra_row_spanning_height,
     Vector<int>& rows_height) {
+  CheckIsNotDestroyed();
   if (!extra_row_spanning_height || !total_percent)
     return;
 
@@ -420,6 +427,7 @@
     float total_percent,
     int& extra_row_spanning_height,
     Vector<int>& rows_height) {
+  CheckIsNotDestroyed();
   if (!extra_row_spanning_height || !total_percent)
     return;
 
@@ -448,6 +456,7 @@
     int total_auto_rows_height,
     int& extra_row_spanning_height,
     Vector<int>& rows_height) {
+  CheckIsNotDestroyed();
   if (!extra_row_spanning_height || !total_auto_rows_height)
     return;
 
@@ -478,6 +487,7 @@
     int total_remaining_rows_height,
     int& extra_row_spanning_height,
     Vector<int>& rows_height) {
+  CheckIsNotDestroyed();
   if (!extra_row_spanning_height || !total_remaining_rows_height)
     return;
 
@@ -543,6 +553,7 @@
     unsigned row_to_apply_extra_height,
     unsigned& extra_table_height_to_propgate,
     Vector<int>& rows_count_with_only_spanning_cells) {
+  CheckIsNotDestroyed();
   DCHECK(RowHasOnlySpanningCells(row));
 
   unsigned row_height = 0;
@@ -597,6 +608,7 @@
     struct SpanningRowsHeight& spanning_rows_height,
     unsigned& extra_height_to_propagate,
     Vector<int>& rows_count_with_only_spanning_cells) {
+  CheckIsNotDestroyed();
   DCHECK(spanning_rows_height.row_height.size());
 
   int accumulated_position_increase = 0;
@@ -626,6 +638,7 @@
 // height of rows in rowSpan cell.
 void LayoutTableSection::DistributeRowSpanHeightToRows(
     SpanningLayoutTableCells& row_span_cells) {
+  CheckIsNotDestroyed();
   DCHECK(row_span_cells.size());
 
   // 'rowSpanCells' list is already sorted based on the cells rowIndex in
@@ -783,6 +796,7 @@
 }
 
 bool LayoutTableSection::RowHasVisibilityCollapse(unsigned row) const {
+  CheckIsNotDestroyed();
   return ((grid_[row].row &&
            grid_[row].row->StyleRef().Visibility() == EVisibility::kCollapse) ||
           StyleRef().Visibility() == EVisibility::kCollapse);
@@ -795,6 +809,7 @@
 void LayoutTableSection::UpdateBaselineForCell(LayoutTableCell* cell,
                                                unsigned row,
                                                LayoutUnit& baseline_descent) {
+  CheckIsNotDestroyed();
   if (!cell->IsBaselineAligned())
     return;
 
@@ -822,6 +837,7 @@
 }
 
 int16_t LayoutTableSection::VBorderSpacingBeforeFirstRow() const {
+  CheckIsNotDestroyed();
   // We ignore the border-spacing on any non-top section, as it is already
   // included in the previous section's last row position.
   if (this != Table()->TopSection())
@@ -830,6 +846,7 @@
 }
 
 int LayoutTableSection::CalcRowLogicalHeight() {
+  CheckIsNotDestroyed();
 #if DCHECK_IS_ON()
   SetLayoutNeededForbiddenScope layout_forbidden_scope(*this);
 #endif
@@ -975,6 +992,7 @@
 }
 
 void LayoutTableSection::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
   CHECK(!NeedsCellRecalc());
@@ -1047,6 +1065,7 @@
 void LayoutTableSection::DistributeExtraLogicalHeightToPercentRows(
     int& extra_logical_height,
     int total_percent) {
+  CheckIsNotDestroyed();
   if (!total_percent)
     return;
 
@@ -1079,6 +1098,7 @@
 void LayoutTableSection::DistributeExtraLogicalHeightToAutoRows(
     int& extra_logical_height,
     unsigned auto_rows_count) {
+  CheckIsNotDestroyed();
   if (!auto_rows_count)
     return;
 
@@ -1098,6 +1118,7 @@
 
 void LayoutTableSection::DistributeRemainingExtraLogicalHeight(
     int& extra_logical_height) {
+  CheckIsNotDestroyed();
   unsigned total_rows = grid_.size();
 
   if (extra_logical_height <= 0 || !row_pos_[total_rows])
@@ -1128,6 +1149,7 @@
 
 int LayoutTableSection::DistributeExtraLogicalHeightToRows(
     int extra_logical_height) {
+  CheckIsNotDestroyed();
   if (!extra_logical_height)
     return extra_logical_height;
 
@@ -1166,6 +1188,7 @@
 }
 
 void LayoutTableSection::LayoutRows() {
+  CheckIsNotDestroyed();
 #if DCHECK_IS_ON()
   SetLayoutNeededForbiddenScope layout_forbidden_scope(*this);
 #endif
@@ -1291,6 +1314,7 @@
 
 void LayoutTableSection::UpdateLogicalWidthForCollapsedCells(
     const Vector<int>& col_collapsed_width) {
+  CheckIsNotDestroyed();
   if (!RuntimeEnabledFeatures::VisibilityCollapseColumnEnabled())
     return;
   unsigned total_rows = grid_.size();
@@ -1331,6 +1355,7 @@
 
 int LayoutTableSection::PaginationStrutForRow(LayoutTableRow* row,
                                               LayoutUnit logical_offset) const {
+  CheckIsNotDestroyed();
   DCHECK(row);
   const LayoutTableSection* footer = Table()->Footer();
   bool make_room_for_repeating_footer =
@@ -1365,6 +1390,7 @@
 }
 
 void LayoutTableSection::ComputeVisualOverflowFromDescendants() {
+  CheckIsNotDestroyed();
   auto old_self_visual_overflow_rect = SelfVisualOverflowRect();
   ClearVisualOverflow();
 
@@ -1428,24 +1454,29 @@
 }
 
 void LayoutTableSection::ComputeLayoutOverflowFromDescendants() {
+  CheckIsNotDestroyed();
   ClearLayoutOverflow();
   for (auto* row = FirstRow(); row; row = row->NextRow())
     AddLayoutOverflowFromChild(*row);
 }
 
 LayoutNGTableRowInterface* LayoutTableSection::FirstRowInterface() const {
+  CheckIsNotDestroyed();
   return FirstRow();
 }
 LayoutNGTableRowInterface* LayoutTableSection::LastRowInterface() const {
+  CheckIsNotDestroyed();
   return LastRow();
 }
 const LayoutNGTableCellInterface* LayoutTableSection::PrimaryCellInterfaceAt(
     unsigned row,
     unsigned effective_column) const {
+  CheckIsNotDestroyed();
   return PrimaryCellAt(row, effective_column);
 }
 
 bool LayoutTableSection::RecalcLayoutOverflow() {
+  CheckIsNotDestroyed();
   if (!ChildNeedsLayoutOverflowRecalc())
     return false;
   ClearChildNeedsLayoutOverflowRecalc();
@@ -1475,6 +1506,7 @@
 }
 
 void LayoutTableSection::RecalcVisualOverflow() {
+  CheckIsNotDestroyed();
   SECURITY_CHECK(!needs_cell_recalc_);
   unsigned total_rows = grid_.size();
   for (unsigned r = 0; r < total_rows; r++) {
@@ -1490,6 +1522,7 @@
 
 void LayoutTableSection::MarkAllCellsWidthsDirtyAndOrNeedsLayout(
     LayoutTable::WhatToMarkAllCells what_to_mark) {
+  CheckIsNotDestroyed();
   for (LayoutTableRow* row = FirstRow(); row; row = row->NextRow()) {
     for (LayoutTableCell* cell = row->FirstCell(); cell;
          cell = cell->NextCell()) {
@@ -1501,6 +1534,7 @@
 }
 
 LayoutUnit LayoutTableSection::FirstLineBoxBaseline() const {
+  CheckIsNotDestroyed();
   DCHECK(!NeedsCellRecalc());
   if (!grid_.size())
     return LayoutUnit(-1);
@@ -1522,11 +1556,13 @@
 }
 
 void LayoutTableSection::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   TableSectionPainter(*this).Paint(paint_info);
 }
 
 LayoutRect LayoutTableSection::LogicalRectForWritingModeAndDirection(
     const PhysicalRect& rect) const {
+  CheckIsNotDestroyed();
   LayoutRect table_aligned_rect = FlipForWritingMode(rect);
 
   if (!TableStyle().IsHorizontalWritingMode())
@@ -1545,6 +1581,7 @@
     const LayoutRect& damage_rect,
     CellSpan& rows,
     CellSpan& columns) const {
+  CheckIsNotDestroyed();
   DCHECK(!NeedsCellRecalc());
   if (!grid_.size()) {
     rows = CellSpan();
@@ -1615,6 +1652,7 @@
 }
 
 CellSpan LayoutTableSection::SpannedRows(const LayoutRect& flipped_rect) const {
+  CheckIsNotDestroyed();
   // Find the first row that starts after rect top.
   unsigned next_row = static_cast<unsigned>(
       std::upper_bound(row_pos_.begin(), row_pos_.end(), flipped_rect.Y()) -
@@ -1644,6 +1682,7 @@
 
 CellSpan LayoutTableSection::SpannedEffectiveColumns(
     const LayoutRect& flipped_rect) const {
+  CheckIsNotDestroyed();
   const Vector<int>& column_pos = Table()->EffectiveColumnPositions();
 
   // Find the first column that starts after rect left.
@@ -1678,6 +1717,7 @@
 }
 
 void LayoutTableSection::RecalcCells() {
+  CheckIsNotDestroyed();
   DCHECK(needs_cell_recalc_);
   // We reset the flag here to ensure that |addCell| works. This is safe to do
   // as fillRowsWithDefaultStartingAtPosition makes sure we match the table's
@@ -1724,6 +1764,7 @@
 // FIXME: This function could be made O(1) in certain cases (like for the
 // non-most-constrainive cells' case).
 void LayoutTableSection::RowLogicalHeightChanged(LayoutTableRow* row) {
+  CheckIsNotDestroyed();
   if (NeedsCellRecalc())
     return;
 
@@ -1736,6 +1777,7 @@
 }
 
 void LayoutTableSection::SetNeedsCellRecalc() {
+  CheckIsNotDestroyed();
   needs_cell_recalc_ = true;
   SetNeedsOverflowRecalc();
   if (LayoutTable* t = Table())
@@ -1743,6 +1785,7 @@
 }
 
 unsigned LayoutTableSection::NumEffectiveColumns() const {
+  CheckIsNotDestroyed();
   unsigned result = 0;
 
   for (unsigned r = 0; r < grid_.size(); ++r) {
@@ -1760,6 +1803,7 @@
 LayoutTableCell* LayoutTableSection::OriginatingCellAt(
     unsigned row,
     unsigned effective_column) {
+  CheckIsNotDestroyed();
   SECURITY_CHECK(!needs_cell_recalc_);
   if (effective_column >= NumCols(row))
     return nullptr;
@@ -1774,6 +1818,7 @@
 }
 
 void LayoutTableSection::AppendEffectiveColumn(unsigned pos) {
+  CheckIsNotDestroyed();
   DCHECK(!needs_cell_recalc_);
 
   for (auto& row : grid_)
@@ -1781,6 +1826,7 @@
 }
 
 void LayoutTableSection::SplitEffectiveColumn(unsigned pos, unsigned first) {
+  CheckIsNotDestroyed();
   DCHECK(!needs_cell_recalc_);
 
   if (c_col_ > pos)
@@ -1810,6 +1856,7 @@
                                      const HitTestLocation& hit_test_location,
                                      const PhysicalOffset& accumulated_offset,
                                      HitTestAction action) {
+  CheckIsNotDestroyed();
   // If we have no children then we have nothing to do.
   if (!FirstRow())
     return false;
@@ -1880,12 +1927,14 @@
 
 LayoutBox* LayoutTableSection::CreateAnonymousBoxWithSameTypeAs(
     const LayoutObject* parent) const {
+  CheckIsNotDestroyed();
   return LayoutObjectFactory::CreateAnonymousTableSectionWithParent(*parent);
 }
 
 void LayoutTableSection::SetLogicalPositionForCell(
     LayoutTableCell* cell,
     unsigned effective_column) const {
+  CheckIsNotDestroyed();
   LayoutPoint cell_location(0, row_pos_[cell->RowIndex()]);
   int16_t horizontal_border_spacing = Table()->HBorderSpacing();
 
@@ -1908,6 +1957,7 @@
 void LayoutTableSection::RelayoutCellIfFlexed(LayoutTableCell& cell,
                                               int row_index,
                                               int row_height) {
+  CheckIsNotDestroyed();
   // Force percent height children to lay themselves out again now that the
   // cell's final height is determined.
   // FIXME: There is still more work to do here to fully match WinIE (should
@@ -1954,6 +2004,7 @@
 
 int LayoutTableSection::LogicalHeightForRow(
     const LayoutTableRow& row_object) const {
+  CheckIsNotDestroyed();
   unsigned row_index = row_object.RowIndex();
   DCHECK_LT(row_index, grid_.size());
   int logical_height = 0;
@@ -1994,6 +2045,7 @@
 }
 
 int LayoutTableSection::OffsetForRepeatedHeader() const {
+  CheckIsNotDestroyed();
   LayoutTableSection* header = Table()->Header();
   if (header && header != this)
     return Table()->RowOffsetFromRepeatingHeader().ToInt();
@@ -2003,6 +2055,7 @@
 
 void LayoutTableSection::AdjustRowForPagination(LayoutTableRow& row_object,
                                                 SubtreeLayoutScope& layouter) {
+  CheckIsNotDestroyed();
   row_object.SetPaginationStrut(LayoutUnit());
   row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object)));
   if (!IsPageLogicalHeightKnown())
@@ -2070,6 +2123,7 @@
 }
 
 bool LayoutTableSection::GroupShouldRepeat() const {
+  CheckIsNotDestroyed();
   DCHECK(Table()->Header() == this || Table()->Footer() == this);
   if (GetLegacyPaginationBreakability() == kAllowAnyBreaks)
     return false;
@@ -2095,6 +2149,7 @@
     const LayoutBoxModelObject* ancestor,
     TransformState& transform_state,
     VisualRectFlags flags) const {
+  CheckIsNotDestroyed();
   if (ancestor == this)
     return true;
   // Repeating table headers and footers are painted once per
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 da9a4b3..c46a917 100644
--- a/third_party/blink/renderer/core/layout/layout_table_section.h
+++ b/third_party/blink/renderer/core/layout/layout_table_section.h
@@ -127,7 +127,10 @@
 
   void MarkAllCellsWidthsDirtyAndOrNeedsLayout(LayoutTable::WhatToMarkAllCells);
 
-  LayoutTable* Table() const final { return To<LayoutTable>(Parent()); }
+  LayoutTable* Table() const final {
+    CheckIsNotDestroyed();
+    return To<LayoutTable>(Parent());
+  }
 
   typedef Vector<LayoutTableCell*, 2> SpanningLayoutTableCells;
 
@@ -148,15 +151,18 @@
   };
 
   TableGridCell& GridCellAt(unsigned row, unsigned effective_column) {
+    CheckIsNotDestroyed();
     SECURITY_DCHECK(!needs_cell_recalc_);
     return grid_[row].grid_cells[effective_column];
   }
   const TableGridCell& GridCellAt(unsigned row,
                                   unsigned effective_column) const {
+    CheckIsNotDestroyed();
     SECURITY_DCHECK(!needs_cell_recalc_);
     return grid_[row].grid_cells[effective_column];
   }
   LayoutTableCell* PrimaryCellAt(unsigned row, unsigned effective_column) {
+    CheckIsNotDestroyed();
     SECURITY_DCHECK(!needs_cell_recalc_);
     auto& grid_cells = grid_[row].grid_cells;
     if (effective_column >= grid_cells.size())
@@ -165,6 +171,7 @@
   }
   const LayoutTableCell* PrimaryCellAt(unsigned row,
                                        unsigned effective_column) const {
+    CheckIsNotDestroyed();
     return const_cast<LayoutTableSection*>(this)->PrimaryCellAt(
         row, effective_column);
   }
@@ -174,11 +181,13 @@
   LayoutTableCell* OriginatingCellAt(unsigned row, unsigned effective_column);
   const LayoutTableCell* OriginatingCellAt(unsigned row,
                                            unsigned effective_column) const {
+    CheckIsNotDestroyed();
     return const_cast<LayoutTableSection*>(this)->OriginatingCellAt(
         row, effective_column);
   }
 
   unsigned NumCols(unsigned row) const final {
+    CheckIsNotDestroyed();
     DCHECK(!NeedsCellRecalc());
     return grid_[row].grid_cells.size();
   }
@@ -186,10 +195,12 @@
   // Returns null for cells with a rowspan that exceed the last row. Possibly
   // others.
   LayoutTableRow* RowLayoutObjectAt(unsigned row) {
+    CheckIsNotDestroyed();
     SECURITY_DCHECK(!needs_cell_recalc_);
     return grid_[row].row;
   }
   const LayoutTableRow* RowLayoutObjectAt(unsigned row) const {
+    CheckIsNotDestroyed();
     SECURITY_DCHECK(!needs_cell_recalc_);
     return grid_[row].row;
   }
@@ -198,6 +209,7 @@
   void SplitEffectiveColumn(unsigned pos, unsigned first);
 
   unsigned NumRows() const final {
+    CheckIsNotDestroyed();
     DCHECK(!NeedsCellRecalc());
     return grid_.size();
   }
@@ -214,14 +226,21 @@
   // m_needsCellRecalc before accessing m_grid.
   void RecalcCells();
   void RecalcCellsIfNeeded() {
+    CheckIsNotDestroyed();
     if (needs_cell_recalc_)
       RecalcCells();
   }
 
-  bool NeedsCellRecalc() const { return needs_cell_recalc_; }
+  bool NeedsCellRecalc() const {
+    CheckIsNotDestroyed();
+    return needs_cell_recalc_;
+  }
   void SetNeedsCellRecalc() final;
 
-  LayoutUnit RowBaseline(unsigned row) { return grid_[row].baseline; }
+  LayoutUnit RowBaseline(unsigned row) {
+    CheckIsNotDestroyed();
+    return grid_[row].baseline;
+  }
 
   void RowLogicalHeightChanged(LayoutTableRow*);
 
@@ -247,23 +266,33 @@
                                       CellSpan& columns) const;
 
   const HashSet<const LayoutTableCell*>& VisuallyOverflowingCells() const {
+    CheckIsNotDestroyed();
     return visually_overflowing_cells_;
   }
   bool HasVisuallyOverflowingCell() const {
+    CheckIsNotDestroyed();
     return visually_overflowing_cells_.size() || force_full_paint_;
   }
-  bool HasMultipleCellLevels() const { return has_multiple_cell_levels_; }
+  bool HasMultipleCellLevels() const {
+    CheckIsNotDestroyed();
+    return has_multiple_cell_levels_;
+  }
 
-  const char* GetName() const override { return "LayoutTableSection"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutTableSection";
+  }
 
   // Whether a section has opaque background depends on many factors, e.g.
   // border spacing, border collapsing, missing cells, etc. For simplicity,
   // just conservatively assume all table sections are not opaque.
   bool ForegroundIsKnownToBeOpaqueInRect(const PhysicalRect&,
                                          unsigned) const override {
+    CheckIsNotDestroyed();
     return false;
   }
   bool BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const override {
+    CheckIsNotDestroyed();
     return false;
   }
 
@@ -275,20 +304,27 @@
       VisualRectFlags = kDefaultVisualRectFlags) const override;
 
   bool IsRepeatingHeaderGroup() const final {
+    CheckIsNotDestroyed();
     return is_repeating_header_group_;
   }
   bool IsRepeatingFooterGroup() const final {
+    CheckIsNotDestroyed();
     return is_repeating_footer_group_;
   }
 
   void UpdateLayout() override;
 
-  CellSpan FullSectionRowSpan() const { return CellSpan(0, grid_.size()); }
+  CellSpan FullSectionRowSpan() const {
+    CheckIsNotDestroyed();
+    return CellSpan(0, grid_.size());
+  }
   CellSpan FullTableEffectiveColumnSpan() const {
+    CheckIsNotDestroyed();
     return CellSpan(0, Table()->NumEffectiveColumns());
   }
 
   void DetermineIfHeaderGroupShouldRepeat() {
+    CheckIsNotDestroyed();
     is_repeating_header_group_ = HeaderGroupShouldRepeat();
   }
 
@@ -296,6 +332,7 @@
   bool RowHasVisibilityCollapse(unsigned row) const;
 
   void DetermineIfFooterGroupShouldRepeat() {
+    CheckIsNotDestroyed();
     is_repeating_footer_group_ = FooterGroupShouldRepeat();
   }
 
@@ -310,13 +347,26 @@
 
   const LayoutNGTableSectionInterface* ToLayoutNGTableSectionInterface()
       const final {
+    CheckIsNotDestroyed();
     return this;
   }
-  const LayoutTableSection* ToLayoutTableSection() const final { return this; }
-  const LayoutObject* ToLayoutObject() const final { return this; }
-  LayoutObject* ToMutableLayoutObject() final { return this; }
+  const LayoutTableSection* ToLayoutTableSection() const final {
+    CheckIsNotDestroyed();
+    return this;
+  }
+  const LayoutObject* ToLayoutObject() const final {
+    CheckIsNotDestroyed();
+    return this;
+  }
+  LayoutObject* ToMutableLayoutObject() final {
+    CheckIsNotDestroyed();
+    return this;
+  }
 
-  LayoutNGTableInterface* TableInterface() const final { return Table(); }
+  LayoutNGTableInterface* TableInterface() const final {
+    CheckIsNotDestroyed();
+    return Table();
+  }
   LayoutNGTableRowInterface* FirstRowInterface() const final;
   LayoutNGTableRowInterface* LastRowInterface() const final;
   const LayoutNGTableCellInterface* PrimaryCellInterfaceAt(
@@ -333,6 +383,7 @@
 
  private:
   MinMaxSizes ComputeIntrinsicLogicalWidths() const final {
+    CheckIsNotDestroyed();
     NOTREACHED();
     return MinMaxSizes();
   }
@@ -340,21 +391,25 @@
   void ComputeVisualOverflowFromDescendants();
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectTableSection || LayoutBox::IsOfType(type);
   }
 
   void WillBeRemovedFromTree() override;
 
   int BorderSpacingForRow(unsigned row) const {
+    CheckIsNotDestroyed();
     return grid_[row].row ? Table()->VBorderSpacing() : 0;
   }
 
   void EnsureRows(unsigned num_rows) {
+    CheckIsNotDestroyed();
     if (num_rows > grid_.size())
       grid_.Grow(num_rows);
   }
 
   void EnsureCols(unsigned row_index, unsigned num_cols) {
+    CheckIsNotDestroyed();
     if (num_cols > NumCols(row_index))
       grid_[row_index].grid_cells.Grow(num_cols);
   }
@@ -423,10 +478,12 @@
   int OffsetForRepeatedHeader() const;
 
   bool HeaderGroupShouldRepeat() const {
+    CheckIsNotDestroyed();
     return Table()->Header() == this && GroupShouldRepeat();
   }
 
   bool FooterGroupShouldRepeat() const {
+    CheckIsNotDestroyed();
     return Table()->Footer() == this && GroupShouldRepeat();
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc
index 5bd1bd8..75d911a 100644
--- a/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -196,11 +196,13 @@
 }
 
 bool LayoutText::IsWordBreak() const {
+  CheckIsNotDestroyed();
   return false;
 }
 
 void LayoutText::StyleDidChange(StyleDifference diff,
                                 const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   // There is no need to ever schedule paint invalidations from a style change
   // of a text run, since we already did this for the parent of the text run.
   // We do have to schedule layouts, though, since a style change can force us
@@ -237,6 +239,7 @@
 }
 
 void LayoutText::RemoveAndDestroyTextBoxes() {
+  CheckIsNotDestroyed();
   if (!DocumentBeingDestroyed()) {
     if (FirstTextBox()) {
       if (IsBR()) {
@@ -274,6 +277,7 @@
 }
 
 void LayoutText::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   if (SecureTextTimer* secure_text_timer = GetSecureTextTimers().Take(this))
     delete secure_text_timer;
 
@@ -291,24 +295,29 @@
 }
 
 void LayoutText::ExtractTextBox(InlineTextBox* box) {
+  CheckIsNotDestroyed();
   MutableTextBoxes().ExtractLineBox(box);
 }
 
 void LayoutText::AttachTextBox(InlineTextBox* box) {
+  CheckIsNotDestroyed();
   MutableTextBoxes().AttachLineBox(box);
 }
 
 void LayoutText::RemoveTextBox(InlineTextBox* box) {
+  CheckIsNotDestroyed();
   MutableTextBoxes().RemoveLineBox(box);
 }
 
 void LayoutText::DeleteTextBoxes() {
+  CheckIsNotDestroyed();
   if (!IsInLayoutNGInlineFormattingContext())
     return MutableTextBoxes().DeleteLineBoxes();
   DetachAbstractInlineTextBoxesIfNeeded();
 }
 
 void LayoutText::DetachAbstractInlineTextBoxes() {
+  CheckIsNotDestroyed();
   // TODO(layout-dev): Because We should call |WillDestroy()| once for
   // associated fragments, when you reuse fragments, you should construct
   // NGAbstractInlineTextBox for them.
@@ -327,6 +336,7 @@
 }
 
 void LayoutText::SetFirstInlineFragment(NGPaintFragment* first_fragment) {
+  CheckIsNotDestroyed();
   CHECK(IsInLayoutNGInlineFormattingContext());
   DCHECK(!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
   DetachAbstractInlineTextBoxesIfNeeded();
@@ -334,6 +344,7 @@
 }
 
 void LayoutText::ClearFirstInlineFragmentItemIndex() {
+  CheckIsNotDestroyed();
   CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
   DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
   DetachAbstractInlineTextBoxesIfNeeded();
@@ -341,6 +352,7 @@
 }
 
 void LayoutText::SetFirstInlineFragmentItemIndex(wtf_size_t index) {
+  CheckIsNotDestroyed();
   CHECK(IsInLayoutNGInlineFormattingContext());
   // TODO(yosin): Call |NGAbstractInlineTextBox::WillDestroy()|.
   DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
@@ -350,6 +362,7 @@
 }
 
 void LayoutText::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
       SetFirstInlineFragment(nullptr);
@@ -373,6 +386,7 @@
 }
 
 Vector<LayoutText::TextBoxInfo> LayoutText::GetTextBoxInfo() const {
+  CheckIsNotDestroyed();
   // This function may kick the layout (e.g., |LocalRect()|), but Inspector may
   // call this function outside of the layout phase.
   FontCachePurgePreventer fontCachePurgePreventer;
@@ -450,6 +464,7 @@
 }
 
 bool LayoutText::HasInlineFragments() const {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
       return first_paint_fragment_;
@@ -460,11 +475,13 @@
 }
 
 scoped_refptr<StringImpl> LayoutText::OriginalText() const {
+  CheckIsNotDestroyed();
   auto* text_node = DynamicTo<Text>(GetNode());
   return text_node ? text_node->DataImpl() : nullptr;
 }
 
 String LayoutText::PlainText() const {
+  CheckIsNotDestroyed();
   if (GetNode())
     return blink::PlainText(EphemeralRange::RangeOfContents(*GetNode()));
 
@@ -543,6 +560,7 @@
 template <typename PhysicalRectCollector>
 void LayoutText::CollectLineBoxRects(const PhysicalRectCollector& yield,
                                      ClippingOption option) const {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     NGInlineCursor cursor;
     cursor.MoveTo(*this);
@@ -576,6 +594,7 @@
 
 void LayoutText::AbsoluteQuads(Vector<FloatQuad>& quads,
                                MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   CollectLineBoxRects([this, &quads, mode](const PhysicalRect& r) {
     quads.push_back(LocalRectToAbsoluteQuad(r, mode));
   });
@@ -584,6 +603,7 @@
 bool LayoutText::MapDOMOffsetToTextContentOffset(const NGOffsetMapping& mapping,
                                                  unsigned* start,
                                                  unsigned* end) const {
+  CheckIsNotDestroyed();
   DCHECK_LE(*start, *end);
 
   // Adjust |start| to the next non-collapsed offset if |start| is collapsed.
@@ -626,6 +646,7 @@
 void LayoutText::AbsoluteQuadsForRange(Vector<FloatQuad>& quads,
                                        unsigned start,
                                        unsigned end) const {
+  CheckIsNotDestroyed();
   // Work around signed/unsigned issues. This function takes unsigneds, and is
   // often passed UINT_MAX to mean "all the way to the end". InlineTextBox
   // coordinates are unsigneds, so changing this function to take ints causes
@@ -726,6 +747,7 @@
 }
 
 FloatRect LayoutText::LocalBoundingBoxRectForAccessibility() const {
+  CheckIsNotDestroyed();
   FloatRect result;
   const LayoutBlock* block_for_flipping =
       UNLIKELY(HasFlippedBlocksWritingMode()) ? ContainingBlock() : nullptr;
@@ -839,6 +861,7 @@
 
 PositionWithAffinity LayoutText::PositionForPoint(
     const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     NGInlineCursor cursor;
     for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject()) {
@@ -914,6 +937,7 @@
     const InlineBox* inline_box,
     int caret_offset,
     LayoutUnit* extra_width_to_end_of_line) const {
+  CheckIsNotDestroyed();
   if (!inline_box)
     return LayoutRect();
 
@@ -1023,6 +1047,7 @@
     HashSet<const SimpleFontData*>* fallback_fonts,
     FloatRect* glyph_bounds_accumulation,
     float expansion) const {
+  CheckIsNotDestroyed();
   if (StyleRef().HasTextCombine() && IsCombineText()) {
     const LayoutTextCombine* combine_text = ToLayoutTextCombine(this);
     if (combine_text->IsCombined())
@@ -1061,6 +1086,7 @@
                                    LayoutUnit& max_width,
                                    bool& strip_front_spaces,
                                    TextDirection direction) {
+  CheckIsNotDestroyed();
   float float_min_width = 0.0f, float_max_width = 0.0f;
 
   // Convert leadWidth to a float here, to avoid multiple implict conversions
@@ -1162,6 +1188,7 @@
 }
 
 float LayoutText::MinLogicalWidth() const {
+  CheckIsNotDestroyed();
   if (IntrinsicLogicalWidthsDirty())
     const_cast<LayoutText*>(this)->ComputePreferredLogicalWidths(0);
 
@@ -1169,6 +1196,7 @@
 }
 
 float LayoutText::MaxLogicalWidth() const {
+  CheckIsNotDestroyed();
   if (IntrinsicLogicalWidthsDirty())
     const_cast<LayoutText*>(this)->ComputePreferredLogicalWidths(0);
 
@@ -1176,6 +1204,7 @@
 }
 
 void LayoutText::ComputePreferredLogicalWidths(float lead_width) {
+  CheckIsNotDestroyed();
   HashSet<const SimpleFontData*> fallback_fonts;
   FloatRect glyph_bounds;
   ComputePreferredLogicalWidths(lead_width, fallback_fonts, glyph_bounds);
@@ -1265,6 +1294,7 @@
     float lead_width,
     HashSet<const SimpleFontData*>& fallback_fonts,
     FloatRect& glyph_bounds) {
+  CheckIsNotDestroyed();
   DCHECK(has_tab_ || IntrinsicLogicalWidthsDirty() ||
          !known_to_have_no_overflow_and_no_fallback_fonts_);
 
@@ -1619,6 +1649,7 @@
 }
 
 bool LayoutText::IsAllCollapsibleWhitespace() const {
+  CheckIsNotDestroyed();
   unsigned length = TextLength();
   if (Is8Bit()) {
     for (unsigned i = 0; i < length; ++i) {
@@ -1635,6 +1666,7 @@
 }
 
 bool LayoutText::ContainsOnlyWhitespace(unsigned from, unsigned len) const {
+  CheckIsNotDestroyed();
   DCHECK(text_);
   StringImpl& text = *text_.Impl();
   unsigned curr_pos;
@@ -1648,6 +1680,7 @@
 }
 
 UChar32 LayoutText::FirstCharacterAfterWhitespaceCollapsing() const {
+  CheckIsNotDestroyed();
   if (InlineTextBox* text_box = FirstTextBox()) {
     String text = text_box->GetText();
     return text.length() ? text.CharacterStartingAt(0) : 0;
@@ -1664,6 +1697,7 @@
 }
 
 UChar32 LayoutText::LastCharacterAfterWhitespaceCollapsing() const {
+  CheckIsNotDestroyed();
   if (InlineTextBox* text_box = LastTextBox()) {
     String text = text_box->GetText();
     return text.length() ? StringView(text).CodepointAt(text.length() - 1) : 0;
@@ -1680,6 +1714,7 @@
 }
 
 PhysicalOffset LayoutText::FirstLineBoxTopLeft() const {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     // TODO(kojii): Some clients call this against dirty-tree, but NG fragments
     // are not safe to read for dirty-tree. crbug.com/963103
@@ -1704,6 +1739,7 @@
 void LayoutText::LogicalStartingPointAndHeight(
     LogicalOffset& logical_starting_point,
     LayoutUnit& logical_height) const {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     NGInlineCursor cursor;
     cursor.MoveTo(*this);
@@ -1738,6 +1774,7 @@
 }
 
 bool LayoutText::CanOptimizeSetText() const {
+  CheckIsNotDestroyed();
   // If we have only one line of text and "contain: layout size" we can avoid
   // doing a layout and only paint in the SetText() operation.
   auto* parent_block_flow = DynamicTo<LayoutBlockFlow>(Parent());
@@ -1758,6 +1795,7 @@
 }
 
 void LayoutText::SetFirstTextBoxLogicalLeft(float text_width) const {
+  CheckIsNotDestroyed();
   DCHECK(FirstTextBox());
   DCHECK(ContainingBlock());
   DCHECK(StyleRef().IsLeftToRightDirection());
@@ -1793,6 +1831,7 @@
 void LayoutText::SetTextWithOffset(scoped_refptr<StringImpl> text,
                                    unsigned offset,
                                    unsigned len) {
+  CheckIsNotDestroyed();
   if (Equal(text_.Impl(), text.get()))
     return;
 
@@ -1918,6 +1957,7 @@
 }
 
 void LayoutText::TransformText() {
+  CheckIsNotDestroyed();
   if (scoped_refptr<StringImpl> text_to_transform = OriginalText())
     ForceSetText(std::move(text_to_transform));
 }
@@ -1931,12 +1971,14 @@
 }
 
 OnlyWhitespaceOrNbsp LayoutText::ContainsOnlyWhitespaceOrNbsp() const {
+  CheckIsNotDestroyed();
   return IntrinsicLogicalWidthsDirty() ? OnlyWhitespaceOrNbsp::kUnknown
                                        : static_cast<OnlyWhitespaceOrNbsp>(
                                              contains_only_whitespace_or_nbsp_);
 }
 
 UChar LayoutText::PreviousCharacter() const {
+  CheckIsNotDestroyed();
   // find previous text layoutObject if one exists
   const LayoutObject* previous_text = PreviousInPreOrder();
   for (; previous_text; previous_text = previous_text->PreviousInPreOrder()) {
@@ -1953,6 +1995,7 @@
 }
 
 void LayoutText::SetTextInternal(scoped_refptr<StringImpl> text) {
+  CheckIsNotDestroyed();
   DCHECK(text);
   text_ = String(std::move(text));
   DCHECK(text_);
@@ -1960,6 +2003,7 @@
 }
 
 void LayoutText::ApplyTextTransform() {
+  CheckIsNotDestroyed();
   if (const ComputedStyle* style = Style()) {
     style->ApplyTextTransform(&text_, PreviousCharacter());
 
@@ -1981,6 +2025,7 @@
 }
 
 void LayoutText::SecureText(UChar mask) {
+  CheckIsNotDestroyed();
   if (!text_.length())
     return;
 
@@ -2005,6 +2050,7 @@
 }
 
 void LayoutText::SetTextIfNeeded(scoped_refptr<StringImpl> text) {
+  CheckIsNotDestroyed();
   DCHECK(text);
 
   if (Equal(text_.Impl(), text.get()))
@@ -2013,12 +2059,14 @@
 }
 
 void LayoutText::ForceSetText(scoped_refptr<StringImpl> text) {
+  CheckIsNotDestroyed();
   DCHECK(text);
   SetTextInternal(std::move(text));
   TextDidChange();
 }
 
 void LayoutText::TextDidChange() {
+  CheckIsNotDestroyed();
   // If preferredLogicalWidthsDirty() of an orphan child is true,
   // LayoutObjectChildList::insertChildNode() fails to set true to owner.
   // To avoid that, we call SetNeedsLayoutAndIntrinsicWidthsRecalc() only if
@@ -2031,6 +2079,7 @@
 }
 
 void LayoutText::TextDidChangeWithoutInvalidation() {
+  CheckIsNotDestroyed();
   ApplyTextTransform();
   known_to_have_no_overflow_and_no_fallback_fonts_ = false;
 
@@ -2051,6 +2100,7 @@
 }
 
 void LayoutText::InvalidateSubtreeLayoutForFontUpdates() {
+  CheckIsNotDestroyed();
   if (RuntimeEnabledFeatures::
           CSSReducedFontLoadingLayoutInvalidationsEnabled() &&
       IsFontFallbackValid()) {
@@ -2065,6 +2115,7 @@
 }
 
 void LayoutText::DirtyOrDeleteLineBoxesIfNeeded(bool full_layout) {
+  CheckIsNotDestroyed();
   if (full_layout)
     DeleteTextBoxes();
   else if (!lines_dirty_)
@@ -2074,6 +2125,7 @@
 }
 
 void LayoutText::DirtyLineBoxes() {
+  CheckIsNotDestroyed();
   for (InlineTextBox* box : TextBoxes())
     box->DirtyLineBoxes();
   lines_dirty_ = false;
@@ -2081,16 +2133,19 @@
 }
 
 InlineTextBox* LayoutText::CreateTextBox(int start, uint16_t length) {
+  CheckIsNotDestroyed();
   return new InlineTextBox(LineLayoutItem(this), start, length);
 }
 
 InlineTextBox* LayoutText::CreateInlineTextBox(int start, uint16_t length) {
+  CheckIsNotDestroyed();
   InlineTextBox* text_box = CreateTextBox(start, length);
   MutableTextBoxes().AppendLineBox(text_box);
   return text_box;
 }
 
 void LayoutText::PositionLineBox(InlineBox* box) {
+  CheckIsNotDestroyed();
   InlineTextBox* s = ToInlineTextBox(box);
 
   // FIXME: should not be needed!!!
@@ -2113,6 +2168,7 @@
                         HashSet<const SimpleFontData*>* fallback_fonts,
                         FloatRect* glyph_bounds,
                         float expansion) const {
+  CheckIsNotDestroyed();
   if (from >= TextLength())
     return 0;
 
@@ -2131,6 +2187,7 @@
                         HashSet<const SimpleFontData*>* fallback_fonts,
                         FloatRect* glyph_bounds,
                         float expansion) const {
+  CheckIsNotDestroyed();
   DCHECK_LE(from + len, TextLength());
   if (!TextLength())
     return 0;
@@ -2177,6 +2234,7 @@
 }
 
 PhysicalRect LayoutText::PhysicalLinesBoundingBox() const {
+  CheckIsNotDestroyed();
   PhysicalRect result;
   CollectLineBoxRects(
       [&result](const PhysicalRect& r) { result.UniteIfNonZero(r); });
@@ -2187,6 +2245,7 @@
 }
 
 PhysicalRect LayoutText::PhysicalVisualOverflowRect() const {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     DCHECK(RuntimeEnabledFeatures::LayoutNGEnabled());
     if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
@@ -2242,10 +2301,12 @@
 }
 
 PhysicalRect LayoutText::LocalVisualRectIgnoringVisibility() const {
+  CheckIsNotDestroyed();
   return UnionRect(PhysicalVisualOverflowRect(), LocalSelectionVisualRect());
 }
 
 PhysicalRect LayoutText::LocalSelectionVisualRect() const {
+  CheckIsNotDestroyed();
   DCHECK(!NeedsLayout());
 
   if (!IsSelected())
@@ -2284,12 +2345,14 @@
 }
 
 const NGOffsetMapping* LayoutText::GetNGOffsetMapping() const {
+  CheckIsNotDestroyed();
   if (!RuntimeEnabledFeatures::LayoutNGEnabled())
     return nullptr;
   return NGOffsetMapping::GetFor(this);
 }
 
 Position LayoutText::PositionForCaretOffset(unsigned offset) const {
+  CheckIsNotDestroyed();
   // ::first-letter handling should be done by LayoutTextFragment override.
   DCHECK(!IsTextFragment());
   // BR handling should be done by LayoutBR override.
@@ -2313,6 +2376,7 @@
 
 base::Optional<unsigned> LayoutText::CaretOffsetForPosition(
     const Position& position) const {
+  CheckIsNotDestroyed();
   // ::first-letter handling should be done by LayoutTextFragment override.
   DCHECK(!IsTextFragment());
   // BR handling should be done by LayoutBR override.
@@ -2334,6 +2398,7 @@
 }
 
 int LayoutText::CaretMinOffset() const {
+  CheckIsNotDestroyed();
   DCHECK(!GetDocument().NeedsLayoutTreeUpdate());
 
   if (auto* mapping = GetNGOffsetMapping()) {
@@ -2358,6 +2423,7 @@
 }
 
 int LayoutText::CaretMaxOffset() const {
+  CheckIsNotDestroyed();
   DCHECK(!GetDocument().NeedsLayoutTreeUpdate());
 
   if (auto* mapping = GetNGOffsetMapping()) {
@@ -2383,6 +2449,7 @@
 }
 
 unsigned LayoutText::ResolvedTextLength() const {
+  CheckIsNotDestroyed();
   if (auto* mapping = GetNGOffsetMapping()) {
     const Position start_position = PositionForCaretOffset(0);
     const Position end_position = PositionForCaretOffset(TextLength());
@@ -2410,12 +2477,14 @@
 }
 
 bool LayoutText::HasNonCollapsedText() const {
+  CheckIsNotDestroyed();
   if (GetNGOffsetMapping())
     return ResolvedTextLength();
   return FirstTextBox();
 }
 
 bool LayoutText::ContainsCaretOffset(int text_offset) const {
+  CheckIsNotDestroyed();
   DCHECK_GE(text_offset, 0);
   if (auto* mapping = GetNGOffsetMapping()) {
     if (text_offset > static_cast<int>(TextLength()))
@@ -2480,6 +2549,7 @@
 }
 
 bool LayoutText::IsBeforeNonCollapsedCharacter(unsigned text_offset) const {
+  CheckIsNotDestroyed();
   if (auto* mapping = GetNGOffsetMapping()) {
     if (text_offset >= TextLength())
       return false;
@@ -2513,6 +2583,7 @@
 }
 
 bool LayoutText::IsAfterNonCollapsedCharacter(unsigned text_offset) const {
+  CheckIsNotDestroyed();
   if (auto* mapping = GetNGOffsetMapping()) {
     if (!text_offset)
       return false;
@@ -2549,6 +2620,7 @@
 
 void LayoutText::MomentarilyRevealLastTypedCharacter(
     unsigned last_typed_character_offset) {
+  CheckIsNotDestroyed();
   SecureTextTimer* secure_text_timer = GetSecureTextTimers().at(this);
   if (!secure_text_timer) {
     secure_text_timer = new SecureTextTimer(this);
@@ -2558,6 +2630,7 @@
 }
 
 scoped_refptr<AbstractInlineTextBox> LayoutText::FirstAbstractInlineTextBox() {
+  CheckIsNotDestroyed();
   if (IsInLayoutNGInlineFormattingContext()) {
     NGInlineCursor cursor;
     cursor.MoveTo(*this);
@@ -2568,6 +2641,7 @@
 }
 
 void LayoutText::InvalidatePaint(const PaintInvalidatorContext& context) const {
+  CheckIsNotDestroyed();
   if (ShouldInvalidateSelection() && !IsSelected())
     GetSelectionDisplayItemClientMap().erase(this);
   LayoutObject::InvalidatePaint(context);
@@ -2575,6 +2649,7 @@
 
 void LayoutText::InvalidateDisplayItemClients(
     PaintInvalidationReason reason) const {
+  CheckIsNotDestroyed();
   ObjectPaintInvalidator invalidator(*this);
   invalidator.InvalidateDisplayItemClient(*this, reason);
 
@@ -2607,6 +2682,7 @@
 }
 
 const DisplayItemClient* LayoutText::GetSelectionDisplayItemClient() const {
+  CheckIsNotDestroyed();
   if (!IsSelected())
     return nullptr;
   if (IsInLayoutNGInlineFormattingContext() &&
@@ -2621,10 +2697,12 @@
 }
 
 PhysicalRect LayoutText::DebugRect() const {
+  CheckIsNotDestroyed();
   return PhysicalRect(EnclosingIntRect(PhysicalLinesBoundingBox()));
 }
 
 DOMNodeId LayoutText::EnsureNodeId() {
+  CheckIsNotDestroyed();
   if (node_id_ == kInvalidDOMNodeId) {
     if (auto* content_capture_manager = GetContentCaptureManager()) {
       if (auto* node = GetNode()) {
@@ -2637,6 +2715,7 @@
 }
 
 ContentCaptureManager* LayoutText::GetContentCaptureManager() {
+  CheckIsNotDestroyed();
   if (auto* node = GetNode()) {
     if (auto* frame = node->GetDocument().GetFrame()) {
       return frame->LocalFrameRoot().GetContentCaptureManager();
@@ -2646,6 +2725,7 @@
 }
 
 void LayoutText::SetInlineItems(NGInlineItem* begin, NGInlineItem* end) {
+  CheckIsNotDestroyed();
 #if DCHECK_IS_ON()
   for (NGInlineItem* item = begin; item != end; ++item) {
     DCHECK_EQ(item->GetLayoutObject(), this);
@@ -2659,6 +2739,7 @@
 }
 
 void LayoutText::ClearInlineItems() {
+  CheckIsNotDestroyed();
   has_bidi_control_items_ = false;
   valid_ng_items_ = false;
   if (base::span<NGInlineItem>* items = GetNGInlineItems())
@@ -2666,6 +2747,7 @@
 }
 
 const base::span<NGInlineItem>& LayoutText::InlineItems() const {
+  CheckIsNotDestroyed();
   DCHECK(valid_ng_items_);
   DCHECK(GetNGInlineItems());
   DCHECK(!GetNGInlineItems()->empty());
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h
index 0f5089d74..e5a8ab7 100644
--- a/third_party/blink/renderer/core/layout/layout_text.h
+++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -86,9 +86,15 @@
                                           scoped_refptr<const ComputedStyle>,
                                           LegacyLayout);
 
-  const char* GetName() const override { return "LayoutText"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutText";
+  }
 
-  bool IsTextFragment() const { return is_text_fragment_; }
+  bool IsTextFragment() const {
+    CheckIsNotDestroyed();
+    return is_text_fragment_;
+  }
   virtual bool IsWordBreak() const;
 
   virtual scoped_refptr<StringImpl> OriginalText() const;
@@ -104,12 +110,21 @@
   void ClearFirstInlineFragmentItemIndex() final;
   void SetFirstInlineFragmentItemIndex(wtf_size_t) final;
 
-  const String& GetText() const { return text_; }
-  virtual unsigned TextStartOffset() const { return 0; }
+  const String& GetText() const {
+    CheckIsNotDestroyed();
+    return text_;
+  }
+  virtual unsigned TextStartOffset() const {
+    CheckIsNotDestroyed();
+    return 0;
+  }
   String PlainText() const;
 
   // Returns first letter part of |LayoutTextFragment|.
-  virtual LayoutText* GetFirstLetterPart() const { return nullptr; }
+  virtual LayoutText* GetFirstLetterPart() const {
+    CheckIsNotDestroyed();
+    return nullptr;
+  }
 
   InlineTextBox* CreateInlineTextBox(int start, uint16_t length);
   void DirtyOrDeleteLineBoxesIfNeeded(bool full_layout);
@@ -128,15 +143,31 @@
 
   PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
 
-  bool Is8Bit() const { return text_.Is8Bit(); }
-  const LChar* Characters8() const { return text_.Impl()->Characters8(); }
-  const UChar* Characters16() const { return text_.Impl()->Characters16(); }
-  bool HasEmptyText() const { return text_.IsEmpty(); }
+  bool Is8Bit() const {
+    CheckIsNotDestroyed();
+    return text_.Is8Bit();
+  }
+  const LChar* Characters8() const {
+    CheckIsNotDestroyed();
+    return text_.Impl()->Characters8();
+  }
+  const UChar* Characters16() const {
+    CheckIsNotDestroyed();
+    return text_.Impl()->Characters16();
+  }
+  bool HasEmptyText() const {
+    CheckIsNotDestroyed();
+    return text_.IsEmpty();
+  }
   UChar CharacterAt(unsigned) const;
   UChar UncheckedCharacterAt(unsigned) const;
-  UChar operator[](unsigned i) const { return UncheckedCharacterAt(i); }
+  UChar operator[](unsigned i) const {
+    CheckIsNotDestroyed();
+    return UncheckedCharacterAt(i);
+  }
   UChar32 CodepointAt(unsigned) const;
   unsigned TextLength() const {
+    CheckIsNotDestroyed();
     return text_.length();
   }  // non virtual implementation of length()
   bool ContainsOnlyWhitespace(unsigned from, unsigned len) const;
@@ -209,6 +240,7 @@
   // TextBoxes() and FirstInlineFragment() are mutually exclusive,
   // depends on IsInLayoutNGInlineFormattingContext().
   const InlineTextBoxList& TextBoxes() const {
+    CheckIsNotDestroyed();
     return IsInLayoutNGInlineFormattingContext() ? InlineTextBoxList::Empty()
                                                  : text_boxes_;
   }
@@ -216,12 +248,21 @@
   // Returns first |InlineTextBox| produces for associated |Node|.
   // Note: When |this| is remaining part of ::first-letter, this function
   // returns first-letter part of |InlineTextBox| instead of remaining part.
-  InlineTextBox* FirstTextBox() const { return TextBoxes().First(); }
-  InlineTextBox* LastTextBox() const { return TextBoxes().Last(); }
+  InlineTextBox* FirstTextBox() const {
+    CheckIsNotDestroyed();
+    return TextBoxes().First();
+  }
+  InlineTextBox* LastTextBox() const {
+    CheckIsNotDestroyed();
+    return TextBoxes().Last();
+  }
 
   // TODO(layoutng) Legacy-only implementation of HasTextBoxes.
   // All callers should call HasTextBoxes instead, and take NG into account.
-  bool HasLegacyTextBoxes() const { return FirstTextBox(); }
+  bool HasLegacyTextBoxes() const {
+    CheckIsNotDestroyed();
+    return FirstTextBox();
+  }
 
   // Compute the rect and offset of text boxes for this LayoutText.
   struct TextBoxInfo {
@@ -261,9 +302,13 @@
   // True if any character remains after CSS white-space collapsing.
   bool HasNonCollapsedText() const;
 
-  bool ContainsReversedText() const { return contains_reversed_text_; }
+  bool ContainsReversedText() const {
+    CheckIsNotDestroyed();
+    return contains_reversed_text_;
+  }
 
   bool IsSecure() const {
+    CheckIsNotDestroyed();
     return StyleRef().TextSecurity() != ETextSecurity::kNone;
   }
   void MomentarilyRevealLastTypedCharacter(
@@ -276,16 +321,21 @@
   scoped_refptr<AbstractInlineTextBox> FirstAbstractInlineTextBox();
 
   bool HasAbstractInlineTextBox() const {
+    CheckIsNotDestroyed();
     return has_abstract_inline_text_box_;
   }
 
-  void SetHasAbstractInlineTextBox() { has_abstract_inline_text_box_ = true; }
+  void SetHasAbstractInlineTextBox() {
+    CheckIsNotDestroyed();
+    has_abstract_inline_text_box_ = true;
+  }
 
   float HyphenWidth(const Font&, TextDirection);
 
   PhysicalRect DebugRect() const override;
 
   void AutosizingMultiplerChanged() {
+    CheckIsNotDestroyed();
     known_to_have_no_overflow_and_no_fallback_fonts_ = false;
 
     // The font size is changing, so we need to make sure to rebuild everything.
@@ -309,24 +359,46 @@
                                        unsigned* start,
                                        unsigned* end) const;
   DOMNodeId EnsureNodeId();
-  bool HasNodeId() const { return node_id_ != kInvalidDOMNodeId; }
+  bool HasNodeId() const {
+    CheckIsNotDestroyed();
+    return node_id_ != kInvalidDOMNodeId;
+  }
 
   void SetInlineItems(NGInlineItem* begin, NGInlineItem* end);
   void ClearInlineItems();
-  bool HasValidInlineItems() const { return valid_ng_items_; }
+  bool HasValidInlineItems() const {
+    CheckIsNotDestroyed();
+    return valid_ng_items_;
+  }
   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() { valid_ng_items_ = false; }
+  void InvalidateInlineItems() {
+    CheckIsNotDestroyed();
+    valid_ng_items_ = false;
+  }
 
-  bool HasBidiControlInlineItems() const { return has_bidi_control_items_; }
-  void SetHasBidiControlInlineItems() { has_bidi_control_items_ = true; }
-  void ClearHasBidiControlInlineItems() { has_bidi_control_items_ = false; }
+  bool HasBidiControlInlineItems() const {
+    CheckIsNotDestroyed();
+    return has_bidi_control_items_;
+  }
+  void SetHasBidiControlInlineItems() {
+    CheckIsNotDestroyed();
+    has_bidi_control_items_ = true;
+  }
+  void ClearHasBidiControlInlineItems() {
+    CheckIsNotDestroyed();
+    has_bidi_control_items_ = false;
+  }
 
   virtual const base::span<NGInlineItem>* GetNGInlineItems() const {
+    CheckIsNotDestroyed();
     return nullptr;
   }
-  virtual base::span<NGInlineItem>* GetNGInlineItems() { return nullptr; }
+  virtual base::span<NGInlineItem>* GetNGInlineItems() {
+    CheckIsNotDestroyed();
+    return nullptr;
+  }
 
   void InvalidateSubtreeLayoutForFontUpdates() override;
 
@@ -340,10 +412,12 @@
   // For LayoutShiftTracker. Saves the value of LogicalStartingPoint() value
   // during the previous paint invalidation.
   LogicalOffset PreviousLogicalStartingPoint() const {
+    CheckIsNotDestroyed();
     return previous_logical_starting_point_;
   }
   // This is const because LayoutObjects are const for paint invalidation.
   void SetPreviousLogicalStartingPoint(const LogicalOffset& point) const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(GetDocument().Lifecycle().GetState(),
               DocumentLifecycle::kInPrePaint);
     previous_logical_starting_point_ = point;
@@ -355,7 +429,9 @@
  protected:
   void WillBeDestroyed() override;
 
-  void StyleWillChange(StyleDifference, const ComputedStyle&) final {}
+  void StyleWillChange(StyleDifference, const ComputedStyle&) final {
+    CheckIsNotDestroyed();
+  }
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
 
   void InLayoutNGInlineFormattingContextWillChange(bool) final;
@@ -368,7 +444,10 @@
   void InvalidatePaint(const PaintInvalidatorContext&) const final;
   void InvalidateDisplayItemClients(PaintInvalidationReason) const final;
 
-  bool CanBeSelectionLeafInternal() const final { return true; }
+  bool CanBeSelectionLeafInternal() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
  private:
   InlineTextBoxList& MutableTextBoxes();
@@ -390,15 +469,25 @@
   // Make length() private so that callers that have a LayoutText*
   // will use the more efficient textLength() instead, while
   // callers with a LayoutObject* can continue to use length().
-  unsigned length() const final { return TextLength(); }
+  unsigned length() const final {
+    CheckIsNotDestroyed();
+    return TextLength();
+  }
 
   // See the class comment as to why we shouldn't call this function directly.
-  void Paint(const PaintInfo&) const final { NOTREACHED(); }
-  void UpdateLayout() final { NOTREACHED(); }
+  void Paint(const PaintInfo&) const final {
+    CheckIsNotDestroyed();
+    NOTREACHED();
+  }
+  void UpdateLayout() final {
+    CheckIsNotDestroyed();
+    NOTREACHED();
+  }
   bool NodeAtPoint(HitTestResult&,
                    const HitTestLocation&,
                    const PhysicalOffset&,
                    HitTestAction) final {
+    CheckIsNotDestroyed();
     NOTREACHED();
     return false;
   }
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 60a7197..63a42de6 100644
--- a/third_party/blink/renderer/core/layout/layout_text_combine.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_combine.cc
@@ -36,6 +36,7 @@
 
 void LayoutTextCombine::StyleDidChange(StyleDifference diff,
                                        const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutText::StyleDidChange(diff, old_style);
   UpdateIsCombined();
   if (!IsCombined())
@@ -47,6 +48,7 @@
 }
 
 void LayoutTextCombine::TextDidChange() {
+  CheckIsNotDestroyed();
   LayoutText::TextDidChange();
 
   bool was_combined = IsCombined();
@@ -80,6 +82,7 @@
                                HashSet<const SimpleFontData*>* fallback_fonts,
                                FloatRect* glyph_bounds,
                                float) const {
+  CheckIsNotDestroyed();
   if (!length)
     return 0;
 
@@ -107,6 +110,7 @@
     GraphicsContext& context,
     const PhysicalRect& box_rect,
     bool clip) const {
+  CheckIsNotDestroyed();
   DCHECK(is_combined_);
 
   // No transform needed if we don't have a font.
@@ -150,6 +154,7 @@
 }
 
 void LayoutTextCombine::UpdateIsCombined() {
+  CheckIsNotDestroyed();
   // CSS3 spec says text-combine works only in vertical writing mode.
   is_combined_ = !StyleRef().IsHorizontalWritingMode()
                  // Nothing to combine.
@@ -157,6 +162,7 @@
 }
 
 void LayoutTextCombine::UpdateFontStyleForCombinedText() {
+  CheckIsNotDestroyed();
   DCHECK(is_combined_);
 
   scoped_refptr<ComputedStyle> style = ComputedStyle::Clone(StyleRef());
diff --git a/third_party/blink/renderer/core/layout/layout_text_combine.h b/third_party/blink/renderer/core/layout/layout_text_combine.h
index 7fcd298..b1e2f16 100644
--- a/third_party/blink/renderer/core/layout/layout_text_combine.h
+++ b/third_party/blink/renderer/core/layout/layout_text_combine.h
@@ -35,20 +35,33 @@
  public:
   LayoutTextCombine(Node*, scoped_refptr<StringImpl>);
 
-  bool IsCombined() const { return is_combined_; }
+  bool IsCombined() const {
+    CheckIsNotDestroyed();
+    return is_combined_;
+  }
   float CombinedTextWidth(const Font& font) const {
+    CheckIsNotDestroyed();
     return font.GetFontDescription().ComputedSize();
   }
-  const Font& OriginalFont() const { return Parent()->StyleRef().GetFont(); }
+  const Font& OriginalFont() const {
+    CheckIsNotDestroyed();
+    return Parent()->StyleRef().GetFont();
+  }
   void TransformToInlineCoordinates(GraphicsContext&,
                                     const PhysicalRect& box_rect,
                                     bool clip = false) const;
   LayoutUnit InlineWidthForLayout() const;
 
-  const char* GetName() const override { return "LayoutTextCombine"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutTextCombine";
+  }
 
  private:
-  bool IsCombineText() const override { return true; }
+  bool IsCombineText() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
   float Width(unsigned from,
               unsigned length,
               const Font&,
diff --git a/third_party/blink/renderer/core/layout/layout_text_control.cc b/third_party/blink/renderer/core/layout/layout_text_control.cc
index 040271aa..059a626 100644
--- a/third_party/blink/renderer/core/layout/layout_text_control.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_control.cc
@@ -40,15 +40,18 @@
 LayoutTextControl::~LayoutTextControl() = default;
 
 TextControlElement* LayoutTextControl::GetTextControlElement() const {
+  CheckIsNotDestroyed();
   return ToTextControl(GetNode());
 }
 
 TextControlInnerEditorElement* LayoutTextControl::InnerEditorElement() const {
+  CheckIsNotDestroyed();
   return GetTextControlElement()->InnerEditorElement();
 }
 
 void LayoutTextControl::StyleDidChange(StyleDifference diff,
                                        const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::StyleDidChange(diff, old_style);
   TextControlInnerEditorElement* inner_editor = InnerEditorElement();
   if (!inner_editor)
@@ -79,6 +82,7 @@
 }
 
 int LayoutTextControl::ScrollbarThickness() const {
+  CheckIsNotDestroyed();
   return GetDocument().GetPage()->GetScrollbarTheme().ScrollbarThickness(
       GetDocument().GetPage()->GetChromeClient().WindowToViewportScalar(
           GetFrame(), 1.0f));
@@ -88,6 +92,7 @@
     LayoutUnit logical_height,
     LayoutUnit logical_top,
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   HTMLElement* inner_editor = InnerEditorElement();
   DCHECK(inner_editor);
   if (LayoutBox* inner_editor_box = inner_editor->GetLayoutBox()) {
@@ -120,6 +125,7 @@
     HitTestResult& result,
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& accumulated_offset) {
+  CheckIsNotDestroyed();
   HTMLElement* inner_editor = InnerEditorElement();
   if (!inner_editor->GetLayoutObject())
     return;
@@ -203,6 +209,7 @@
 }
 
 float LayoutTextControl::GetAvgCharWidth(const AtomicString& family) const {
+  CheckIsNotDestroyed();
   const Font& font = StyleRef().GetFont();
 
   const SimpleFontData* primary_font = font.PrimaryFont();
@@ -217,6 +224,7 @@
 }
 
 MinMaxSizes LayoutTextControl::ComputeIntrinsicLogicalWidths() const {
+  CheckIsNotDestroyed();
   MinMaxSizes sizes;
   sizes += BorderAndPaddingLogicalWidth();
 
@@ -240,12 +248,14 @@
 void LayoutTextControl::AddOutlineRects(Vector<PhysicalRect>& rects,
                                         const PhysicalOffset& additional_offset,
                                         NGOutlineType) const {
+  CheckIsNotDestroyed();
   rects.emplace_back(additional_offset, Size());
 }
 
 LayoutObject* LayoutTextControl::LayoutSpecialExcludedChild(
     bool relayout_children,
     SubtreeLayoutScope& layout_scope) {
+  CheckIsNotDestroyed();
   HTMLElement* placeholder = ToTextControl(GetNode())->PlaceholderElement();
   LayoutObject* placeholder_layout_object =
       placeholder ? placeholder->GetLayoutObject() : nullptr;
@@ -257,6 +267,7 @@
 }
 
 LayoutUnit LayoutTextControl::FirstLineBoxBaseline() const {
+  CheckIsNotDestroyed();
   if (ShouldApplyLayoutContainment())
     return LayoutUnit(-1);
 
diff --git a/third_party/blink/renderer/core/layout/layout_text_control.h b/third_party/blink/renderer/core/layout/layout_text_control.h
index b3298fc3..f91d803 100644
--- a/third_party/blink/renderer/core/layout/layout_text_control.h
+++ b/third_party/blink/renderer/core/layout/layout_text_control.h
@@ -37,9 +37,13 @@
   ~LayoutTextControl() override;
 
   TextControlElement* GetTextControlElement() const;
-  const char* GetName() const override { return "LayoutTextControl"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutTextControl";
+  }
 
   bool CreatesNewFormattingContext() const final {
+    CheckIsNotDestroyed();
     // INPUT and other replaced elements rendered by Blink itself should be
     // completely contained.
     return true;
@@ -77,18 +81,24 @@
   LayoutUnit FirstLineBoxBaseline() const override;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectTextControl || LayoutBlockFlow::IsOfType(type);
   }
 
  private:
   MinMaxSizes ComputeIntrinsicLogicalWidths() const final;
-  void RemoveLeftoverAnonymousBlock(LayoutBlock*) final {}
+  void RemoveLeftoverAnonymousBlock(LayoutBlock*) final {
+    CheckIsNotDestroyed();
+  }
 
   void AddOutlineRects(Vector<PhysicalRect>&,
                        const PhysicalOffset& additional_offset,
                        NGOutlineType) const final;
 
-  bool CanBeProgramaticallyScrolled() const final { return true; }
+  bool CanBeProgramaticallyScrolled() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc b/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc
index c972672..74f9794 100644
--- a/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc
@@ -41,6 +41,7 @@
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& accumulated_offset,
     HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   if (!LayoutTextControl::NodeAtPoint(result, hit_test_location,
                                       accumulated_offset, hit_test_action))
     return false;
@@ -58,6 +59,7 @@
 
 LayoutUnit LayoutTextControlMultiLine::PreferredContentLogicalWidth(
     float char_width) const {
+  CheckIsNotDestroyed();
   int factor = To<HTMLTextAreaElement>(GetNode())->cols();
   return static_cast<LayoutUnit>(ceilf(char_width * factor)) +
          ScrollbarThickness();
@@ -66,6 +68,7 @@
 LayoutUnit LayoutTextControlMultiLine::ComputeControlLogicalHeight(
     LayoutUnit line_height,
     LayoutUnit non_content_height) const {
+  CheckIsNotDestroyed();
   return line_height * To<HTMLTextAreaElement>(GetNode())->rows() +
          non_content_height;
 }
@@ -75,6 +78,7 @@
     bool first_line,
     LineDirectionMode direction,
     LinePositionMode line_position_mode) const {
+  CheckIsNotDestroyed();
   return LayoutBox::BaselinePosition(baseline_type, first_line, direction,
                                      line_position_mode);
 }
@@ -82,6 +86,7 @@
 LayoutObject* LayoutTextControlMultiLine::LayoutSpecialExcludedChild(
     bool relayout_children,
     SubtreeLayoutScope& layout_scope) {
+  CheckIsNotDestroyed();
   LayoutObject* placeholder_layout_object =
       LayoutTextControl::LayoutSpecialExcludedChild(relayout_children,
                                                     layout_scope);
@@ -97,6 +102,7 @@
 }
 
 LayoutUnit LayoutTextControlMultiLine::ScrollWidth() const {
+  CheckIsNotDestroyed();
   // If in preview state, fake the scroll width to prevent that any information
   // about the suggested content can be derived from the size.
   if (!GetTextControlElement()->SuggestedValue().IsEmpty())
@@ -105,6 +111,7 @@
 }
 
 LayoutUnit LayoutTextControlMultiLine::ScrollHeight() const {
+  CheckIsNotDestroyed();
   // If in preview state, fake the scroll height to prevent that any information
   // about the suggested content can be derived from the size.
   if (!GetTextControlElement()->SuggestedValue().IsEmpty())
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h b/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h
index 21111aa..be059db 100644
--- a/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h
+++ b/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h
@@ -36,6 +36,7 @@
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectTextArea || LayoutTextControl::IsOfType(type);
   }
 
@@ -56,6 +57,7 @@
       LineDirectionMode,
       LinePositionMode = kPositionOnContainingLine) const override;
   LayoutUnit InlineBlockBaseline(LineDirectionMode) const override {
+    CheckIsNotDestroyed();
     return LayoutUnit(-1);
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc b/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
index 11aee944..55bd72d 100644
--- a/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
@@ -47,26 +47,31 @@
 LayoutTextControlSingleLine::~LayoutTextControlSingleLine() = default;
 
 inline Element* LayoutTextControlSingleLine::ContainerElement() const {
+  CheckIsNotDestroyed();
   return InputElement()->UserAgentShadowRoot()->getElementById(
       shadow_element_names::kIdTextFieldContainer);
 }
 
 inline Element* LayoutTextControlSingleLine::EditingViewPortElement() const {
+  CheckIsNotDestroyed();
   return InputElement()->UserAgentShadowRoot()->getElementById(
       shadow_element_names::kIdEditingViewPort);
 }
 
 inline HTMLElement* LayoutTextControlSingleLine::InnerSpinButtonElement()
     const {
+  CheckIsNotDestroyed();
   return To<HTMLElement>(InputElement()->UserAgentShadowRoot()->getElementById(
       shadow_element_names::kIdSpinButton));
 }
 
 void LayoutTextControlSingleLine::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   TextControlSingleLinePainter(*this).Paint(paint_info);
 }
 
 void LayoutTextControlSingleLine::UpdateLayout() {
+  CheckIsNotDestroyed();
   LayoutAnalyzer::Scope analyzer(*this);
 
   LayoutBlockFlow::UpdateBlockLayout(true);
@@ -141,6 +146,7 @@
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& accumulated_offset,
     HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   if (!LayoutTextControl::NodeAtPoint(result, hit_test_location,
                                       accumulated_offset, hit_test_action))
     return false;
@@ -174,6 +180,7 @@
 }
 
 void LayoutTextControlSingleLine::CapsLockStateMayHaveChanged() {
+  CheckIsNotDestroyed();
   if (!GetNode())
     return;
 
@@ -199,6 +206,7 @@
 
 LayoutUnit LayoutTextControlSingleLine::PreferredContentLogicalWidth(
     float char_width) const {
+  CheckIsNotDestroyed();
   int factor;
   bool includes_decoration =
       InputElement()->SizeShouldIncludeDecoration(factor);
@@ -235,10 +243,12 @@
 LayoutUnit LayoutTextControlSingleLine::ComputeControlLogicalHeight(
     LayoutUnit line_height,
     LayoutUnit non_content_height) const {
+  CheckIsNotDestroyed();
   return line_height + non_content_height;
 }
 
 LayoutUnit LayoutTextControlSingleLine::ScrollWidth() const {
+  CheckIsNotDestroyed();
   // If in preview state, fake the scroll width to prevent that any information
   // about the suggested content can be derived from the size.
   if (!GetTextControlElement()->SuggestedValue().IsEmpty())
@@ -256,6 +266,7 @@
 }
 
 LayoutUnit LayoutTextControlSingleLine::ScrollHeight() const {
+  CheckIsNotDestroyed();
   // If in preview state, fake the scroll height to prevent that any information
   // about the suggested content can be derived from the size.
   if (!GetTextControlElement()->SuggestedValue().IsEmpty())
@@ -273,11 +284,12 @@
 }
 
 HTMLInputElement* LayoutTextControlSingleLine::InputElement() const {
+  CheckIsNotDestroyed();
   return To<HTMLInputElement>(GetNode());
 }
 
-void LayoutTextControlSingleLine::ComputeVisualOverflow(
-    bool recompute_floats) {
+void LayoutTextControlSingleLine::ComputeVisualOverflow(bool recompute_floats) {
+  CheckIsNotDestroyed();
   LayoutRect previous_visual_overflow_rect = VisualOverflowRect();
   ClearVisualOverflow();
   AddVisualOverflowFromChildren();
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_single_line.h b/third_party/blink/renderer/core/layout/layout_text_control_single_line.h
index 7c0a7f1..b40e2c9 100644
--- a/third_party/blink/renderer/core/layout/layout_text_control_single_line.h
+++ b/third_party/blink/renderer/core/layout/layout_text_control_single_line.h
@@ -44,6 +44,7 @@
 
   void CapsLockStateMayHaveChanged();
   bool ShouldDrawCapsLockIndicator() const {
+    CheckIsNotDestroyed();
     return should_draw_caps_lock_indicator_;
   }
 
@@ -54,6 +55,7 @@
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectTextField || LayoutTextControl::IsOfType(type);
   }
 
@@ -80,9 +82,12 @@
   // If the INPUT content height is smaller than the font height, the
   // inner-editor element overflows the INPUT box intentionally, however it
   // shouldn't affect outside of the INPUT box.  So we ignore child overflow.
-  void AddLayoutOverflowFromChildren() final {}
+  void AddLayoutOverflowFromChildren() final { CheckIsNotDestroyed(); }
 
-  bool AllowsNonVisibleOverflow() const override { return false; }
+  bool AllowsNonVisibleOverflow() const override {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   HTMLElement* InnerSpinButtonElement() const;
 
@@ -100,15 +105,24 @@
 
 class LayoutTextControlInnerEditor : public LayoutBlockFlow {
  public:
-  LayoutTextControlInnerEditor(Element* element) : LayoutBlockFlow(element) {}
+  LayoutTextControlInnerEditor(Element* element) : LayoutBlockFlow(element) {
+    CheckIsNotDestroyed();
+  }
 
  private:
   bool IsIntrinsicallyScrollable(
       ScrollbarOrientation orientation) const override {
+    CheckIsNotDestroyed();
     return orientation == kHorizontalScrollbar;
   }
-  bool ScrollsOverflowX() const override { return IsScrollContainer(); }
-  bool ScrollsOverflowY() const override { return false; }
+  bool ScrollsOverflowX() const override {
+    CheckIsNotDestroyed();
+    return IsScrollContainer();
+  }
+  bool ScrollsOverflowY() const override {
+    CheckIsNotDestroyed();
+    return false;
+  }
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_text_fragment.cc b/third_party/blink/renderer/core/layout/layout_text_fragment.cc
index a3a975f0..2c20041c 100644
--- a/third_party/blink/renderer/core/layout/layout_text_fragment.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_fragment.cc
@@ -81,6 +81,7 @@
 }
 
 void LayoutTextFragment::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   if (is_remaining_text_layout_object_ && first_letter_pseudo_element_)
     first_letter_pseudo_element_->ClearRemainingTextLayoutObject();
   first_letter_pseudo_element_ = nullptr;
@@ -88,16 +89,19 @@
 }
 
 scoped_refptr<StringImpl> LayoutTextFragment::CompleteText() const {
+  CheckIsNotDestroyed();
   Text* text = AssociatedTextNode();
   return text ? text->DataImpl() : ContentString();
 }
 
 void LayoutTextFragment::SetContentString(StringImpl* str) {
+  CheckIsNotDestroyed();
   content_string_ = str;
   SetTextIfNeeded(str);
 }
 
 scoped_refptr<StringImpl> LayoutTextFragment::OriginalText() const {
+  CheckIsNotDestroyed();
   scoped_refptr<StringImpl> result = CompleteText();
   if (!result)
     return nullptr;
@@ -105,6 +109,7 @@
 }
 
 void LayoutTextFragment::TextDidChange() {
+  CheckIsNotDestroyed();
   LayoutText::TextDidChange();
 
   start_ = 0;
@@ -124,6 +129,7 @@
 void LayoutTextFragment::SetTextFragment(scoped_refptr<StringImpl> text,
                                          unsigned start,
                                          unsigned length) {
+  CheckIsNotDestroyed();
   // Note, we have to call |LayoutText::TextDidChange()| here because, if we
   // use our version we will, potentially, screw up the first-letter settings
   // where we only use portions of the string.
@@ -137,6 +143,7 @@
 }
 
 void LayoutTextFragment::TransformText() {
+  CheckIsNotDestroyed();
   // Note, we have to call LayoutText::TextDidChange()| here because, if we use
   // our version we will, potentially, screw up the first-letter settings where
   // we only use portions of the string.
@@ -147,6 +154,7 @@
 }
 
 UChar LayoutTextFragment::PreviousCharacter() const {
+  CheckIsNotDestroyed();
   if (Start()) {
     StringImpl* original = CompleteText().get();
     if (original && Start() <= original->length())
@@ -159,6 +167,7 @@
 // If this is the layoutObject for a first-letter pseudoNode then we have to
 // look at the node for the remaining text to find our content.
 Text* LayoutTextFragment::AssociatedTextNode() const {
+  CheckIsNotDestroyed();
   Node* node = GetFirstLetterPseudoElement();
   if (is_remaining_text_layout_object_ || !node) {
     // If we don't have a node, then we aren't part of a first-letter pseudo
@@ -182,6 +191,7 @@
 }
 
 LayoutText* LayoutTextFragment::GetFirstLetterPart() const {
+  CheckIsNotDestroyed();
   if (!is_remaining_text_layout_object_)
     return nullptr;
   // Node: We assume first letter pseudo element has only one child and it
@@ -197,6 +207,7 @@
 void LayoutTextFragment::UpdateHitTestResult(
     HitTestResult& result,
     const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   if (result.InnerNode())
     return;
 
@@ -210,6 +221,7 @@
 }
 
 Position LayoutTextFragment::PositionForCaretOffset(unsigned offset) const {
+  CheckIsNotDestroyed();
   // TODO(layout-dev): Make the following DCHECK always enabled after we
   // properly support 'text-transform' changing text length.
 #if DCHECK_IS_ON()
@@ -226,6 +238,7 @@
 
 base::Optional<unsigned> LayoutTextFragment::CaretOffsetForPosition(
     const Position& position) const {
+  CheckIsNotDestroyed();
   if (position.IsNull() || position.AnchorNode() != AssociatedTextNode())
     return base::nullopt;
   unsigned dom_offset;
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 9dfed8a..dd5c143 100644
--- a/third_party/blink/renderer/core/layout/layout_text_fragment.h
+++ b/third_party/blink/renderer/core/layout/layout_text_fragment.h
@@ -59,13 +59,25 @@
   base::Optional<unsigned> CaretOffsetForPosition(
       const Position&) const override;
 
-  unsigned Start() const { return start_; }
-  unsigned FragmentLength() const { return fragment_length_; }
+  unsigned Start() const {
+    CheckIsNotDestroyed();
+    return start_;
+  }
+  unsigned FragmentLength() const {
+    CheckIsNotDestroyed();
+    return fragment_length_;
+  }
 
-  unsigned TextStartOffset() const override { return Start(); }
+  unsigned TextStartOffset() const override {
+    CheckIsNotDestroyed();
+    return Start();
+  }
 
   void SetContentString(StringImpl*);
-  StringImpl* ContentString() const { return content_string_.get(); }
+  StringImpl* ContentString() const {
+    CheckIsNotDestroyed();
+    return content_string_.get();
+  }
   // The complete text is all of the text in the associated DOM text node.
   scoped_refptr<StringImpl> CompleteText() const;
   // The fragment text is the text which will be used by this
@@ -80,19 +92,26 @@
 
   void TransformText() override;
 
-  const char* GetName() const override { return "LayoutTextFragment"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutTextFragment";
+  }
 
   void SetFirstLetterPseudoElement(FirstLetterPseudoElement* element) {
+    CheckIsNotDestroyed();
     first_letter_pseudo_element_ = element;
   }
   FirstLetterPseudoElement* GetFirstLetterPseudoElement() const {
+    CheckIsNotDestroyed();
     return first_letter_pseudo_element_;
   }
 
   void SetIsRemainingTextLayoutObject(bool is_remaining_text) {
+    CheckIsNotDestroyed();
     is_remaining_text_layout_object_ = is_remaining_text;
   }
   bool IsRemainingTextLayoutObject() const {
+    CheckIsNotDestroyed();
     return is_remaining_text_layout_object_;
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_video.cc b/third_party/blink/renderer/core/layout/layout_video.cc
index ee2d9d3f..cc78cb6 100644
--- a/third_party/blink/renderer/core/layout/layout_video.cc
+++ b/third_party/blink/renderer/core/layout/layout_video.cc
@@ -49,12 +49,14 @@
 }
 
 void LayoutVideo::IntrinsicSizeChanged() {
+  CheckIsNotDestroyed();
   if (VideoElement()->IsShowPosterFlagSet())
     LayoutMedia::IntrinsicSizeChanged();
   UpdateIntrinsicSize(/* is_in_layout */ false);
 }
 
 void LayoutVideo::UpdateIntrinsicSize(bool is_in_layout) {
+  CheckIsNotDestroyed();
   LayoutSize size = CalculateIntrinsicSize(StyleRef().EffectiveZoom());
 
   // Never set the element size to zero when in a media document.
@@ -74,6 +76,7 @@
 }
 
 LayoutSize LayoutVideo::CalculateIntrinsicSize(float scale) {
+  CheckIsNotDestroyed();
   HTMLVideoElement* video = VideoElement();
   DCHECK(video);
 
@@ -118,6 +121,7 @@
 
 void LayoutVideo::ImageChanged(WrappedImagePtr new_image,
                                CanDeferInvalidation defer) {
+  CheckIsNotDestroyed();
   LayoutMedia::ImageChanged(new_image, defer);
 
   // Cache the image intrinsic size so we can continue to use it to draw the
@@ -134,6 +138,7 @@
 }
 
 LayoutVideo::DisplayMode LayoutVideo::GetDisplayMode() const {
+  CheckIsNotDestroyed();
   if (!VideoElement()->IsShowPosterFlagSet() ||
       VideoElement()->PosterImageURL().IsEmpty()) {
     return kVideo;
@@ -144,19 +149,23 @@
 
 void LayoutVideo::PaintReplaced(const PaintInfo& paint_info,
                                 const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   VideoPainter(*this).PaintReplaced(paint_info, paint_offset);
 }
 
 void LayoutVideo::UpdateLayout() {
+  CheckIsNotDestroyed();
   UpdatePlayer(/* is_in_layout */ true);
   LayoutMedia::UpdateLayout();
 }
 
 HTMLVideoElement* LayoutVideo::VideoElement() const {
+  CheckIsNotDestroyed();
   return To<HTMLVideoElement>(GetNode());
 }
 
 void LayoutVideo::UpdateFromElement() {
+  CheckIsNotDestroyed();
   LayoutMedia::UpdateFromElement();
   UpdatePlayer(/* is_in_layout */ false);
 
@@ -164,6 +173,7 @@
 }
 
 void LayoutVideo::UpdatePlayer(bool is_in_layout) {
+  CheckIsNotDestroyed();
   UpdateIntrinsicSize(is_in_layout);
 
   WebMediaPlayer* media_player = MediaElement()->GetWebMediaPlayer();
@@ -178,19 +188,23 @@
 
 LayoutUnit LayoutVideo::ComputeReplacedLogicalWidth(
     ShouldComputePreferred should_compute_preferred) const {
+  CheckIsNotDestroyed();
   return LayoutReplaced::ComputeReplacedLogicalWidth(should_compute_preferred);
 }
 
 LayoutUnit LayoutVideo::ComputeReplacedLogicalHeight(
     LayoutUnit estimated_used_width) const {
+  CheckIsNotDestroyed();
   return LayoutReplaced::ComputeReplacedLogicalHeight(estimated_used_width);
 }
 
 LayoutUnit LayoutVideo::MinimumReplacedHeight() const {
+  CheckIsNotDestroyed();
   return LayoutReplaced::MinimumReplacedHeight();
 }
 
 PhysicalRect LayoutVideo::ReplacedContentRect() const {
+  CheckIsNotDestroyed();
   if (GetDisplayMode() == kVideo) {
     // Video codecs may need to restart from an I-frame when the output is
     // resized. Round size in advance to avoid 1px snap difference.
@@ -202,10 +216,12 @@
 }
 
 bool LayoutVideo::SupportsAcceleratedRendering() const {
+  CheckIsNotDestroyed();
   return !!MediaElement()->CcLayer();
 }
 
 CompositingReasons LayoutVideo::AdditionalCompositingReasons() const {
+  CheckIsNotDestroyed();
   auto* element = To<HTMLMediaElement>(GetNode());
   if (element->IsFullscreen() && element->UsesOverlayFullscreenVideo())
     return CompositingReason::kVideo;
diff --git a/third_party/blink/renderer/core/layout/layout_video.h b/third_party/blink/renderer/core/layout/layout_video.h
index bf28cb53..ca97cf4 100644
--- a/third_party/blink/renderer/core/layout/layout_video.h
+++ b/third_party/blink/renderer/core/layout/layout_video.h
@@ -49,11 +49,17 @@
 
   HTMLVideoElement* VideoElement() const;
 
-  const char* GetName() const override { return "LayoutVideo"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutVideo";
+  }
 
   void IntrinsicSizeChanged() override;
 
-  bool ComputeShouldClipOverflow() const final { return true; }
+  bool ComputeShouldClipOverflow() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
  private:
   void UpdateFromElement() override;
@@ -64,6 +70,7 @@
   void ImageChanged(WrappedImagePtr, CanDeferInvalidation) override;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectVideo || LayoutMedia::IsOfType(type);
   }
 
@@ -78,7 +85,10 @@
       LayoutUnit estimated_used_width = LayoutUnit()) const override;
   LayoutUnit MinimumReplacedHeight() const override;
 
-  bool CanHaveAdditionalCompositingReasons() const override { return true; }
+  bool CanHaveAdditionalCompositingReasons() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
   CompositingReasons AdditionalCompositingReasons() const override;
 
   void UpdatePlayer(bool is_in_layout);
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc
index 4707295..2ca8c68 100644
--- a/third_party/blink/renderer/core/layout/layout_view.cc
+++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -129,6 +129,7 @@
 
 bool LayoutView::HitTest(const HitTestLocation& location,
                          HitTestResult& result) {
+  CheckIsNotDestroyed();
   // We have to recursively update layout/style here because otherwise, when the
   // hit test recurses into a child document, it could trigger a layout on the
   // parent document, which can destroy PaintLayer that are higher up in the
@@ -153,6 +154,7 @@
 
 bool LayoutView::HitTestNoLifecycleUpdate(const HitTestLocation& location,
                                           HitTestResult& result) {
+  CheckIsNotDestroyed();
   TRACE_EVENT_BEGIN0("blink,devtools.timeline", "HitTest");
   hit_test_count_++;
 
@@ -214,6 +216,7 @@
 }
 
 void LayoutView::ClearHitTestCache() {
+  CheckIsNotDestroyed();
   hit_test_cache_->Clear();
   auto* object = GetFrame()->OwnerLayoutObject();
   if (object)
@@ -224,19 +227,23 @@
     LayoutUnit logical_height,
     LayoutUnit,
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   computed_values.extent_ = LayoutUnit(ViewLogicalHeightForBoxSizing());
 }
 
 void LayoutView::UpdateLogicalWidth() {
+  CheckIsNotDestroyed();
   SetLogicalWidth(LayoutUnit(ViewLogicalWidthForBoxSizing()));
 }
 
 bool LayoutView::IsChildAllowed(LayoutObject* child,
                                 const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   return child->IsBox();
 }
 
 bool LayoutView::CanHaveChildren() const {
+  CheckIsNotDestroyed();
   FrameOwner* owner = GetFrame()->Owner();
   if (!owner)
     return true;
@@ -257,11 +264,13 @@
 
 #if DCHECK_IS_ON()
 void LayoutView::CheckLayoutState() {
+  CheckIsNotDestroyed();
   DCHECK(!layout_state_->Next());
 }
 #endif
 
 bool LayoutView::ShouldPlaceBlockDirectionScrollbarOnLogicalLeft() const {
+  CheckIsNotDestroyed();
   LocalFrame& frame = GetFrameView()->GetFrame();
   // See crbug.com/249860
   if (frame.IsMainFrame())
@@ -278,6 +287,7 @@
 }
 
 void LayoutView::UpdateBlockLayout(bool relayout_children) {
+  CheckIsNotDestroyed();
   SubtreeLayoutScope layout_scope(*this);
 
   // Use calcWidth/Height to get the new width/height, since this will take the
@@ -314,6 +324,7 @@
 }
 
 void LayoutView::UpdateLayout() {
+  CheckIsNotDestroyed();
   if (!GetDocument().Printing()) {
     SetPageLogicalHeight(LayoutUnit());
     named_pages_mapper_ = nullptr;
@@ -368,6 +379,7 @@
 }
 
 PhysicalRect LayoutView::LocalVisualRectIgnoringVisibility() const {
+  CheckIsNotDestroyed();
   PhysicalRect rect = PhysicalVisualOverflowRect();
   rect.Unite(PhysicalRect(rect.offset, ViewRect().size));
   return rect;
@@ -376,6 +388,7 @@
 void LayoutView::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                                     TransformState& transform_state,
                                     MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   if (!ancestor && !(mode & kIgnoreTransforms) &&
       ShouldUseTransformFromContainer(nullptr)) {
     TransformationMatrix t;
@@ -410,6 +423,7 @@
 const LayoutObject* LayoutView::PushMappingToContainer(
     const LayoutBoxModelObject* ancestor_to_stop_at,
     LayoutGeometryMap& geometry_map) const {
+  CheckIsNotDestroyed();
   PhysicalOffset offset;
   LayoutObject* container = nullptr;
 
@@ -440,6 +454,7 @@
 void LayoutView::MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
                                     TransformState& transform_state,
                                     MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   if (this != ancestor && (mode & kTraverseDocumentBoundaries)) {
     if (auto* parent_doc_layout_object = GetFrame()->OwnerLayoutObject()) {
       // A LayoutView is a containing block for fixed-position elements, so
@@ -465,11 +480,13 @@
 }
 
 void LayoutView::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   ViewPainter(*this).Paint(paint_info);
 }
 
 void LayoutView::PaintBoxDecorationBackground(const PaintInfo& paint_info,
                                               const PhysicalOffset&) const {
+  CheckIsNotDestroyed();
   ViewPainter(*this).PaintBoxDecorationBackground(paint_info);
 }
 
@@ -483,6 +500,7 @@
 }
 
 void LayoutView::SetShouldDoFullPaintInvalidationForViewAndAllDescendants() {
+  CheckIsNotDestroyed();
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
     SetSubtreeShouldDoFullPaintInvalidation();
   else
@@ -490,6 +508,7 @@
 }
 
 void LayoutView::InvalidatePaintForViewAndCompositedLayers() {
+  CheckIsNotDestroyed();
   SetSubtreeShouldDoFullPaintInvalidation();
 
   if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
@@ -504,6 +523,7 @@
     PhysicalRect& rect,
     MapCoordinatesFlags mode,
     VisualRectFlags visual_rect_flags) const {
+  CheckIsNotDestroyed();
   bool intersects = true;
   if (MapToVisualRectInAncestorSpaceInternalFastPath(
           ancestor, rect, visual_rect_flags, intersects))
@@ -523,6 +543,7 @@
     const LayoutBoxModelObject* ancestor,
     TransformState& transform_state,
     VisualRectFlags visual_rect_flags) const {
+  CheckIsNotDestroyed();
   return MapToVisualRectInAncestorSpaceInternal(ancestor, transform_state, 0,
                                                 visual_rect_flags);
 }
@@ -532,6 +553,7 @@
     TransformState& transform_state,
     MapCoordinatesFlags mode,
     VisualRectFlags visual_rect_flags) const {
+  CheckIsNotDestroyed();
   if (mode & kIsFixed)
     transform_state.Move(OffsetForFixedPosition());
 
@@ -589,34 +611,40 @@
 }
 
 PhysicalOffset LayoutView::OffsetForFixedPosition() const {
+  CheckIsNotDestroyed();
   return IsScrollContainer() ? PhysicalOffset(ScrolledContentOffset())
                              : PhysicalOffset();
 }
 
 PhysicalOffset LayoutView::PixelSnappedOffsetForFixedPosition() const {
+  CheckIsNotDestroyed();
   return PhysicalOffset(FlooredIntPoint(OffsetForFixedPosition()));
 }
 
 void LayoutView::AbsoluteQuads(Vector<FloatQuad>& quads,
                                MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   quads.push_back(LocalRectToAbsoluteQuad(
       PhysicalRect(PhysicalOffset(), PhysicalSizeToBeNoop(Layer()->Size())),
       mode));
 }
 
 void LayoutView::CommitPendingSelection() {
+  CheckIsNotDestroyed();
   TRACE_EVENT0("blink", "LayoutView::commitPendingSelection");
   DCHECK(!NeedsLayout());
   frame_view_->GetFrame().Selection().CommitAppearanceIfNeeded();
 }
 
 bool LayoutView::ShouldUsePrintingLayout() const {
+  CheckIsNotDestroyed();
   if (!GetDocument().Printing() || !frame_view_)
     return false;
   return frame_view_->GetFrame().ShouldUsePrintingLayout();
 }
 
 PhysicalRect LayoutView::ViewRect() const {
+  CheckIsNotDestroyed();
   if (ShouldUsePrintingLayout())
     return PhysicalRect(PhysicalOffset(), Size());
   if (frame_view_)
@@ -627,6 +655,7 @@
 PhysicalRect LayoutView::OverflowClipRect(
     const PhysicalOffset& location,
     OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior) const {
+  CheckIsNotDestroyed();
   PhysicalRect rect = ViewRect();
   if (rect.IsEmpty()) {
     return LayoutBox::OverflowClipRect(location,
@@ -642,6 +671,7 @@
 
 void LayoutView::SetAutosizeScrollbarModes(mojom::blink::ScrollbarMode h_mode,
                                            mojom::blink::ScrollbarMode v_mode) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(v_mode == mojom::blink::ScrollbarMode::kAuto,
             h_mode == mojom::blink::ScrollbarMode::kAuto);
   autosize_v_scrollbar_mode_ = v_mode;
@@ -651,6 +681,7 @@
 void LayoutView::CalculateScrollbarModes(
     mojom::blink::ScrollbarMode& h_mode,
     mojom::blink::ScrollbarMode& v_mode) const {
+  CheckIsNotDestroyed();
 #define RETURN_SCROLLBAR_MODE(mode) \
   {                                 \
     h_mode = v_mode = mode;         \
@@ -748,11 +779,13 @@
 }
 
 PhysicalRect LayoutView::DocumentRect() const {
+  CheckIsNotDestroyed();
   return FlipForWritingMode(LayoutOverflowRect());
 }
 
 IntSize LayoutView::GetLayoutSize(
     IncludeScrollbarsInRect scrollbar_inclusion) const {
+  CheckIsNotDestroyed();
   if (ShouldUsePrintingLayout())
     return IntSize(Size().Width().ToInt(), PageLogicalHeight().ToInt());
 
@@ -767,27 +800,32 @@
 
 int LayoutView::ViewLogicalWidth(
     IncludeScrollbarsInRect scrollbar_inclusion) const {
+  CheckIsNotDestroyed();
   return StyleRef().IsHorizontalWritingMode() ? ViewWidth(scrollbar_inclusion)
                                               : ViewHeight(scrollbar_inclusion);
 }
 
 int LayoutView::ViewLogicalHeight(
     IncludeScrollbarsInRect scrollbar_inclusion) const {
+  CheckIsNotDestroyed();
   return StyleRef().IsHorizontalWritingMode() ? ViewHeight(scrollbar_inclusion)
                                               : ViewWidth(scrollbar_inclusion);
 }
 
 LayoutUnit LayoutView::ViewLogicalHeightForPercentages() const {
+  CheckIsNotDestroyed();
   if (ShouldUsePrintingLayout())
     return PageLogicalHeight();
   return LayoutUnit(ViewLogicalHeight());
 }
 
 float LayoutView::ZoomFactor() const {
+  CheckIsNotDestroyed();
   return frame_view_->GetFrame().PageZoomFactor();
 }
 
 const LayoutBox& LayoutView::RootBox() const {
+  CheckIsNotDestroyed();
   Element* document_element = GetDocument().documentElement();
   DCHECK(document_element);
   DCHECK(document_element->GetLayoutObject());
@@ -796,6 +834,7 @@
 }
 
 void LayoutView::UpdateAfterLayout() {
+  CheckIsNotDestroyed();
   // Unlike every other layer, the root PaintLayer takes its size from the
   // layout viewport size.  The call to AdjustViewSize() will update the
   // frame's contents size, which will also update the page's minimum scale
@@ -814,6 +853,7 @@
 
 void LayoutView::UpdateHitTestResult(HitTestResult& result,
                                      const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   if (result.InnerNode())
     return;
 
@@ -828,36 +868,43 @@
 }
 
 bool LayoutView::UsesCompositing() const {
+  CheckIsNotDestroyed();
   return compositor_ && compositor_->StaleInCompositingMode();
 }
 
 PaintLayerCompositor* LayoutView::Compositor() {
+  CheckIsNotDestroyed();
   return compositor_.get();
 }
 
 void LayoutView::CleanUpCompositor() {
+  CheckIsNotDestroyed();
   DCHECK(compositor_);
   compositor_->CleanUp();
 }
 
 IntervalArena* LayoutView::GetIntervalArena() {
+  CheckIsNotDestroyed();
   if (!interval_arena_)
     interval_arena_ = IntervalArena::Create();
   return interval_arena_.get();
 }
 
 bool LayoutView::BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const {
+  CheckIsNotDestroyed();
   // The base background color applies to the main frame only.
   return GetFrame()->IsMainFrame() &&
          !frame_view_->BaseBackgroundColor().HasAlpha();
 }
 
 FloatSize LayoutView::ViewportSizeForViewportUnits() const {
+  CheckIsNotDestroyed();
   return GetFrameView() ? GetFrameView()->ViewportSizeForViewportUnits()
                         : FloatSize();
 }
 
 void LayoutView::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   // TODO(wangxianzhu): This is a workaround of crbug.com/570706.
   // Should find and fix the root cause.
   if (PaintLayer* layer = Layer())
@@ -867,6 +914,7 @@
 }
 
 void LayoutView::UpdateFromStyle() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::UpdateFromStyle();
 
   // LayoutView of the main frame is responsible for painting base background.
@@ -875,6 +923,7 @@
 }
 
 bool LayoutView::RecalcLayoutOverflow() {
+  CheckIsNotDestroyed();
   if (!NeedsLayoutOverflowRecalc())
     return false;
   bool result = LayoutBlockFlow::RecalcLayoutOverflow();
@@ -897,11 +946,13 @@
 }
 
 PhysicalRect LayoutView::DebugRect() const {
+  CheckIsNotDestroyed();
   return PhysicalRect(IntRect(0, 0, ViewWidth(kIncludeScrollbars),
                               ViewHeight(kIncludeScrollbars)));
 }
 
 bool LayoutView::UpdateLogicalWidthAndColumnWidth() {
+  CheckIsNotDestroyed();
   bool relayout_children = LayoutBlockFlow::UpdateLogicalWidthAndColumnWidth();
   // When we're printing, the size of LayoutView is changed outside of layout,
   // so we'll fail to detect any changes here. Just return true.
@@ -909,6 +960,7 @@
 }
 
 CompositingReasons LayoutView::AdditionalCompositingReasons() const {
+  CheckIsNotDestroyed();
   // TODO(lfg): Audit for portals
   const LocalFrame& frame = frame_view_->GetFrame();
   if (frame.OwnerLayoutObject() &&
@@ -921,6 +973,7 @@
 }
 
 void LayoutView::UpdateCounters() {
+  CheckIsNotDestroyed();
   if (!needs_counter_update_)
     return;
 
@@ -938,11 +991,13 @@
 }
 
 bool LayoutView::HasTickmarks() const {
+  CheckIsNotDestroyed();
   return !tickmarks_override_.IsEmpty() ||
          GetDocument().Markers().PossiblyHasTextMatchMarkers();
 }
 
 Vector<IntRect> LayoutView::GetTickmarks() const {
+  CheckIsNotDestroyed();
   if (!tickmarks_override_.IsEmpty())
     return tickmarks_override_;
 
@@ -950,11 +1005,13 @@
 }
 
 void LayoutView::OverrideTickmarks(const Vector<IntRect>& tickmarks) {
+  CheckIsNotDestroyed();
   tickmarks_override_ = tickmarks;
   InvalidatePaintForTickmarks();
 }
 
 void LayoutView::InvalidatePaintForTickmarks() {
+  CheckIsNotDestroyed();
   ScrollableArea* scrollable_area = GetScrollableArea();
   if (!scrollable_area)
     return;
diff --git a/third_party/blink/renderer/core/layout/layout_view.h b/third_party/blink/renderer/core/layout/layout_view.h
index d44e74b..2e2409e 100644
--- a/third_party/blink/renderer/core/layout/layout_view.h
+++ b/third_party/blink/renderer/core/layout/layout_view.h
@@ -76,18 +76,29 @@
                                 HitTestResult&);
 
   // Returns the total count of calls to HitTest, for testing.
-  unsigned HitTestCount() const { return hit_test_count_; }
-  unsigned HitTestCacheHits() const { return hit_test_cache_hits_; }
+  unsigned HitTestCount() const {
+    CheckIsNotDestroyed();
+    return hit_test_count_;
+  }
+  unsigned HitTestCacheHits() const {
+    CheckIsNotDestroyed();
+    return hit_test_cache_hits_;
+  }
 
   void ClearHitTestCache();
 
-  const char* GetName() const override { return "LayoutView"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutView";
+  }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectLayoutView || LayoutBlockFlow::IsOfType(type);
   }
 
   PaintLayerType LayerTypeRequired() const override {
+    CheckIsNotDestroyed();
     return kNormalPaintLayer;
   }
 
@@ -107,10 +118,12 @@
 
   int ViewHeight(
       IncludeScrollbarsInRect scrollbar_inclusion = kExcludeScrollbars) const {
+    CheckIsNotDestroyed();
     return GetLayoutSize(scrollbar_inclusion).Height();
   }
   int ViewWidth(
       IncludeScrollbarsInRect scrollbar_inclusion = kExcludeScrollbars) const {
+    CheckIsNotDestroyed();
     return GetLayoutSize(scrollbar_inclusion).Width();
   }
 
@@ -121,7 +134,10 @@
 
   float ZoomFactor() const;
 
-  LocalFrameView* GetFrameView() const { return frame_view_; }
+  LocalFrameView* GetFrameView() const {
+    CheckIsNotDestroyed();
+    return frame_view_;
+  }
   const LayoutBox& RootBox() const;
 
   void UpdateAfterLayout() override;
@@ -169,33 +185,47 @@
   void SetAutosizeScrollbarModes(mojom::blink::ScrollbarMode h_mode,
                                  mojom::blink::ScrollbarMode v_mode);
   mojom::blink::ScrollbarMode AutosizeHorizontalScrollbarMode() const {
+    CheckIsNotDestroyed();
     return autosize_h_scrollbar_mode_;
   }
   mojom::blink::ScrollbarMode AutosizeVerticalScrollbarMode() const {
+    CheckIsNotDestroyed();
     return autosize_v_scrollbar_mode_;
   }
 
   void CalculateScrollbarModes(mojom::blink::ScrollbarMode& h_mode,
                                mojom::blink::ScrollbarMode& v_mode) const;
 
-  LayoutState* GetLayoutState() const { return layout_state_; }
+  LayoutState* GetLayoutState() const {
+    CheckIsNotDestroyed();
+    return layout_state_;
+  }
 
-  bool CanHaveAdditionalCompositingReasons() const override { return true; }
+  bool CanHaveAdditionalCompositingReasons() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
   CompositingReasons AdditionalCompositingReasons() const override;
 
   void UpdateHitTestResult(HitTestResult&,
                            const PhysicalOffset&) const override;
 
   ViewFragmentationContext* FragmentationContext() const {
+    CheckIsNotDestroyed();
     return fragmentation_context_.get();
   }
 
-  LayoutUnit PageLogicalHeight() const { return page_logical_height_; }
+  LayoutUnit PageLogicalHeight() const {
+    CheckIsNotDestroyed();
+    return page_logical_height_;
+  }
   void SetPageLogicalHeight(LayoutUnit height) {
+    CheckIsNotDestroyed();
     page_logical_height_ = height;
   }
 
   NamedPagesMapper* GetNamedPagesMapper() const {
+    CheckIsNotDestroyed();
     return named_pages_mapper_.get();
   }
 
@@ -206,23 +236,37 @@
 
   IntervalArena* GetIntervalArena();
 
-  void SetLayoutQuoteHead(LayoutQuote* head) { layout_quote_head_ = head; }
-  LayoutQuote* LayoutQuoteHead() const { return layout_quote_head_; }
+  void SetLayoutQuoteHead(LayoutQuote* head) {
+    CheckIsNotDestroyed();
+    layout_quote_head_ = head;
+  }
+  LayoutQuote* LayoutQuoteHead() const {
+    CheckIsNotDestroyed();
+    return layout_quote_head_;
+  }
 
   // FIXME: This is a work around because the current implementation of counters
   // requires walking the entire tree repeatedly and most pages don't actually
   // use either feature so we shouldn't take the performance hit when not
   // needed. Long term we should rewrite the counter and quotes code.
   void AddLayoutCounter() {
+    CheckIsNotDestroyed();
     layout_counter_count_++;
     SetNeedsCounterUpdate();
   }
   void RemoveLayoutCounter() {
+    CheckIsNotDestroyed();
     DCHECK_GT(layout_counter_count_, 0u);
     layout_counter_count_--;
   }
-  bool HasLayoutCounters() { return layout_counter_count_; }
-  void SetNeedsCounterUpdate() { needs_counter_update_ = true; }
+  bool HasLayoutCounters() {
+    CheckIsNotDestroyed();
+    return layout_counter_count_;
+  }
+  void SetNeedsCounterUpdate() {
+    CheckIsNotDestroyed();
+    needs_counter_update_ = true;
+  }
   void UpdateCounters();
 
   bool BackgroundIsKnownToBeOpaqueInRect(
@@ -233,9 +277,11 @@
   FloatSize ViewportSizeForViewportUnits() const;
 
   void PushLayoutState(LayoutState& layout_state) {
+    CheckIsNotDestroyed();
     layout_state_ = &layout_state;
   }
   void PopLayoutState() {
+    CheckIsNotDestroyed();
     DCHECK(layout_state_);
     layout_state_ = layout_state_->Next();
   }
@@ -270,16 +316,19 @@
   // will be painted in this rect. It's also the positioning area of fixed-
   // attachment backgrounds.
   PhysicalRect BackgroundRect() const {
+    CheckIsNotDestroyed();
     return OverflowClipRect(PhysicalOffset());
   }
 
   // The previous BackgroundRect after the previous paint invalidation.
   PhysicalRect PreviousBackgroundRect() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(GetDocument().Lifecycle().GetState(),
               DocumentLifecycle::kInPrePaint);
     return previous_background_rect_;
   }
   void SetPreviousBackgroundRect(const PhysicalRect& r) const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(GetDocument().Lifecycle().GetState(),
               DocumentLifecycle::kInPrePaint);
     previous_background_rect_ = r;
@@ -310,9 +359,11 @@
   void UpdateFromStyle() override;
 
   int ViewLogicalWidthForBoxSizing() const {
+    CheckIsNotDestroyed();
     return ViewLogicalWidth(kIncludeScrollbars);
   }
   int ViewLogicalHeightForBoxSizing() const {
+    CheckIsNotDestroyed();
     return ViewLogicalHeight(kIncludeScrollbars);
   }
 
diff --git a/third_party/blink/renderer/core/layout/layout_vtt_cue.cc b/third_party/blink/renderer/core/layout/layout_vtt_cue.cc
index f882270..443e8a2 100644
--- a/third_party/blink/renderer/core/layout/layout_vtt_cue.cc
+++ b/third_party/blink/renderer/core/layout/layout_vtt_cue.cc
@@ -280,6 +280,7 @@
     : LayoutBlockFlow(node), snap_to_lines_position_(snap_to_lines_position) {}
 
 void LayoutVTTCue::RepositionCueSnapToLinesNotSet() {
+  CheckIsNotDestroyed();
   // FIXME: Implement overlapping detection when snap-to-lines is not set.
   // http://wkb.ug/84296
 
@@ -324,6 +325,7 @@
 }
 
 IntRect LayoutVTTCue::ComputeControlsRect() const {
+  CheckIsNotDestroyed();
   // Determine the area covered by the media controls, if any. For this, the
   // LayoutVTTCue will walk the tree up to the HTMLMediaElement, then ask for
   // the MediaControls.
@@ -359,6 +361,7 @@
 }
 
 void LayoutVTTCue::UpdateLayout() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::UpdateLayout();
 
   DCHECK(FirstChild());
diff --git a/third_party/blink/renderer/core/layout/layout_vtt_cue.h b/third_party/blink/renderer/core/layout/layout_vtt_cue.h
index c05ca7d0..de88be3 100644
--- a/third_party/blink/renderer/core/layout/layout_vtt_cue.h
+++ b/third_party/blink/renderer/core/layout/layout_vtt_cue.h
@@ -38,7 +38,10 @@
 
   // The computed line position for snap-to-lines layout, and NaN for
   // non-snap-to-lines layout where no adjustment should take place.
-  float SnapToLinesPosition() { return snap_to_lines_position_; }
+  float SnapToLinesPosition() {
+    CheckIsNotDestroyed();
+    return snap_to_lines_position_;
+  }
 
  private:
   void UpdateLayout() override;
diff --git a/third_party/blink/renderer/core/layout/layout_word_break.cc b/third_party/blink/renderer/core/layout/layout_word_break.cc
index 71af9f4..1e0b24a8 100644
--- a/third_party/blink/renderer/core/layout/layout_word_break.cc
+++ b/third_party/blink/renderer/core/layout/layout_word_break.cc
@@ -35,10 +35,12 @@
     : LayoutText(element, StringImpl::empty_) {}
 
 bool LayoutWordBreak::IsWordBreak() const {
+  CheckIsNotDestroyed();
   return true;
 }
 
 Position LayoutWordBreak::PositionForCaretOffset(unsigned offset) const {
+  CheckIsNotDestroyed();
   if (!GetNode())
     return Position();
   // The only allowed caret offset is 0, since LayoutWordBreak always has
@@ -49,6 +51,7 @@
 
 base::Optional<unsigned> LayoutWordBreak::CaretOffsetForPosition(
     const Position& position) const {
+  CheckIsNotDestroyed();
   if (position.IsNull() || position.AnchorNode() != GetNode())
     return base::nullopt;
   DCHECK(position.IsBeforeAnchor() || position.IsAfterAnchor());
diff --git a/third_party/blink/renderer/core/layout/layout_word_break.h b/third_party/blink/renderer/core/layout/layout_word_break.h
index 35d79ff7..2c1502e 100644
--- a/third_party/blink/renderer/core/layout/layout_word_break.h
+++ b/third_party/blink/renderer/core/layout/layout_word_break.h
@@ -40,7 +40,10 @@
   Position PositionForCaretOffset(unsigned offset) const final;
   base::Optional<unsigned> CaretOffsetForPosition(const Position&) const final;
 
-  const char* GetName() const override { return "LayoutWordBreak"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutWordBreak";
+  }
   bool IsWordBreak() const override;
 };
 
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 a03bdd4..9fb42b0 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
@@ -15,18 +15,28 @@
 class CORE_EXPORT LayoutNGText : public LayoutText {
  public:
   LayoutNGText(Node* node, scoped_refptr<StringImpl> text)
-      : LayoutText(node, text) {}
+      : LayoutText(node, text) {
+    CheckIsNotDestroyed();
+  }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectNGText || LayoutText::IsOfType(type);
   }
-  bool IsLayoutNGObject() const override { return true; }
+  bool IsLayoutNGObject() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
  private:
   const base::span<NGInlineItem>* GetNGInlineItems() const final {
+    CheckIsNotDestroyed();
     return &inline_items_;
   }
-  base::span<NGInlineItem>* GetNGInlineItems() final { return &inline_items_; }
+  base::span<NGInlineItem>* GetNGInlineItems() final {
+    CheckIsNotDestroyed();
+    return &inline_items_;
+  }
 
   base::span<NGInlineItem> inline_items_;
 };
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 0612bfa..bc4f172 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
@@ -18,17 +18,27 @@
                        StringImpl* text,
                        int start_offset,
                        int length)
-      : LayoutTextFragment(node, text, start_offset, length) {}
+      : LayoutTextFragment(node, text, start_offset, length) {
+    CheckIsNotDestroyed();
+  }
 
-  bool IsLayoutNGObject() const final { return true; }
+  bool IsLayoutNGObject() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
  private:
   const base::span<NGInlineItem>* GetNGInlineItems() const final {
+    CheckIsNotDestroyed();
     return &inline_items_;
   }
-  base::span<NGInlineItem>* GetNGInlineItems() final { return &inline_items_; }
+  base::span<NGInlineItem>* GetNGInlineItems() final {
+    CheckIsNotDestroyed();
+    return &inline_items_;
+  }
 
   void InsertedIntoTree() final {
+    CheckIsNotDestroyed();
     valid_ng_items_ = false;
     LayoutText::InsertedIntoTree();
   }
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 14d06df..947f093 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
@@ -141,7 +141,7 @@
     return end_offsets;
   }
 
-  void TestAnyItrermsAreDirty(LayoutBlockFlow* block_flow, bool expected) {
+  void TestAnyItemsAreDirty(LayoutBlockFlow* block_flow, bool expected) {
     const NGFragmentItems* items = block_flow->FragmentItems();
     items->DirtyLinesFromNeedsLayout(block_flow);
     // Check |NGFragmentItem::IsDirty| directly without using
@@ -599,11 +599,14 @@
   unsigned needs_collect_inlines;
   base::Optional<bool> is_line_dirty;
 } style_change_data[] = {
-    // Changing color, etc. should not re-run
+    // Changing color, text-decoration, outline, etc. should not re-run
     // |CollectInlines()|.
     {"#parent.after { color: red; }", StyleChangeData::kNone, false},
-    {"#parent.after { text-decoration-color: red; }", StyleChangeData::kNone,
-     false},
+    // TODO(crbug.com/1128199): text-decorations, outline, etc. should not
+    // require layout, only ink overflow, but they currently do.
+    {"#parent.after { text-decoration-line: underline; }",
+     StyleChangeData::kNone, true},
+    {"#parent.after { outline: auto; }", StyleChangeData::kNone, true},
     // Changing fonts should re-run |CollectInlines()|.
     {"#parent.after { font-size: 200%; }", StyleChangeData::kAll, true},
     // Changing from/to out-of-flow should re-rerun |CollectInlines()|.
@@ -682,8 +685,8 @@
 
   if (data.is_line_dirty &&
       RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
-    TestAnyItrermsAreDirty(To<LayoutBlockFlow>(container->GetLayoutObject()),
-                           *data.is_line_dirty);
+    TestAnyItemsAreDirty(To<LayoutBlockFlow>(container->GetLayoutObject()),
+                         *data.is_line_dirty);
   }
 
   ForceLayout();  // Ensure running layout does not crash.
diff --git a/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.cc b/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.cc
index 626ba03e2..9098a82 100644
--- a/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.cc
+++ b/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.cc
@@ -12,12 +12,14 @@
     : LayoutInline(element) {}
 
 bool LayoutNGInsideListMarker::IsOfType(LayoutObjectType type) const {
+  CheckIsNotDestroyed();
   return type == kLayoutObjectNGInsideListMarker ||
          LayoutInline::IsOfType(type);
 }
 
 PositionWithAffinity LayoutNGInsideListMarker::PositionForPoint(
     const PhysicalOffset&) const {
+  CheckIsNotDestroyed();
   return CreatePositionWithAffinity(0);
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h b/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h
index 8d1e302..fe5642c 100644
--- a/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h
+++ b/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h
@@ -16,13 +16,23 @@
  public:
   explicit LayoutNGInsideListMarker(Element*);
 
-  const char* GetName() const override { return "LayoutNGInsideListMarker"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutNGInsideListMarker";
+  }
 
-  const ListMarker& Marker() const { return list_marker_; }
-  ListMarker& Marker() { return list_marker_; }
+  const ListMarker& Marker() const {
+    CheckIsNotDestroyed();
+    return list_marker_;
+  }
+  ListMarker& Marker() {
+    CheckIsNotDestroyed();
+    return list_marker_;
+  }
 
 #if DCHECK_IS_ON()
   void AddChild(LayoutObject* new_child, LayoutObject* before_child) override {
+    CheckIsNotDestroyed();
     // List markers with 'content: normal' should have at most one child.
     DCHECK(!StyleRef().ContentBehavesAsNormal() || !FirstChild());
     LayoutInline::AddChild(new_child, before_child);
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 f1c8235..0468c45 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
@@ -17,6 +17,7 @@
 
 void LayoutNGTableColumn::StyleDidChange(StyleDifference diff,
                                          const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   if (diff.NeedsPaintInvalidation() && old_style) {
     if (LayoutNGTable* table = Table()) {
       if (NGTableBorders::HasBorder(old_style) ||
@@ -28,6 +29,7 @@
 }
 
 void LayoutNGTableColumn::ImageChanged(WrappedImagePtr, CanDeferInvalidation) {
+  CheckIsNotDestroyed();
   if (LayoutNGTable* table = Table()) {
     table->SetShouldDoFullPaintInvalidationWithoutGeometryChange(
         PaintInvalidationReason::kImage);
@@ -36,15 +38,18 @@
 
 bool LayoutNGTableColumn::IsChildAllowed(LayoutObject* child,
                                          const ComputedStyle& style) const {
+  CheckIsNotDestroyed();
   return child->IsLayoutTableCol() && style.Display() == EDisplay::kTableColumn;
 }
 
 bool LayoutNGTableColumn::CanHaveChildren() const {
+  CheckIsNotDestroyed();
   // <col> cannot have children.
   return IsColumnGroup();
 }
 
 void LayoutNGTableColumn::ClearNeedsLayoutForChildren() const {
+  CheckIsNotDestroyed();
   LayoutObject* child = children_.FirstChild();
   while (child) {
     child->ClearNeedsLayout();
@@ -53,6 +58,7 @@
 }
 
 LayoutNGTable* LayoutNGTableColumn::Table() const {
+  CheckIsNotDestroyed();
   LayoutObject* table = Parent();
   if (table && !table->IsTable())
     table = table->Parent();
@@ -64,6 +70,7 @@
 }
 
 void LayoutNGTableColumn::UpdateFromElement() {
+  CheckIsNotDestroyed();
   unsigned old_span = span_;
   if (const auto* tc = DynamicTo<HTMLTableColElement>(GetNode())) {
     span_ = tc->span();
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 0db6305e..81c5bf1 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
@@ -20,14 +20,19 @@
   LayoutNGTable* Table() const;
 
   bool IsColumn() const {
+    CheckIsNotDestroyed();
     return StyleRef().Display() == EDisplay::kTableColumn;
   }
 
   bool IsColumnGroup() const {
+    CheckIsNotDestroyed();
     return StyleRef().Display() == EDisplay::kTableColumnGroup;
   }
 
-  unsigned Span() const { return span_; }
+  unsigned Span() const {
+    CheckIsNotDestroyed();
+    return span_;
+  }
 
   // Clears needs-layout for child columns too.
   void ClearNeedsLayoutForChildren() const;
@@ -35,13 +40,17 @@
   // LayoutObject methods start.
 
   const char* GetName() const override {
+    CheckIsNotDestroyed();
     if (IsColumn())
       return "LayoutNGTableCol";
     else
       return "LayoutNGTableColGroup";
   }
 
-  bool IsLayoutNGObject() const final { return true; }
+  bool IsLayoutNGObject() const final {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   void StyleDidChange(StyleDifference diff,
                       const ComputedStyle* old_style) final;
@@ -51,11 +60,13 @@
  protected:
   // Required by LayoutBox, but not used.
   MinMaxSizes ComputeIntrinsicLogicalWidths() const override {
+    CheckIsNotDestroyed();
     NOTIMPLEMENTED();
     return MinMaxSizes();
   }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectLayoutTableCol || LayoutBox::IsOfType(type);
   }
 
@@ -66,11 +77,18 @@
 
   void UpdateFromElement() override;
 
-  PaintLayerType LayerTypeRequired() const override { return kNoPaintLayer; }
+  PaintLayerType LayerTypeRequired() const override {
+    CheckIsNotDestroyed();
+    return kNoPaintLayer;
+  }
 
-  LayoutObjectChildList* VirtualChildren() override { return &children_; }
+  LayoutObjectChildList* VirtualChildren() override {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
 
   const LayoutObjectChildList* VirtualChildren() const override {
+    CheckIsNotDestroyed();
     return &children_;
   }
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc
index 87407ce..823db0b 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_block.cc
@@ -41,16 +41,19 @@
       transform_uses_reference_box_(false) {}
 
 SVGElement* LayoutSVGBlock::GetElement() const {
+  CheckIsNotDestroyed();
   return To<SVGElement>(LayoutObject::GetNode());
 }
 
 void LayoutSVGBlock::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   SVGResourcesCache::ClientDestroyed(*this);
   SVGResources::ClearClipPathFilterMask(*GetElement(), Style());
   LayoutBlockFlow::WillBeDestroyed();
 }
 
 void LayoutSVGBlock::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::InsertedIntoTree();
   if (CompositingReasonFinder::DirectReasonsForSVGChildPaintProperties(*this) !=
       CompositingReason::kNone) {
@@ -59,6 +62,7 @@
 }
 
 void LayoutSVGBlock::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::WillBeRemovedFromTree();
   if (CompositingReasonFinder::DirectReasonsForSVGChildPaintProperties(*this) !=
       CompositingReason::kNone) {
@@ -67,11 +71,13 @@
 }
 
 void LayoutSVGBlock::UpdateFromStyle() {
+  CheckIsNotDestroyed();
   LayoutBlockFlow::UpdateFromStyle();
   SetFloating(false);
 }
 
 bool LayoutSVGBlock::CheckForImplicitTransformChange(bool bbox_changed) const {
+  CheckIsNotDestroyed();
   // If the transform is relative to the reference box, check relevant
   // conditions to see if we need to recompute the transform.
   switch (StyleRef().TransformBox()) {
@@ -85,6 +91,7 @@
 }
 
 bool LayoutSVGBlock::UpdateTransformAfterLayout(bool bounds_changed) {
+  CheckIsNotDestroyed();
   // If our transform depends on the reference box, we need to check if it needs
   // to be updated.
   if (!needs_transform_update_ && transform_uses_reference_box_) {
@@ -102,6 +109,7 @@
 
 void LayoutSVGBlock::StyleDidChange(StyleDifference diff,
                                     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   transform_uses_reference_box_ =
       TransformHelper::DependsOnReferenceBox(StyleRef());
 
@@ -137,6 +145,7 @@
 void LayoutSVGBlock::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                                         TransformState& transform_state,
                                         MapCoordinatesFlags flags) const {
+  CheckIsNotDestroyed();
   // Convert from local HTML coordinates to local SVG coordinates.
   transform_state.Move(PhysicalLocation());
   // Apply other mappings on local SVG coordinates.
@@ -146,6 +155,7 @@
 void LayoutSVGBlock::MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
                                         TransformState& transform_state,
                                         MapCoordinatesFlags flags) const {
+  CheckIsNotDestroyed();
   if (this == ancestor)
     return;
 
@@ -158,6 +168,7 @@
 const LayoutObject* LayoutSVGBlock::PushMappingToContainer(
     const LayoutBoxModelObject* ancestor_to_stop_at,
     LayoutGeometryMap& geometry_map) const {
+  CheckIsNotDestroyed();
   // Convert from local HTML coordinates to local SVG coordinates.
   geometry_map.Push(this, PhysicalLocation());
   // Apply other mappings on local SVG coordinates.
@@ -166,6 +177,7 @@
 }
 
 PhysicalRect LayoutSVGBlock::VisualRectInDocument(VisualRectFlags flags) const {
+  CheckIsNotDestroyed();
   return SVGLayoutSupport::VisualRectInAncestorSpace(*this, *View(), flags);
 }
 
@@ -173,6 +185,7 @@
     const LayoutBoxModelObject* ancestor,
     TransformState& transform_state,
     VisualRectFlags) const {
+  CheckIsNotDestroyed();
   transform_state.Flatten();
   PhysicalRect rect(LayoutRect(transform_state.LastPlanarQuad().BoundingBox()));
   // Convert from local HTML coordinates to local SVG coordinates.
@@ -188,6 +201,7 @@
                                  const HitTestLocation&,
                                  const PhysicalOffset&,
                                  HitTestAction) {
+  CheckIsNotDestroyed();
   NOTREACHED();
   return false;
 }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_block.h b/third_party/blink/renderer/core/layout/svg/layout_svg_block.h
index 7e3e67c..61ac83c3 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_block.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_block.h
@@ -49,10 +49,19 @@
       const LayoutBoxModelObject* ancestor_to_stop_at,
       LayoutGeometryMap&) const final;
 
-  AffineTransform LocalSVGTransform() const final { return local_transform_; }
-  void SetNeedsTransformUpdate() override { needs_transform_update_ = true; }
+  AffineTransform LocalSVGTransform() const final {
+    CheckIsNotDestroyed();
+    return local_transform_;
+  }
+  void SetNeedsTransformUpdate() override {
+    CheckIsNotDestroyed();
+    needs_transform_update_ = true;
+  }
 
-  PaintLayerType LayerTypeRequired() const override { return kNoPaintLayer; }
+  PaintLayerType LayerTypeRequired() const override {
+    CheckIsNotDestroyed();
+    return kNoPaintLayer;
+  }
 
   SVGElement* GetElement() const;
 
@@ -71,6 +80,7 @@
   bool transform_uses_reference_box_ : 1;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVG || LayoutBlockFlow::IsOfType(type);
   }
 
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 1445d274..b49f276 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
@@ -45,6 +45,7 @@
 LayoutSVGContainer::~LayoutSVGContainer() = default;
 
 void LayoutSVGContainer::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
 
@@ -88,6 +89,7 @@
 
 void LayoutSVGContainer::AddChild(LayoutObject* child,
                                   LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   LayoutSVGModelObject::AddChild(child, before_child);
   SVGResourcesCache::ClientWasAddedToTree(*child);
 
@@ -99,6 +101,7 @@
 }
 
 void LayoutSVGContainer::RemoveChild(LayoutObject* child) {
+  CheckIsNotDestroyed();
   SVGResourcesCache::ClientWillBeRemovedFromTree(*child);
   LayoutSVGModelObject::RemoveChild(child);
 
@@ -110,11 +113,13 @@
 }
 
 bool LayoutSVGContainer::SelfWillPaint() const {
+  CheckIsNotDestroyed();
   return SVGLayoutSupport::HasFilterResource(*this);
 }
 
 void LayoutSVGContainer::StyleDidChange(StyleDifference diff,
                                         const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutSVGModelObject::StyleDidChange(diff, old_style);
 
   bool had_isolation =
@@ -140,6 +145,7 @@
 }
 
 bool LayoutSVGContainer::HasNonIsolatedBlendingDescendants() const {
+  CheckIsNotDestroyed();
   if (has_non_isolated_blending_descendants_dirty_) {
     has_non_isolated_blending_descendants_ =
         SVGLayoutSupport::ComputeHasNonIsolatedBlendingDescendants(this);
@@ -150,6 +156,7 @@
 
 void LayoutSVGContainer::DescendantIsolationRequirementsChanged(
     DescendantIsolationState state) {
+  CheckIsNotDestroyed();
   switch (state) {
     case kDescendantIsolationRequired:
       has_non_isolated_blending_descendants_ = true;
@@ -170,10 +177,12 @@
 }
 
 void LayoutSVGContainer::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   SVGContainerPainter(*this).Paint(paint_info);
 }
 
 void LayoutSVGContainer::UpdateCachedBoundaries() {
+  CheckIsNotDestroyed();
   auto old_object_bounding_box = object_bounding_box_;
 
   SVGLayoutSupport::ComputeContainerBoundingBoxes(
@@ -192,6 +201,7 @@
                                      const HitTestLocation& hit_test_location,
                                      const PhysicalOffset& accumulated_offset,
                                      HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(accumulated_offset, PhysicalOffset());
   TransformedHitTestLocation local_location(hit_test_location,
                                             LocalToSVGParentTransform());
@@ -228,6 +238,7 @@
 
 SVGTransformChange LayoutSVGContainer::CalculateLocalTransform(
     bool bounds_changed) {
+  CheckIsNotDestroyed();
   return SVGTransformChange::kNone;
 }
 
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 d68caa6..cc47b5d 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
@@ -41,37 +41,57 @@
   void SlowLastChild() const = delete;
 
   LayoutObject* FirstChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->FirstChild();
   }
   LayoutObject* LastChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->LastChild();
   }
 
   void Paint(const PaintInfo&) const override;
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
-  void SetNeedsBoundariesUpdate() final { needs_boundaries_update_ = true; }
+  void SetNeedsBoundariesUpdate() final {
+    CheckIsNotDestroyed();
+    needs_boundaries_update_ = true;
+  }
   bool DidScreenScaleFactorChange() const {
+    CheckIsNotDestroyed();
     return did_screen_scale_factor_change_;
   }
-  bool IsObjectBoundingBoxValid() const { return object_bounding_box_valid_; }
+  bool IsObjectBoundingBoxValid() const {
+    CheckIsNotDestroyed();
+    return object_bounding_box_valid_;
+  }
 
   bool SelfWillPaint() const;
 
   bool HasNonIsolatedBlendingDescendants() const final;
 
-  const char* GetName() const override { return "LayoutSVGContainer"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGContainer";
+  }
 
-  FloatRect ObjectBoundingBox() const final { return object_bounding_box_; }
+  FloatRect ObjectBoundingBox() const final {
+    CheckIsNotDestroyed();
+    return object_bounding_box_;
+  }
 
  protected:
-  LayoutObjectChildList* VirtualChildren() final { return Children(); }
+  LayoutObjectChildList* VirtualChildren() final {
+    CheckIsNotDestroyed();
+    return Children();
+  }
   const LayoutObjectChildList* VirtualChildren() const final {
+    CheckIsNotDestroyed();
     return Children();
   }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVGContainer ||
            LayoutSVGModelObject::IsOfType(type);
   }
@@ -81,7 +101,10 @@
                 LayoutObject* before_child = nullptr) final;
   void RemoveChild(LayoutObject*) final;
 
-  FloatRect StrokeBoundingBox() const final { return stroke_bounding_box_; }
+  FloatRect StrokeBoundingBox() const final {
+    CheckIsNotDestroyed();
+    return stroke_bounding_box_;
+  }
 
   bool NodeAtPoint(HitTestResult&,
                    const HitTestLocation&,
@@ -96,8 +119,14 @@
   void DescendantIsolationRequirementsChanged(DescendantIsolationState) final;
 
  private:
-  const LayoutObjectChildList* Children() const { return &children_; }
-  LayoutObjectChildList* Children() { return &children_; }
+  const LayoutObjectChildList* Children() const {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
+  LayoutObjectChildList* Children() {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
 
   LayoutObjectChildList children_;
   FloatRect object_bounding_box_;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.cc
index b19a0cf..d69a785 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.cc
@@ -39,6 +39,7 @@
 LayoutSVGEllipse::~LayoutSVGEllipse() = default;
 
 void LayoutSVGEllipse::UpdateShapeFromElement() {
+  CheckIsNotDestroyed();
   // Before creating a new object we need to clear the cached bounding box
   // to avoid using garbage.
   fill_bounding_box_ = FloatRect();
@@ -79,6 +80,7 @@
 }
 
 void LayoutSVGEllipse::CalculateRadiiAndCenter() {
+  CheckIsNotDestroyed();
   DCHECK(GetElement());
   SVGLengthContext length_context(GetElement());
   const ComputedStyle& style = StyleRef();
@@ -102,6 +104,7 @@
 
 bool LayoutSVGEllipse::ShapeDependentStrokeContains(
     const HitTestLocation& location) {
+  CheckIsNotDestroyed();
   if (radii_.Width() < 0 || radii_.Height() < 0)
     return false;
 
@@ -121,6 +124,7 @@
 bool LayoutSVGEllipse::ShapeDependentFillContains(
     const HitTestLocation& location,
     const WindRule fill_rule) const {
+  CheckIsNotDestroyed();
   const FloatPoint& point = location.TransformedPoint();
   const FloatPoint center =
       FloatPoint(center_.X() - point.X(), center_.Y() - point.Y());
@@ -133,6 +137,7 @@
 }
 
 bool LayoutSVGEllipse::HasContinuousStroke() const {
+  CheckIsNotDestroyed();
   const SVGComputedStyle& svg_style = StyleRef().SvgStyle();
   return svg_style.StrokeDashArray()->data.IsEmpty();
 }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.h b/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.h
index 9672a40b..39a80bd 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.h
@@ -37,14 +37,19 @@
   ~LayoutSVGEllipse() override;
 
   ShapeGeometryCodePath GeometryCodePath() const override {
+    CheckIsNotDestroyed();
     return use_path_fallback_ ? kPathGeometry : kEllipseGeometryFastPath;
   }
 
-  const char* GetName() const override { return "LayoutSVGEllipse"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGEllipse";
+  }
 
  private:
   void UpdateShapeFromElement() override;
   bool IsShapeEmpty() const override {
+    CheckIsNotDestroyed();
     return use_path_fallback_ ? LayoutSVGShape::IsShapeEmpty()
                               : fill_bounding_box_.IsEmpty();
   }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.cc
index 7ab5397..a03174f 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.cc
@@ -57,6 +57,7 @@
 
 void LayoutSVGFilterPrimitive::StyleDidChange(StyleDifference diff,
                                               const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   if (!old_style)
     return;
   auto& element = To<SVGFilterPrimitiveStandardAttributes>(*GetNode());
@@ -81,6 +82,7 @@
 }
 
 void LayoutSVGFilterPrimitive::UpdateLayout() {
+  CheckIsNotDestroyed();
   ClearNeedsLayout();
 }
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.h b/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.h
index b0e16f4..534a8ca 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.h
@@ -39,23 +39,33 @@
 
  private:
   bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override {
+    CheckIsNotDestroyed();
     return false;
   }
 
   void StyleDidChange(StyleDifference, const ComputedStyle*) override;
   void UpdateLayout() override;
 
-  const char* GetName() const override { return "LayoutSVGFilterPrimitive"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGFilterPrimitive";
+  }
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVG ||
            type == kLayoutObjectSVGFilterPrimitive ||
            LayoutObject::IsOfType(type);
   }
-  FloatRect ObjectBoundingBox() const override { return FloatRect(); }
+  FloatRect ObjectBoundingBox() const override {
+    CheckIsNotDestroyed();
+    return FloatRect();
+  }
   FloatRect VisualRectInLocalSVGCoordinates() const override {
+    CheckIsNotDestroyed();
     return FloatRect();
   }
   FloatRect LocalBoundingBoxRectForAccessibility() const override {
+    CheckIsNotDestroyed();
     return FloatRect();
   }
 };
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
index 1cc2664..5f7a312 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.cc
@@ -39,16 +39,19 @@
 
 bool LayoutSVGForeignObject::IsChildAllowed(LayoutObject* child,
                                             const ComputedStyle& style) const {
+  CheckIsNotDestroyed();
   // Disallow arbitary SVG content. Only allow proper <svg xmlns="svgNS">
   // subdocuments.
   return !child->IsSVGChild();
 }
 
 void LayoutSVGForeignObject::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   SVGForeignObjectPainter(*this).Paint(paint_info);
 }
 
 void LayoutSVGForeignObject::UpdateLogicalWidth() {
+  CheckIsNotDestroyed();
   const ComputedStyle& style = StyleRef();
   float logical_width =
       style.IsHorizontalWritingMode() ? viewport_.Width() : viewport_.Height();
@@ -60,6 +63,7 @@
     LayoutUnit,
     LayoutUnit logical_top,
     LogicalExtentComputedValues& computed_values) const {
+  CheckIsNotDestroyed();
   const ComputedStyle& style = StyleRef();
   float logical_height =
       style.IsHorizontalWritingMode() ? viewport_.Height() : viewport_.Width();
@@ -69,6 +73,7 @@
 }
 
 AffineTransform LayoutSVGForeignObject::LocalToSVGParentTransform() const {
+  CheckIsNotDestroyed();
   // Include a zoom inverse in the local-to-parent transform since descendants
   // of the <foreignObject> will have regular zoom applied, and thus need to
   // have that removed when moving into the <fO> ancestors chain (the SVG root
@@ -79,6 +84,7 @@
 }
 
 void LayoutSVGForeignObject::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
 
   auto* foreign = To<SVGForeignObjectElement>(GetElement());
@@ -144,6 +150,7 @@
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& accumulated_offset,
     HitTestAction) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(accumulated_offset, PhysicalOffset());
   TransformedHitTestLocation local_location(hit_test_location,
                                             LocalToSVGParentTransform());
@@ -179,18 +186,21 @@
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& accumulated_offset,
     HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   // Skip LayoutSVGBlock's override.
   return LayoutBlockFlow::NodeAtPoint(result, hit_test_location,
                                       accumulated_offset, hit_test_action);
 }
 
 PaintLayerType LayoutSVGForeignObject::LayerTypeRequired() const {
+  CheckIsNotDestroyed();
   // Skip LayoutSVGBlock's override.
   return LayoutBlockFlow::LayerTypeRequired();
 }
 
 void LayoutSVGForeignObject::StyleDidChange(StyleDifference diff,
                                             const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutSVGBlock::StyleDidChange(diff, old_style);
 
   if (old_style && (SVGLayoutSupport::IsOverflowHidden(*old_style) !=
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h b/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h
index aa751ed..0d26b38 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h
@@ -55,7 +55,10 @@
   explicit LayoutSVGForeignObject(SVGForeignObjectElement*);
   ~LayoutSVGForeignObject() override;
 
-  const char* GetName() const override { return "LayoutSVGForeignObject"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGForeignObject";
+  }
 
   bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
 
@@ -63,12 +66,22 @@
 
   void UpdateLayout() override;
 
-  FloatRect ObjectBoundingBox() const override { return viewport_; }
-  FloatRect StrokeBoundingBox() const override { return ObjectBoundingBox(); }
+  FloatRect ObjectBoundingBox() const override {
+    CheckIsNotDestroyed();
+    return viewport_;
+  }
+  FloatRect StrokeBoundingBox() const override {
+    CheckIsNotDestroyed();
+    return ObjectBoundingBox();
+  }
   FloatRect VisualRectInLocalSVGCoordinates() const override {
+    CheckIsNotDestroyed();
     return FloatRect(FrameRect());
   }
-  bool IsObjectBoundingBoxValid() const { return !viewport_.IsEmpty(); }
+  bool IsObjectBoundingBoxValid() const {
+    CheckIsNotDestroyed();
+    return !viewport_.IsEmpty();
+  }
 
   bool NodeAtPoint(HitTestResult&,
                    const HitTestLocation&,
@@ -85,6 +98,7 @@
                           HitTestAction);
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVGForeignObject ||
            LayoutSVGBlock::IsOfType(type);
   }
@@ -92,6 +106,7 @@
   PaintLayerType LayerTypeRequired() const override;
 
   bool CreatesNewFormattingContext() const final {
+    CheckIsNotDestroyed();
     // This is the root of a foreign object. Don't let anything inside it escape
     // to our ancestors.
     return true;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.cc
index c2c57a7..dbc61af 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.cc
@@ -28,6 +28,7 @@
     : LayoutSVGContainer(element) {}
 
 void LayoutSVGHiddenContainer::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
 
@@ -47,6 +48,7 @@
                                            const HitTestLocation&,
                                            const PhysicalOffset&,
                                            HitTestAction) {
+  CheckIsNotDestroyed();
   return false;
 }
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h b/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h
index 06e9e782..c3c32c4f 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h
@@ -32,27 +32,35 @@
  public:
   explicit LayoutSVGHiddenContainer(SVGElement*);
 
-  const char* GetName() const override { return "LayoutSVGHiddenContainer"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGHiddenContainer";
+  }
 
  protected:
   void UpdateLayout() override;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVGHiddenContainer ||
            LayoutSVGContainer::IsOfType(type);
   }
 
  private:
   // LayoutSVGHiddenContainer paints nothing.
-  void Paint(const PaintInfo&) const final {}
+  void Paint(const PaintInfo&) const final { CheckIsNotDestroyed(); }
   PhysicalRect VisualRectInDocument(VisualRectFlags) const final {
+    CheckIsNotDestroyed();
     return PhysicalRect();
   }
   FloatRect VisualRectInLocalSVGCoordinates() const final {
+    CheckIsNotDestroyed();
     return FloatRect();
   }
   void AbsoluteQuads(Vector<FloatQuad>&,
-                     MapCoordinatesFlags mode = 0) const final {}
+                     MapCoordinatesFlags mode = 0) const final {
+    CheckIsNotDestroyed();
+  }
 
   bool NodeAtPoint(HitTestResult&,
                    const HitTestLocation&,
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 3367c8d..58bfbc5 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
@@ -61,12 +61,14 @@
 
 void LayoutSVGImage::StyleDidChange(StyleDifference diff,
                                     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   transform_uses_reference_box_ =
       TransformHelper::DependsOnReferenceBox(StyleRef());
   LayoutSVGModelObject::StyleDidChange(diff, old_style);
 }
 
 void LayoutSVGImage::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   image_resource_->Shutdown();
 
   LayoutSVGModelObject::WillBeDestroyed();
@@ -83,6 +85,7 @@
 }
 
 bool LayoutSVGImage::HasOverriddenIntrinsicSize() const {
+  CheckIsNotDestroyed();
   if (!RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled())
     return false;
   auto* svg_image_element = DynamicTo<SVGImageElement>(GetElement());
@@ -90,6 +93,7 @@
 }
 
 FloatSize LayoutSVGImage::CalculateObjectSize() const {
+  CheckIsNotDestroyed();
   FloatSize intrinsic_size;
   ImageResourceContent* cached_image = image_resource_->CachedImage();
   bool has_intrinsic_ratio = true;
@@ -134,6 +138,7 @@
 }
 
 bool LayoutSVGImage::UpdateBoundingBox() {
+  CheckIsNotDestroyed();
   FloatRect old_object_bounding_box = object_bounding_box_;
 
   SVGLengthContext length_context(GetElement());
@@ -155,6 +160,7 @@
 }
 
 void LayoutSVGImage::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
 
@@ -202,6 +208,7 @@
 }
 
 void LayoutSVGImage::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   SVGImagePainter(*this).Paint(paint_info);
 }
 
@@ -209,6 +216,7 @@
                                  const HitTestLocation& hit_test_location,
                                  const PhysicalOffset& accumulated_offset,
                                  HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(accumulated_offset, PhysicalOffset());
   // We only draw in the forground phase, so we only hit-test then.
   if (hit_test_action != kHitTestForeground)
@@ -242,6 +250,7 @@
 }
 
 void LayoutSVGImage::ImageChanged(WrappedImagePtr, CanDeferInvalidation defer) {
+  CheckIsNotDestroyed();
   // Notify parent resources that we've changed. This also invalidates
   // references from resources (filters) that may have a cached
   // representation of this image/layout object.
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 bc8b9227..0cbbbf9 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
@@ -36,32 +36,53 @@
   explicit LayoutSVGImage(SVGImageElement*);
   ~LayoutSVGImage() override;
 
-  void SetNeedsBoundariesUpdate() override { needs_boundaries_update_ = true; }
-  void SetNeedsTransformUpdate() override { needs_transform_update_ = true; }
+  void SetNeedsBoundariesUpdate() override {
+    CheckIsNotDestroyed();
+    needs_boundaries_update_ = true;
+  }
+  void SetNeedsTransformUpdate() override {
+    CheckIsNotDestroyed();
+    needs_transform_update_ = true;
+  }
 
-  LayoutImageResource* ImageResource() { return image_resource_.Get(); }
+  LayoutImageResource* ImageResource() {
+    CheckIsNotDestroyed();
+    return image_resource_.Get();
+  }
   const LayoutImageResource* ImageResource() const {
+    CheckIsNotDestroyed();
     return image_resource_.Get();
   }
 
-  FloatRect ObjectBoundingBox() const override { return object_bounding_box_; }
+  FloatRect ObjectBoundingBox() const override {
+    CheckIsNotDestroyed();
+    return object_bounding_box_;
+  }
   bool IsObjectBoundingBoxValid() const {
+    CheckIsNotDestroyed();
     return !object_bounding_box_.IsEmpty();
   }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVGImage ||
            LayoutSVGModelObject::IsOfType(type);
   }
 
-  const char* GetName() const override { return "LayoutSVGImage"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGImage";
+  }
 
  protected:
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
   void WillBeDestroyed() override;
 
  private:
-  FloatRect StrokeBoundingBox() const override { return object_bounding_box_; }
+  FloatRect StrokeBoundingBox() const override {
+    CheckIsNotDestroyed();
+    return object_bounding_box_;
+  }
 
   void ImageChanged(WrappedImagePtr, CanDeferInvalidation) override;
 
@@ -76,6 +97,7 @@
                    HitTestAction) override;
 
   AffineTransform LocalSVGTransform() const override {
+    CheckIsNotDestroyed();
     return local_transform_;
   }
 
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 0a1f4135..592713b 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
@@ -34,6 +34,7 @@
 
 bool LayoutSVGInline::IsChildAllowed(LayoutObject* child,
                                      const ComputedStyle& style) const {
+  CheckIsNotDestroyed();
   if (child->IsText())
     return SVGLayoutSupport::IsLayoutableTextNode(child);
 
@@ -55,12 +56,14 @@
 }
 
 InlineFlowBox* LayoutSVGInline::CreateInlineFlowBox() {
+  CheckIsNotDestroyed();
   InlineFlowBox* box = new SVGInlineFlowBox(LineLayoutItem(this));
   box->SetHasVirtualLogicalHeight();
   return box;
 }
 
 FloatRect LayoutSVGInline::ObjectBoundingBox() const {
+  CheckIsNotDestroyed();
   FloatRect bounds;
   for (InlineFlowBox* box : *LineBoxes())
     bounds.Unite(FloatRect(box->FrameRect()));
@@ -68,12 +71,14 @@
 }
 
 FloatRect LayoutSVGInline::StrokeBoundingBox() const {
+  CheckIsNotDestroyed();
   if (!FirstLineBox())
     return FloatRect();
   return SVGLayoutSupport::ExtendTextBBoxWithStroke(*this, ObjectBoundingBox());
 }
 
 FloatRect LayoutSVGInline::VisualRectInLocalSVGCoordinates() const {
+  CheckIsNotDestroyed();
   if (!FirstLineBox())
     return FloatRect();
   const LayoutSVGText* text_root =
@@ -86,24 +91,28 @@
 
 PhysicalRect LayoutSVGInline::VisualRectInDocument(
     VisualRectFlags flags) const {
+  CheckIsNotDestroyed();
   return SVGLayoutSupport::VisualRectInAncestorSpace(*this, *View(), flags);
 }
 
 void LayoutSVGInline::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                                          TransformState& transform_state,
                                          MapCoordinatesFlags flags) const {
+  CheckIsNotDestroyed();
   SVGLayoutSupport::MapLocalToAncestor(this, ancestor, transform_state, flags);
 }
 
 const LayoutObject* LayoutSVGInline::PushMappingToContainer(
     const LayoutBoxModelObject* ancestor_to_stop_at,
     LayoutGeometryMap& geometry_map) const {
+  CheckIsNotDestroyed();
   return SVGLayoutSupport::PushMappingToContainer(this, ancestor_to_stop_at,
                                                   geometry_map);
 }
 
 void LayoutSVGInline::AbsoluteQuads(Vector<FloatQuad>& quads,
                                     MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   for (InlineFlowBox* box : *LineBoxes()) {
     FloatRect box_rect(box->FrameRect());
     quads.push_back(LocalToAbsoluteQuad(
@@ -112,6 +121,7 @@
 }
 
 void LayoutSVGInline::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   SVGResourcesCache::ClientDestroyed(*this);
   SVGResources::ClearClipPathFilterMask(To<SVGElement>(*GetNode()), Style());
   SVGResources::ClearPaints(To<SVGElement>(*GetNode()), Style());
@@ -120,6 +130,7 @@
 
 void LayoutSVGInline::StyleDidChange(StyleDifference diff,
                                      const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   // Since layout depends on the bounds of the filter, we need to force layout
   // when the filter changes.
   if (diff.FilterChanged())
@@ -140,6 +151,7 @@
 
 void LayoutSVGInline::AddChild(LayoutObject* child,
                                LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   LayoutInline::AddChild(child, before_child);
   SVGResourcesCache::ClientWasAddedToTree(*child);
   LayoutSVGText::NotifySubtreeStructureChanged(
@@ -147,6 +159,7 @@
 }
 
 void LayoutSVGInline::RemoveChild(LayoutObject* child) {
+  CheckIsNotDestroyed();
   SVGResourcesCache::ClientWillBeRemovedFromTree(*child);
   LayoutSVGText::NotifySubtreeStructureChanged(
       this, layout_invalidation_reason::kChildChanged);
@@ -154,6 +167,7 @@
 }
 
 void LayoutSVGInline::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   LayoutInline::InsertedIntoTree();
   if (CompositingReasonFinder::DirectReasonsForSVGChildPaintProperties(*this) !=
       CompositingReason::kNone) {
@@ -162,6 +176,7 @@
 }
 
 void LayoutSVGInline::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   LayoutInline::WillBeRemovedFromTree();
   if (CompositingReasonFinder::DirectReasonsForSVGChildPaintProperties(*this) !=
       CompositingReason::kNone) {
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
index d4294b6..3a4858ae 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
@@ -29,9 +29,16 @@
  public:
   explicit LayoutSVGInline(Element*);
 
-  const char* GetName() const override { return "LayoutSVGInline"; }
-  PaintLayerType LayerTypeRequired() const final { return kNoPaintLayer; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGInline";
+  }
+  PaintLayerType LayerTypeRequired() const final {
+    CheckIsNotDestroyed();
+    return kNoPaintLayer;
+  }
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVG || type == kLayoutObjectSVGInline ||
            LayoutInline::IsOfType(type);
   }
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 4df02e4..f66316b4 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
@@ -57,6 +57,7 @@
       scaling_factor_(1) {}
 
 void LayoutSVGInlineText::TextDidChange() {
+  CheckIsNotDestroyed();
   SetTextInternal(NormalizeWhitespace(GetText().Impl()));
   LayoutText::TextDidChange();
   LayoutSVGText::NotifySubtreeStructureChanged(
@@ -65,6 +66,7 @@
 
 void LayoutSVGInlineText::StyleDidChange(StyleDifference diff,
                                          const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutText::StyleDidChange(diff, old_style);
   UpdateScaledFont();
 
@@ -89,6 +91,7 @@
 }
 
 InlineTextBox* LayoutSVGInlineText::CreateTextBox(int start, uint16_t length) {
+  CheckIsNotDestroyed();
   InlineTextBox* box =
       new SVGInlineTextBox(LineLayoutItem(this), start, length);
   box->SetHasVirtualLogicalHeight();
@@ -98,6 +101,7 @@
 LayoutRect LayoutSVGInlineText::LocalCaretRect(const InlineBox* box,
                                                int caret_offset,
                                                LayoutUnit*) const {
+  CheckIsNotDestroyed();
   if (!box || !box->IsInlineTextBox())
     return LayoutRect();
 
@@ -122,6 +126,7 @@
 }
 
 FloatRect LayoutSVGInlineText::FloatLinesBoundingBox() const {
+  CheckIsNotDestroyed();
   FloatRect bounding_box;
   for (InlineTextBox* box : TextBoxes())
     bounding_box.Unite(FloatRect(box->FrameRect()));
@@ -129,10 +134,12 @@
 }
 
 PhysicalRect LayoutSVGInlineText::PhysicalLinesBoundingBox() const {
+  CheckIsNotDestroyed();
   return PhysicalRect::EnclosingRect(FloatLinesBoundingBox());
 }
 
 bool LayoutSVGInlineText::CharacterStartsNewTextChunk(int position) const {
+  CheckIsNotDestroyed();
   DCHECK_GE(position, 0);
   DCHECK_LT(position, static_cast<int>(TextLength()));
 
@@ -151,6 +158,7 @@
 
 PositionWithAffinity LayoutSVGInlineText::PositionForPoint(
     const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   if (!HasInlineFragments() || !TextLength())
     return CreatePositionWithAffinity(0);
 
@@ -298,6 +306,7 @@
 void LayoutSVGInlineText::AddMetricsFromRun(
     const TextRun& run,
     bool& last_character_was_white_space) {
+  CheckIsNotDestroyed();
   Vector<CharacterRange> char_ranges =
       ScaledFont().IndividualCharacterRanges(run);
   SynthesizeGraphemeWidths(run, char_ranges);
@@ -337,6 +346,7 @@
 
 void LayoutSVGInlineText::UpdateMetricsList(
     bool& last_character_was_white_space) {
+  CheckIsNotDestroyed();
   metrics_.clear();
 
   if (!TextLength())
@@ -379,6 +389,7 @@
 }
 
 void LayoutSVGInlineText::UpdateScaledFont() {
+  CheckIsNotDestroyed();
   ComputeNewScaledFontForStyle(*this, scaling_factor_, scaled_font_);
 }
 
@@ -420,10 +431,12 @@
 
 PhysicalRect LayoutSVGInlineText::VisualRectInDocument(
     VisualRectFlags flags) const {
+  CheckIsNotDestroyed();
   return Parent()->VisualRectInDocument(flags);
 }
 
 FloatRect LayoutSVGInlineText::VisualRectInLocalSVGCoordinates() const {
+  CheckIsNotDestroyed();
   return Parent()->VisualRectInLocalSVGCoordinates();
 }
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h
index 20ca818..e0f2a08 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.h
@@ -34,15 +34,28 @@
   LayoutSVGInlineText(Node*, scoped_refptr<StringImpl>);
 
   bool CharacterStartsNewTextChunk(int position) const;
-  SVGCharacterDataMap& CharacterDataMap() { return character_data_map_; }
+  SVGCharacterDataMap& CharacterDataMap() {
+    CheckIsNotDestroyed();
+    return character_data_map_;
+  }
   const SVGCharacterDataMap& CharacterDataMap() const {
+    CheckIsNotDestroyed();
     return character_data_map_;
   }
 
-  const Vector<SVGTextMetrics>& MetricsList() const { return metrics_; }
+  const Vector<SVGTextMetrics>& MetricsList() const {
+    CheckIsNotDestroyed();
+    return metrics_;
+  }
 
-  float ScalingFactor() const { return scaling_factor_; }
-  const Font& ScaledFont() const { return scaled_font_; }
+  float ScalingFactor() const {
+    CheckIsNotDestroyed();
+    return scaling_factor_;
+  }
+  const Font& ScaledFont() const {
+    CheckIsNotDestroyed();
+    return scaled_font_;
+  }
   void UpdateScaledFont();
   void UpdateMetricsList(bool& last_character_was_white_space);
   static void ComputeNewScaledFontForStyle(const LayoutObject&,
@@ -53,7 +66,10 @@
   // round and does a better job than enclosingIntRect.
   FloatRect FloatLinesBoundingBox() const;
 
-  const char* GetName() const override { return "LayoutSVGInlineText"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGInlineText";
+  }
 
  private:
   void TextDidChange() override;
@@ -62,10 +78,12 @@
   void AddMetricsFromRun(const TextRun&, bool& last_character_was_white_space);
 
   FloatRect ObjectBoundingBox() const override {
+    CheckIsNotDestroyed();
     return FloatLinesBoundingBox();
   }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVG || type == kLayoutObjectSVGInlineText ||
            LayoutText::IsOfType(type);
   }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc
index d13473f7..9cfa1c37 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.cc
@@ -45,6 +45,7 @@
 
 bool LayoutSVGModelObject::IsChildAllowed(LayoutObject* child,
                                           const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   return child->IsSVG() && !(child->IsSVGInline() || child->IsSVGInlineText());
 }
 
@@ -52,11 +53,13 @@
     const LayoutBoxModelObject* ancestor,
     TransformState& transform_state,
     MapCoordinatesFlags flags) const {
+  CheckIsNotDestroyed();
   SVGLayoutSupport::MapLocalToAncestor(this, ancestor, transform_state, flags);
 }
 
 PhysicalRect LayoutSVGModelObject::VisualRectInDocument(
     VisualRectFlags flags) const {
+  CheckIsNotDestroyed();
   return SVGLayoutSupport::VisualRectInAncestorSpace(*this, *View(), flags);
 }
 
@@ -64,18 +67,21 @@
     const LayoutBoxModelObject* ancestor,
     TransformState& transform_state,
     MapCoordinatesFlags flags) const {
+  CheckIsNotDestroyed();
   SVGLayoutSupport::MapAncestorToLocal(*this, ancestor, transform_state, flags);
 }
 
 const LayoutObject* LayoutSVGModelObject::PushMappingToContainer(
     const LayoutBoxModelObject* ancestor_to_stop_at,
     LayoutGeometryMap& geometry_map) const {
+  CheckIsNotDestroyed();
   return SVGLayoutSupport::PushMappingToContainer(this, ancestor_to_stop_at,
                                                   geometry_map);
 }
 
 void LayoutSVGModelObject::AbsoluteQuads(Vector<FloatQuad>& quads,
                                          MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   quads.push_back(LocalToAbsoluteQuad(StrokeBoundingBox(), mode));
 }
 
@@ -84,21 +90,25 @@
 void LayoutSVGModelObject::AddOutlineRects(Vector<PhysicalRect>& rects,
                                            const PhysicalOffset&,
                                            NGOutlineType) const {
+  CheckIsNotDestroyed();
   rects.push_back(
       PhysicalRect::EnclosingRect(VisualRectInLocalSVGCoordinates()));
 }
 
 FloatRect LayoutSVGModelObject::LocalBoundingBoxRectForAccessibility() const {
+  CheckIsNotDestroyed();
   return StrokeBoundingBox();
 }
 
 void LayoutSVGModelObject::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   SVGResourcesCache::ClientDestroyed(*this);
   SVGResources::ClearClipPathFilterMask(*GetElement(), Style());
   LayoutObject::WillBeDestroyed();
 }
 
 AffineTransform LayoutSVGModelObject::CalculateLocalTransform() const {
+  CheckIsNotDestroyed();
   auto* element = GetElement();
   if (element->HasTransform(SVGElement::kIncludeMotionTransform))
     return element->CalculateTransform(SVGElement::kIncludeMotionTransform);
@@ -107,6 +117,7 @@
 
 bool LayoutSVGModelObject::CheckForImplicitTransformChange(
     bool bbox_changed) const {
+  CheckIsNotDestroyed();
   // If the transform is relative to the reference box, check relevant
   // conditions to see if we need to recompute the transform.
   switch (StyleRef().TransformBox()) {
@@ -121,6 +132,7 @@
 
 void LayoutSVGModelObject::StyleDidChange(StyleDifference diff,
                                           const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   // Since layout depends on the bounds of the filter, we need to force layout
   // when the filter changes. We also need to make sure paint will be
   // performed, since if the filter changed we will not have cached result from
@@ -158,6 +170,7 @@
 }
 
 void LayoutSVGModelObject::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   LayoutObject::InsertedIntoTree();
   if (CompositingReasonFinder::DirectReasonsForSVGChildPaintProperties(*this) !=
       CompositingReason::kNone) {
@@ -166,6 +179,7 @@
 }
 
 void LayoutSVGModelObject::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   LayoutObject::WillBeRemovedFromTree();
   if (CompositingReasonFinder::DirectReasonsForSVGChildPaintProperties(*this) !=
       CompositingReason::kNone) {
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h
index 4bf6cd8..941e5d40 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h
@@ -51,6 +51,7 @@
       VisualRectFlags = kDefaultVisualRectFlags) const override;
 
   FloatRect VisualRectInLocalSVGCoordinates() const override {
+    CheckIsNotDestroyed();
     return local_visual_rect_;
   }
 
@@ -70,10 +71,12 @@
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
 
   SVGElement* GetElement() const {
+    CheckIsNotDestroyed();
     return To<SVGElement>(LayoutObject::GetNode());
   }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVG || LayoutObject::IsOfType(type);
   }
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_path.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_path.cc
index 9f5bd0a..d152fd8 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_path.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_path.cc
@@ -42,27 +42,32 @@
 
 void LayoutSVGPath::StyleDidChange(StyleDifference diff,
                                    const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutSVGShape::StyleDidChange(diff, old_style);
   SVGResources::UpdateMarkers(*GetElement(), old_style, StyleRef());
 }
 
 void LayoutSVGPath::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   SVGResources::ClearMarkers(*GetElement(), Style());
   LayoutSVGShape::WillBeDestroyed();
 }
 
 void LayoutSVGPath::UpdateShapeFromElement() {
+  CheckIsNotDestroyed();
   LayoutSVGShape::UpdateShapeFromElement();
   UpdateMarkers();
 }
 
 const StylePath* LayoutSVGPath::GetStylePath() const {
+  CheckIsNotDestroyed();
   if (!IsA<SVGPathElement>(*GetElement()))
     return nullptr;
   return StyleRef().SvgStyle().D();
 }
 
 void LayoutSVGPath::UpdateMarkers() {
+  CheckIsNotDestroyed();
   marker_positions_.clear();
 
   if (!StyleRef().SvgStyle().HasMarkers() ||
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_path.h b/third_party/blink/renderer/core/layout/svg/layout_svg_path.h
index 97b0056..f3e1ac52 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_path.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_path.h
@@ -36,10 +36,14 @@
   ~LayoutSVGPath() override;
 
   const Vector<MarkerPosition>* MarkerPositions() const override {
+    CheckIsNotDestroyed();
     return &marker_positions_;
   }
 
-  const char* GetName() const override { return "LayoutSVGPath"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGPath";
+  }
 
  private:
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_rect.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_rect.cc
index 03650fc..7a0bf57 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_rect.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_rect.cc
@@ -39,6 +39,7 @@
 LayoutSVGRect::~LayoutSVGRect() = default;
 
 void LayoutSVGRect::UpdateShapeFromElement() {
+  CheckIsNotDestroyed();
   // Before creating a new object we need to clear the cached bounding box
   // to avoid using garbage.
   fill_bounding_box_ = FloatRect();
@@ -86,6 +87,7 @@
 
 bool LayoutSVGRect::ShapeDependentStrokeContains(
     const HitTestLocation& location) {
+  CheckIsNotDestroyed();
   // The optimized code below does not support the cases that we set
   // use_path_fallback_ in UpdateShapeFromElement().
   if (use_path_fallback_)
@@ -112,6 +114,7 @@
 
 bool LayoutSVGRect::ShapeDependentFillContains(const HitTestLocation& location,
                                                const WindRule fill_rule) const {
+  CheckIsNotDestroyed();
   if (use_path_fallback_)
     return LayoutSVGShape::ShapeDependentFillContains(location, fill_rule);
   const FloatPoint& point = location.TransformedPoint();
@@ -120,6 +123,7 @@
 
 // Returns true if the stroke is continuous and definitely uses miter joins.
 bool LayoutSVGRect::DefinitelyHasSimpleStroke() const {
+  CheckIsNotDestroyed();
   const SVGComputedStyle& svg_style = StyleRef().SvgStyle();
 
   // The four angles of a rect are 90 degrees. Using the formula at:
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_rect.h b/third_party/blink/renderer/core/layout/svg/layout_svg_rect.h
index 9dc9c764..30a18f5 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_rect.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_rect.h
@@ -38,14 +38,19 @@
   ~LayoutSVGRect() override;
 
   ShapeGeometryCodePath GeometryCodePath() const override {
+    CheckIsNotDestroyed();
     return use_path_fallback_ ? kPathGeometry : kRectGeometryFastPath;
   }
 
-  const char* GetName() const override { return "LayoutSVGRect"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGRect";
+  }
 
  private:
   void UpdateShapeFromElement() override;
   bool IsShapeEmpty() const override {
+    CheckIsNotDestroyed();
     return use_path_fallback_ ? LayoutSVGShape::IsShapeEmpty()
                               : fill_bounding_box_.IsEmpty();
   }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
index 898ca49..bcfa3c9 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
@@ -111,6 +111,7 @@
 LayoutSVGResourceClipper::~LayoutSVGResourceClipper() = default;
 
 void LayoutSVGResourceClipper::RemoveAllClientsFromCache() {
+  CheckIsNotDestroyed();
   clip_content_path_validity_ = kClipContentPathUnknown;
   clip_content_path_.Clear();
   cached_paint_record_.reset();
@@ -120,6 +121,7 @@
 }
 
 base::Optional<Path> LayoutSVGResourceClipper::AsPath() {
+  CheckIsNotDestroyed();
   if (clip_content_path_validity_ == kClipContentPathValid)
     return base::Optional<Path>(clip_content_path_);
   if (clip_content_path_validity_ == kClipContentPathInvalid)
@@ -170,6 +172,7 @@
 }
 
 sk_sp<const PaintRecord> LayoutSVGResourceClipper::CreatePaintRecord() {
+  CheckIsNotDestroyed();
   DCHECK(GetFrame());
   if (cached_paint_record_)
     return cached_paint_record_;
@@ -201,6 +204,7 @@
 }
 
 void LayoutSVGResourceClipper::CalculateLocalClipBounds() {
+  CheckIsNotDestroyed();
   // This is a rough heuristic to appraise the clip size and doesn't consider
   // clip on clip.
   for (const SVGElement& child_element :
@@ -214,6 +218,7 @@
 }
 
 SVGUnitTypes::SVGUnitType LayoutSVGResourceClipper::ClipPathUnits() const {
+  CheckIsNotDestroyed();
   return To<SVGClipPathElement>(GetElement())
       ->clipPathUnits()
       ->CurrentEnumValue();
@@ -221,6 +226,7 @@
 
 AffineTransform LayoutSVGResourceClipper::CalculateClipTransform(
     const FloatRect& reference_box) const {
+  CheckIsNotDestroyed();
   AffineTransform transform =
       To<SVGClipPathElement>(GetElement())
           ->CalculateTransform(SVGElement::kIncludeMotionTransform);
@@ -234,6 +240,7 @@
 bool LayoutSVGResourceClipper::HitTestClipContent(
     const FloatRect& object_bounding_box,
     const HitTestLocation& location) const {
+  CheckIsNotDestroyed();
   if (!SVGLayoutSupport::IntersectsClipPath(*this, object_bounding_box,
                                             location))
     return false;
@@ -262,6 +269,7 @@
 
 FloatRect LayoutSVGResourceClipper::ResourceBoundingBox(
     const FloatRect& reference_box) {
+  CheckIsNotDestroyed();
   // The resource has not been layouted yet. Return the reference box.
   if (SelfNeedsLayout())
     return reference_box;
@@ -274,6 +282,7 @@
 
 void LayoutSVGResourceClipper::StyleDidChange(StyleDifference diff,
                                               const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutSVGResourceContainer::StyleDidChange(diff, old_style);
   if (diff.TransformChanged()) {
     MarkAllClientsForInvalidation(SVGResourceClient::kBoundariesInvalidation |
@@ -282,6 +291,7 @@
 }
 
 void LayoutSVGResourceClipper::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   MarkAllClientsForInvalidation(SVGResourceClient::kBoundariesInvalidation |
                                 SVGResourceClient::kPaintInvalidation);
   LayoutSVGResourceContainer::WillBeDestroyed();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h
index 661f7b0..aeebef2 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h
@@ -34,14 +34,20 @@
   explicit LayoutSVGResourceClipper(SVGClipPathElement*);
   ~LayoutSVGResourceClipper() override;
 
-  const char* GetName() const override { return "LayoutSVGResourceClipper"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGResourceClipper";
+  }
 
   void RemoveAllClientsFromCache() override;
 
   FloatRect ResourceBoundingBox(const FloatRect& reference_box);
 
   static const LayoutSVGResourceType kResourceType = kClipperResourceType;
-  LayoutSVGResourceType ResourceType() const override { return kResourceType; }
+  LayoutSVGResourceType ResourceType() const override {
+    CheckIsNotDestroyed();
+    return kResourceType;
+  }
 
   bool HitTestClipContent(const FloatRect&, const HitTestLocation&) const;
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc
index 3f449e5..1c1715ed 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc
@@ -49,6 +49,7 @@
 LayoutSVGResourceContainer::~LayoutSVGResourceContainer() = default;
 
 void LayoutSVGResourceContainer::UpdateLayout() {
+  CheckIsNotDestroyed();
   // FIXME: Investigate a way to detect and break resource layout dependency
   // cycles early. Then we can remove this method altogether, and fall back onto
   // LayoutSVGHiddenContainer::layout().
@@ -64,6 +65,7 @@
 }
 
 void LayoutSVGResourceContainer::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   LayoutSVGHiddenContainer::WillBeDestroyed();
   // The resource is being torn down.
   // TODO(fs): Remove this when SVGResources is gone.
@@ -74,6 +76,7 @@
 void LayoutSVGResourceContainer::StyleDidChange(
     StyleDifference diff,
     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutSVGHiddenContainer::StyleDidChange(diff, old_style);
   // The resource has been attached. Notify any pending clients that
   // they can now try to add themselves as clients to the resource.
@@ -86,6 +89,7 @@
 
 bool LayoutSVGResourceContainer::FindCycle(
     SVGResourcesCycleSolver& solver) const {
+  CheckIsNotDestroyed();
   if (solver.IsKnownAcyclic(this))
     return false;
   SVGResourcesCycleSolver::Scope scope(solver);
@@ -116,6 +120,7 @@
 
 bool LayoutSVGResourceContainer::FindCycleFromSelf(
     SVGResourcesCycleSolver& solver) const {
+  CheckIsNotDestroyed();
   return FindCycleInSubtree(solver, *this);
 }
 
@@ -147,6 +152,7 @@
 
 void LayoutSVGResourceContainer::MarkAllClientsForInvalidation(
     InvalidationModeMask invalidation_mask) {
+  CheckIsNotDestroyed();
   if (is_invalidating_)
     return;
   LocalSVGResource* resource = ResourceForContainer(*this);
@@ -190,6 +196,7 @@
 void LayoutSVGResourceContainer::InvalidateCacheAndMarkForLayout(
     LayoutInvalidationReasonForTracing reason,
     SubtreeLayoutScope* layout_scope) {
+  CheckIsNotDestroyed();
   if (SelfNeedsLayout())
     return;
 
@@ -202,6 +209,7 @@
 
 void LayoutSVGResourceContainer::InvalidateCacheAndMarkForLayout(
     SubtreeLayoutScope* layout_scope) {
+  CheckIsNotDestroyed();
   InvalidateCacheAndMarkForLayout(
       layout_invalidation_reason::kSvgResourceInvalidated, layout_scope);
 }
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h
index 6874d6e..f0a1d75 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h
@@ -47,10 +47,14 @@
   virtual void RemoveAllClientsFromCache() = 0;
 
   // Remove any cached data for the |client|, and return true if so.
-  virtual bool RemoveClientFromCache(SVGResourceClient&) { return false; }
+  virtual bool RemoveClientFromCache(SVGResourceClient&) {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   void UpdateLayout() override;
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVGResourceContainer ||
            LayoutSVGHiddenContainer::IsOfType(type);
   }
@@ -58,6 +62,7 @@
   virtual LayoutSVGResourceType ResourceType() const = 0;
 
   bool IsSVGPaintServer() const {
+    CheckIsNotDestroyed();
     LayoutSVGResourceType resource_type = ResourceType();
     return resource_type == kPatternResourceType ||
            resource_type == kLinearGradientResourceType ||
@@ -75,7 +80,10 @@
       bool needs_layout = true);
   static void MarkClientForInvalidation(LayoutObject&, InvalidationModeMask);
 
-  void ClearInvalidationMask() { completed_invalidations_mask_ = 0; }
+  void ClearInvalidationMask() {
+    CheckIsNotDestroyed();
+    completed_invalidations_mask_ = 0;
+  }
 
  protected:
   // Used from RemoveAllClientsFromCache methods.
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc
index 7f0bfa6..9a52c5a 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc
@@ -38,26 +38,31 @@
 
 bool LayoutSVGResourceFilter::IsChildAllowed(LayoutObject* child,
                                              const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   return child->IsSVGFilterPrimitive();
 }
 
 void LayoutSVGResourceFilter::RemoveAllClientsFromCache() {
+  CheckIsNotDestroyed();
   MarkAllClientsForInvalidation(SVGResourceClient::kLayoutInvalidation |
                                 SVGResourceClient::kBoundariesInvalidation);
 }
 
 FloatRect LayoutSVGResourceFilter::ResourceBoundingBox(
     const FloatRect& reference_box) const {
+  CheckIsNotDestroyed();
   const auto* filter_element = To<SVGFilterElement>(GetElement());
   return SVGLengthContext::ResolveRectangle(filter_element, FilterUnits(),
                                             reference_box);
 }
 
 SVGUnitTypes::SVGUnitType LayoutSVGResourceFilter::FilterUnits() const {
+  CheckIsNotDestroyed();
   return To<SVGFilterElement>(GetElement())->filterUnits()->CurrentEnumValue();
 }
 
 SVGUnitTypes::SVGUnitType LayoutSVGResourceFilter::PrimitiveUnits() const {
+  CheckIsNotDestroyed();
   return To<SVGFilterElement>(GetElement())
       ->primitiveUnits()
       ->CurrentEnumValue();
@@ -65,6 +70,7 @@
 
 bool LayoutSVGResourceFilter::FindCycleFromSelf(
     SVGResourcesCycleSolver& solver) const {
+  CheckIsNotDestroyed();
   // Traverse and check all <feImage> 'href' element references.
   for (auto& feimage_element :
        Traversal<SVGFEImageElement>::ChildrenOf(*GetElement())) {
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h
index 467c193..8ba1fffe 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h
@@ -38,7 +38,10 @@
 
   bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
 
-  const char* GetName() const override { return "LayoutSVGResourceFilter"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGResourceFilter";
+  }
 
   void RemoveAllClientsFromCache() override;
 
@@ -48,7 +51,10 @@
   SVGUnitTypes::SVGUnitType PrimitiveUnits() const;
 
   static const LayoutSVGResourceType kResourceType = kFilterResourceType;
-  LayoutSVGResourceType ResourceType() const override { return kResourceType; }
+  LayoutSVGResourceType ResourceType() const override {
+    CheckIsNotDestroyed();
+    return kResourceType;
+  }
 
  private:
   bool FindCycleFromSelf(SVGResourcesCycleSolver&) const override;
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 24613470..6356b6b 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,6 +42,7 @@
       gradient_map_(MakeGarbageCollected<GradientMap>()) {}
 
 void LayoutSVGResourceGradient::RemoveAllClientsFromCache() {
+  CheckIsNotDestroyed();
   gradient_map_->clear();
   should_collect_gradient_attributes_ = true;
   To<SVGGradientElement>(*GetElement()).InvalidateDependentGradients();
@@ -50,6 +51,7 @@
 
 bool LayoutSVGResourceGradient::RemoveClientFromCache(
     SVGResourceClient& client) {
+  CheckIsNotDestroyed();
   auto entry = gradient_map_->find(&client);
   if (entry == gradient_map_->end())
     return false;
@@ -59,6 +61,7 @@
 
 std::unique_ptr<GradientData> LayoutSVGResourceGradient::BuildGradientData(
     const FloatRect& object_bounding_box) {
+  CheckIsNotDestroyed();
   // Create gradient object
   auto gradient_data = std::make_unique<GradientData>();
 
@@ -97,6 +100,7 @@
 SVGPaintServer LayoutSVGResourceGradient::PreparePaintServer(
     const SVGResourceClient& client,
     const FloatRect& object_bounding_box) {
+  CheckIsNotDestroyed();
   ClearInvalidationMask();
 
   std::unique_ptr<GradientData>& gradient_data =
@@ -113,6 +117,7 @@
 
 bool LayoutSVGResourceGradient::IsChildAllowed(LayoutObject* child,
                                                const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   if (!child->IsSVGResourceContainer())
     return false;
 
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 8d88444..7fc7f91e 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
@@ -34,6 +34,7 @@
 LayoutSVGResourceLinearGradient::~LayoutSVGResourceLinearGradient() = default;
 
 void LayoutSVGResourceLinearGradient::CollectGradientAttributes() {
+  CheckIsNotDestroyed();
   DCHECK(GetElement());
   attributes_wrapper_->Set(LinearGradientAttributes());
   To<SVGLinearGradientElement>(GetElement())
@@ -42,6 +43,7 @@
 
 FloatPoint LayoutSVGResourceLinearGradient::StartPoint(
     const LinearGradientAttributes& attributes) const {
+  CheckIsNotDestroyed();
   return SVGLengthContext::ResolvePoint(GetElement(),
                                         attributes.GradientUnits(),
                                         *attributes.X1(), *attributes.Y1());
@@ -49,12 +51,14 @@
 
 FloatPoint LayoutSVGResourceLinearGradient::EndPoint(
     const LinearGradientAttributes& attributes) const {
+  CheckIsNotDestroyed();
   return SVGLengthContext::ResolvePoint(GetElement(),
                                         attributes.GradientUnits(),
                                         *attributes.X2(), *attributes.Y2());
 }
 
 scoped_refptr<Gradient> LayoutSVGResourceLinearGradient::BuildGradient() const {
+  CheckIsNotDestroyed();
   const LinearGradientAttributes& attributes = Attributes();
   scoped_refptr<Gradient> gradient = Gradient::CreateLinear(
       StartPoint(attributes), EndPoint(attributes),
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 48c43d5..fbb05e4 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
@@ -34,17 +34,23 @@
   ~LayoutSVGResourceLinearGradient() override;
 
   const char* GetName() const override {
+    CheckIsNotDestroyed();
     return "LayoutSVGResourceLinearGradient";
   }
 
   static const LayoutSVGResourceType kResourceType =
       kLinearGradientResourceType;
-  LayoutSVGResourceType ResourceType() const override { return kResourceType; }
+  LayoutSVGResourceType ResourceType() const override {
+    CheckIsNotDestroyed();
+    return kResourceType;
+  }
 
   SVGUnitTypes::SVGUnitType GradientUnits() const override {
+    CheckIsNotDestroyed();
     return Attributes().GradientUnits();
   }
   AffineTransform CalculateGradientTransform() const override {
+    CheckIsNotDestroyed();
     return Attributes().GradientTransform();
   }
   void CollectGradientAttributes() override;
@@ -57,9 +63,11 @@
   Persistent<LinearGradientAttributesWrapper> attributes_wrapper_;
 
   LinearGradientAttributes& MutableAttributes() {
+    CheckIsNotDestroyed();
     return attributes_wrapper_->Attributes();
   }
   const LinearGradientAttributes& Attributes() const {
+    CheckIsNotDestroyed();
     return attributes_wrapper_->Attributes();
   }
 };
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.cc
index 21a99db..05a00ab 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.cc
@@ -36,6 +36,7 @@
 LayoutSVGResourceMarker::~LayoutSVGResourceMarker() = default;
 
 void LayoutSVGResourceMarker::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   if (is_in_layout_)
     return;
@@ -51,12 +52,14 @@
 }
 
 void LayoutSVGResourceMarker::RemoveAllClientsFromCache() {
+  CheckIsNotDestroyed();
   MarkAllClientsForInvalidation(SVGResourceClient::kLayoutInvalidation |
                                 SVGResourceClient::kBoundariesInvalidation);
 }
 
 FloatRect LayoutSVGResourceMarker::MarkerBoundaries(
     const AffineTransform& marker_transformation) const {
+  CheckIsNotDestroyed();
   FloatRect coordinates = LayoutSVGContainer::VisualRectInLocalSVGCoordinates();
 
   // Map visual rect into parent coordinate space, in which the marker
@@ -67,6 +70,7 @@
 }
 
 FloatPoint LayoutSVGResourceMarker::ReferencePoint() const {
+  CheckIsNotDestroyed();
   auto* marker = To<SVGMarkerElement>(GetElement());
   DCHECK(marker);
 
@@ -76,6 +80,7 @@
 }
 
 float LayoutSVGResourceMarker::Angle() const {
+  CheckIsNotDestroyed();
   return To<SVGMarkerElement>(GetElement())
       ->orientAngle()
       ->CurrentValue()
@@ -83,16 +88,19 @@
 }
 
 SVGMarkerUnitsType LayoutSVGResourceMarker::MarkerUnits() const {
+  CheckIsNotDestroyed();
   return To<SVGMarkerElement>(GetElement())->markerUnits()->CurrentEnumValue();
 }
 
 SVGMarkerOrientType LayoutSVGResourceMarker::OrientType() const {
+  CheckIsNotDestroyed();
   return To<SVGMarkerElement>(GetElement())->orientType()->CurrentEnumValue();
 }
 
 AffineTransform LayoutSVGResourceMarker::MarkerTransformation(
     const MarkerPosition& position,
     float stroke_width) const {
+  CheckIsNotDestroyed();
   // Apply scaling according to markerUnits ('strokeWidth' or 'userSpaceOnUse'.)
   float marker_scale =
       MarkerUnits() == kSVGMarkerUnitsStrokeWidth ? stroke_width : 1;
@@ -120,6 +128,7 @@
 }
 
 bool LayoutSVGResourceMarker::ShouldPaint() const {
+  CheckIsNotDestroyed();
   // An empty viewBox disables rendering.
   auto* marker = To<SVGMarkerElement>(GetElement());
   DCHECK(marker);
@@ -129,6 +138,7 @@
 }
 
 void LayoutSVGResourceMarker::SetNeedsTransformUpdate() {
+  CheckIsNotDestroyed();
   // The transform paint property relies on the SVG transform being up-to-date
   // (see: PaintPropertyTreeBuilder::updateTransformForNonRootSVG).
   SetNeedsPaintPropertyUpdate();
@@ -137,6 +147,7 @@
 
 SVGTransformChange LayoutSVGResourceMarker::CalculateLocalTransform(
     bool bounds_changed) {
+  CheckIsNotDestroyed();
   if (!needs_transform_update_)
     return SVGTransformChange::kNone;
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h
index eadd407e..05e4c56 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h
@@ -33,7 +33,10 @@
   explicit LayoutSVGResourceMarker(SVGMarkerElement*);
   ~LayoutSVGResourceMarker() override;
 
-  const char* GetName() const override { return "LayoutSVGResourceMarker"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGResourceMarker";
+  }
 
   void RemoveAllClientsFromCache() override;
 
@@ -45,13 +48,17 @@
                                        float stroke_width) const;
 
   AffineTransform LocalToSVGParentTransform() const final {
+    CheckIsNotDestroyed();
     return local_to_parent_transform_;
   }
   void SetNeedsTransformUpdate() final;
 
   // The viewport origin is (0,0) and not the reference point because each
   // marker instance includes the reference in markerTransformation().
-  FloatRect Viewport() const { return FloatRect(FloatPoint(), viewport_size_); }
+  FloatRect Viewport() const {
+    CheckIsNotDestroyed();
+    return FloatRect(FloatPoint(), viewport_size_);
+  }
 
   bool ShouldPaint() const;
 
@@ -61,7 +68,10 @@
   SVGMarkerOrientType OrientType() const;
 
   static const LayoutSVGResourceType kResourceType = kMarkerResourceType;
-  LayoutSVGResourceType ResourceType() const override { return kResourceType; }
+  LayoutSVGResourceType ResourceType() const override {
+    CheckIsNotDestroyed();
+    return kResourceType;
+  }
 
  private:
   void UpdateLayout() override;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
index 6e2b4b2..24daeec 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
@@ -39,6 +39,7 @@
 LayoutSVGResourceMasker::~LayoutSVGResourceMasker() = default;
 
 void LayoutSVGResourceMasker::RemoveAllClientsFromCache() {
+  CheckIsNotDestroyed();
   cached_paint_record_.reset();
   mask_content_boundaries_ = FloatRect();
   MarkAllClientsForInvalidation(SVGResourceClient::kLayoutInvalidation |
@@ -48,6 +49,7 @@
 sk_sp<const PaintRecord> LayoutSVGResourceMasker::CreatePaintRecord(
     const AffineTransform& content_transformation,
     GraphicsContext& context) {
+  CheckIsNotDestroyed();
   if (cached_paint_record_)
     return cached_paint_record_;
 
@@ -74,6 +76,7 @@
 }
 
 void LayoutSVGResourceMasker::CalculateMaskContentVisualRect() {
+  CheckIsNotDestroyed();
   for (const SVGElement& child_element :
        Traversal<SVGElement>::ChildrenOf(*GetElement())) {
     const LayoutObject* layout_object = child_element.GetLayoutObject();
@@ -87,10 +90,12 @@
 }
 
 SVGUnitTypes::SVGUnitType LayoutSVGResourceMasker::MaskUnits() const {
+  CheckIsNotDestroyed();
   return To<SVGMaskElement>(GetElement())->maskUnits()->CurrentEnumValue();
 }
 
 SVGUnitTypes::SVGUnitType LayoutSVGResourceMasker::MaskContentUnits() const {
+  CheckIsNotDestroyed();
   return To<SVGMaskElement>(GetElement())
       ->maskContentUnits()
       ->CurrentEnumValue();
@@ -99,6 +104,7 @@
 FloatRect LayoutSVGResourceMasker::ResourceBoundingBox(
     const FloatRect& reference_box,
     float reference_box_zoom) {
+  CheckIsNotDestroyed();
   auto* mask_element = To<SVGMaskElement>(GetElement());
   DCHECK(mask_element);
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h
index fe02ae0..3f7ec68 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h
@@ -36,7 +36,10 @@
   explicit LayoutSVGResourceMasker(SVGMaskElement*);
   ~LayoutSVGResourceMasker() override;
 
-  const char* GetName() const override { return "LayoutSVGResourceMasker"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGResourceMasker";
+  }
 
   void RemoveAllClientsFromCache() override;
 
@@ -47,7 +50,10 @@
   SVGUnitTypes::SVGUnitType MaskContentUnits() const;
 
   static const LayoutSVGResourceType kResourceType = kMaskerResourceType;
-  LayoutSVGResourceType ResourceType() const override { return kResourceType; }
+  LayoutSVGResourceType ResourceType() const override {
+    CheckIsNotDestroyed();
+    return kResourceType;
+  }
 
   sk_sp<const PaintRecord> CreatePaintRecord(const AffineTransform&,
                                              GraphicsContext&);
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 6944d12..5b1d2f107 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
@@ -53,6 +53,7 @@
       pattern_map_(MakeGarbageCollected<PatternMap>()) {}
 
 void LayoutSVGResourcePattern::RemoveAllClientsFromCache() {
+  CheckIsNotDestroyed();
   pattern_map_->clear();
   should_collect_pattern_attributes_ = true;
   MarkAllClientsForInvalidation(SVGResourceClient::kPaintInvalidation);
@@ -60,6 +61,7 @@
 
 bool LayoutSVGResourcePattern::RemoveClientFromCache(
     SVGResourceClient& client) {
+  CheckIsNotDestroyed();
   auto entry = pattern_map_->find(&client);
   if (entry == pattern_map_->end())
     return false;
@@ -69,6 +71,7 @@
 
 std::unique_ptr<PatternData> LayoutSVGResourcePattern::BuildPatternData(
     const FloatRect& object_bounding_box) {
+  CheckIsNotDestroyed();
   auto pattern_data = std::make_unique<PatternData>();
 
   DCHECK(GetElement());
@@ -135,6 +138,7 @@
 SVGPaintServer LayoutSVGResourcePattern::PreparePaintServer(
     const SVGResourceClient& client,
     const FloatRect& object_bounding_box) {
+  CheckIsNotDestroyed();
   ClearInvalidationMask();
 
   std::unique_ptr<PatternData>& pattern_data =
@@ -150,6 +154,7 @@
 
 const LayoutSVGResourceContainer*
 LayoutSVGResourcePattern::ResolveContentElement() const {
+  CheckIsNotDestroyed();
   DCHECK(Attributes().PatternContentElement());
   LayoutSVGResourceContainer* expected_layout_object =
       ToLayoutSVGResourceContainer(
@@ -179,6 +184,7 @@
 sk_sp<PaintRecord> LayoutSVGResourcePattern::AsPaintRecord(
     const FloatSize& size,
     const AffineTransform& tile_transform) const {
+  CheckIsNotDestroyed();
   DCHECK(!should_collect_pattern_attributes_);
 
   AffineTransform content_transform;
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 4630fee..dd40d55 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
@@ -39,7 +39,10 @@
  public:
   explicit LayoutSVGResourcePattern(SVGPatternElement*);
 
-  const char* GetName() const override { return "LayoutSVGResourcePattern"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGResourcePattern";
+  }
 
   void RemoveAllClientsFromCache() override;
   bool RemoveClientFromCache(SVGResourceClient&) override;
@@ -49,7 +52,10 @@
       const FloatRect& object_bounding_box) override;
 
   static const LayoutSVGResourceType kResourceType = kPatternResourceType;
-  LayoutSVGResourceType ResourceType() const override { return kResourceType; }
+  LayoutSVGResourceType ResourceType() const override {
+    CheckIsNotDestroyed();
+    return kResourceType;
+  }
 
  private:
   std::unique_ptr<PatternData> BuildPatternData(
@@ -63,9 +69,11 @@
   Persistent<PatternAttributesWrapper> attributes_wrapper_;
 
   PatternAttributes& MutableAttributes() {
+    CheckIsNotDestroyed();
     return attributes_wrapper_->Attributes();
   }
   const PatternAttributes& Attributes() const {
+    CheckIsNotDestroyed();
     return attributes_wrapper_->Attributes();
   }
 
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 bf85cc0..67e7b67 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
@@ -35,6 +35,7 @@
 LayoutSVGResourceRadialGradient::~LayoutSVGResourceRadialGradient() = default;
 
 void LayoutSVGResourceRadialGradient::CollectGradientAttributes() {
+  CheckIsNotDestroyed();
   DCHECK(GetElement());
   attributes_wrapper_->Set(RadialGradientAttributes());
   To<SVGRadialGradientElement>(GetElement())
@@ -43,6 +44,7 @@
 
 FloatPoint LayoutSVGResourceRadialGradient::CenterPoint(
     const RadialGradientAttributes& attributes) const {
+  CheckIsNotDestroyed();
   return SVGLengthContext::ResolvePoint(GetElement(),
                                         attributes.GradientUnits(),
                                         *attributes.Cx(), *attributes.Cy());
@@ -50,6 +52,7 @@
 
 FloatPoint LayoutSVGResourceRadialGradient::FocalPoint(
     const RadialGradientAttributes& attributes) const {
+  CheckIsNotDestroyed();
   return SVGLengthContext::ResolvePoint(GetElement(),
                                         attributes.GradientUnits(),
                                         *attributes.Fx(), *attributes.Fy());
@@ -57,17 +60,20 @@
 
 float LayoutSVGResourceRadialGradient::Radius(
     const RadialGradientAttributes& attributes) const {
+  CheckIsNotDestroyed();
   return SVGLengthContext::ResolveLength(
       GetElement(), attributes.GradientUnits(), *attributes.R());
 }
 
 float LayoutSVGResourceRadialGradient::FocalRadius(
     const RadialGradientAttributes& attributes) const {
+  CheckIsNotDestroyed();
   return SVGLengthContext::ResolveLength(
       GetElement(), attributes.GradientUnits(), *attributes.Fr());
 }
 
 scoped_refptr<Gradient> LayoutSVGResourceRadialGradient::BuildGradient() const {
+  CheckIsNotDestroyed();
   const RadialGradientAttributes& attributes = Attributes();
   scoped_refptr<Gradient> gradient = Gradient::CreateRadial(
       FocalPoint(attributes), FocalRadius(attributes), CenterPoint(attributes),
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 4177123..44394005 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
@@ -34,17 +34,23 @@
   ~LayoutSVGResourceRadialGradient() override;
 
   const char* GetName() const override {
+    CheckIsNotDestroyed();
     return "LayoutSVGResourceRadialGradient";
   }
 
   static const LayoutSVGResourceType kResourceType =
       kRadialGradientResourceType;
-  LayoutSVGResourceType ResourceType() const override { return kResourceType; }
+  LayoutSVGResourceType ResourceType() const override {
+    CheckIsNotDestroyed();
+    return kResourceType;
+  }
 
   SVGUnitTypes::SVGUnitType GradientUnits() const override {
+    CheckIsNotDestroyed();
     return Attributes().GradientUnits();
   }
   AffineTransform CalculateGradientTransform() const override {
+    CheckIsNotDestroyed();
     return Attributes().GradientTransform();
   }
   void CollectGradientAttributes() override;
@@ -59,9 +65,11 @@
   Persistent<RadialGradientAttributesWrapper> attributes_wrapper_;
 
   RadialGradientAttributes& MutableAttributes() {
+    CheckIsNotDestroyed();
     return attributes_wrapper_->Attributes();
   }
   const RadialGradientAttributes& Attributes() const {
+    CheckIsNotDestroyed();
     return attributes_wrapper_->Attributes();
   }
 };
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 fadff84..9abe8334 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
@@ -76,6 +76,7 @@
 
 void LayoutSVGRoot::UnscaledIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  CheckIsNotDestroyed();
   // https://www.w3.org/TR/SVG/coords.html#IntrinsicSizing
 
   auto* svg = To<SVGSVGElement>(GetNode());
@@ -105,6 +106,7 @@
 
 void LayoutSVGRoot::ComputeIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  CheckIsNotDestroyed();
   DCHECK(!ShouldApplySizeContainment());
   UnscaledIntrinsicSizingInfo(intrinsic_sizing_info);
 
@@ -112,10 +114,12 @@
 }
 
 bool LayoutSVGRoot::IsEmbeddedThroughSVGImage() const {
+  CheckIsNotDestroyed();
   return SVGImage::IsInSVGImage(To<SVGSVGElement>(GetNode()));
 }
 
 bool LayoutSVGRoot::IsEmbeddedThroughFrameContainingSVGDocument() const {
+  CheckIsNotDestroyed();
   if (!GetNode())
     return false;
 
@@ -135,6 +139,7 @@
 
 LayoutUnit LayoutSVGRoot::ComputeReplacedLogicalWidth(
     ShouldComputePreferred should_compute_preferred) const {
+  CheckIsNotDestroyed();
   // When we're embedded through SVGImage
   // (border-image/background-image/<html:img>/...) we're forced to resize to a
   // specific size.
@@ -153,6 +158,7 @@
 
 LayoutUnit LayoutSVGRoot::ComputeReplacedLogicalHeight(
     LayoutUnit estimated_used_width) const {
+  CheckIsNotDestroyed();
   // When we're embedded through SVGImage
   // (border-image/background-image/<html:img>/...) we're forced to resize to a
   // specific size.
@@ -176,6 +182,7 @@
 }
 
 double LayoutSVGRoot::LogicalSizeScaleFactorForPercentageLengths() const {
+  CheckIsNotDestroyed();
   if (!IsDocumentElement() || !GetDocument().IsInMainFrame())
     return 1;
   if (GetDocument().GetLayoutView()->ShouldUsePrintingLayout())
@@ -189,6 +196,7 @@
 }
 
 void LayoutSVGRoot::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
 
@@ -271,6 +279,7 @@
 }
 
 bool LayoutSVGRoot::ShouldApplyViewportClip() const {
+  CheckIsNotDestroyed();
   // the outermost svg is clipped if auto, and svg document roots are always
   // clipped. When the svg is stand-alone (isDocumentElement() == true) the
   // viewport clipping should always be applied, noting that the window
@@ -281,6 +290,7 @@
 }
 
 void LayoutSVGRoot::RecalcVisualOverflow() {
+  CheckIsNotDestroyed();
   LayoutReplaced::RecalcVisualOverflow();
   UpdateCachedBoundaries();
   if (!ShouldApplyViewportClip())
@@ -288,6 +298,7 @@
 }
 
 LayoutRect LayoutSVGRoot::ComputeContentsVisualOverflow() const {
+  CheckIsNotDestroyed();
   FloatRect content_visual_rect = VisualRectInLocalSVGCoordinates();
   content_visual_rect =
       local_to_border_box_transform_.MapRect(content_visual_rect);
@@ -302,18 +313,21 @@
 
 void LayoutSVGRoot::PaintReplaced(const PaintInfo& paint_info,
                                   const PhysicalOffset& paint_offset) const {
+  CheckIsNotDestroyed();
   if (ChildPaintBlockedByDisplayLock())
     return;
   SVGRootPainter(*this).PaintReplaced(paint_info, paint_offset);
 }
 
 void LayoutSVGRoot::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   SVGResourcesCache::ClientDestroyed(*this);
   SVGResources::ClearClipPathFilterMask(To<SVGSVGElement>(*GetNode()), Style());
   LayoutReplaced::WillBeDestroyed();
 }
 
 bool LayoutSVGRoot::IntrinsicSizeIsFontMetricsDependent() const {
+  CheckIsNotDestroyed();
   const auto& svg = To<SVGSVGElement>(*GetNode());
   return svg.width()->CurrentValue()->IsFontRelative() ||
          svg.height()->CurrentValue()->IsFontRelative();
@@ -321,6 +335,7 @@
 
 bool LayoutSVGRoot::StyleChangeAffectsIntrinsicSize(
     const ComputedStyle& old_style) const {
+  CheckIsNotDestroyed();
   const ComputedStyle& style = StyleRef();
   // If the writing mode changed from a horizontal mode to a vertical
   // mode, or vice versa, then our intrinsic dimensions will have
@@ -337,6 +352,7 @@
 }
 
 void LayoutSVGRoot::IntrinsicSizingInfoChanged() {
+  CheckIsNotDestroyed();
   SetIntrinsicLogicalWidthsDirty();
 
   // TODO(fs): Merge with IntrinsicSizeChanged()? (from LayoutReplaced)
@@ -350,6 +366,7 @@
 
 void LayoutSVGRoot::StyleDidChange(StyleDifference diff,
                                    const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   if (diff.NeedsFullLayout())
     SetNeedsBoundariesUpdate();
   if (diff.NeedsPaintInvalidation()) {
@@ -368,10 +385,12 @@
 
 bool LayoutSVGRoot::IsChildAllowed(LayoutObject* child,
                                    const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   return child->IsSVG() && !(child->IsSVGInline() || child->IsSVGInlineText());
 }
 
 void LayoutSVGRoot::AddChild(LayoutObject* child, LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   LayoutReplaced::AddChild(child, before_child);
   SVGResourcesCache::ClientWasAddedToTree(*child);
 
@@ -383,6 +402,7 @@
 }
 
 void LayoutSVGRoot::RemoveChild(LayoutObject* child) {
+  CheckIsNotDestroyed();
   SVGResourcesCache::ClientWillBeRemovedFromTree(*child);
   LayoutReplaced::RemoveChild(child);
 
@@ -394,6 +414,7 @@
 }
 
 bool LayoutSVGRoot::HasNonIsolatedBlendingDescendants() const {
+  CheckIsNotDestroyed();
   if (has_non_isolated_blending_descendants_dirty_) {
     has_non_isolated_blending_descendants_ =
         SVGLayoutSupport::ComputeHasNonIsolatedBlendingDescendants(this);
@@ -404,6 +425,7 @@
 
 void LayoutSVGRoot::DescendantIsolationRequirementsChanged(
     DescendantIsolationState state) {
+  CheckIsNotDestroyed();
   switch (state) {
     case kDescendantIsolationRequired:
       has_non_isolated_blending_descendants_ = true;
@@ -419,17 +441,20 @@
 }
 
 void LayoutSVGRoot::InsertedIntoTree() {
+  CheckIsNotDestroyed();
   LayoutReplaced::InsertedIntoTree();
   SVGResourcesCache::ClientWasAddedToTree(*this);
 }
 
 void LayoutSVGRoot::WillBeRemovedFromTree() {
+  CheckIsNotDestroyed();
   SVGResourcesCache::ClientWillBeRemovedFromTree(*this);
   LayoutReplaced::WillBeRemovedFromTree();
 }
 
 PositionWithAffinity LayoutSVGRoot::PositionForPoint(
     const PhysicalOffset& point) const {
+  CheckIsNotDestroyed();
   FloatPoint absolute_point = FloatPoint(point);
   absolute_point =
       local_to_border_box_transform_.Inverse().MapPoint(absolute_point);
@@ -459,6 +484,7 @@
 // LayoutBox methods will expect coordinates w/o any transforms in coordinates
 // relative to our borderBox origin.  This method gives us exactly that.
 SVGTransformChange LayoutSVGRoot::BuildLocalToBorderBoxTransform() {
+  CheckIsNotDestroyed();
   SVGTransformChangeDetector change_detector(local_to_border_box_transform_);
   auto* svg = To<SVGSVGElement>(GetNode());
   DCHECK(svg);
@@ -478,6 +504,7 @@
 }
 
 AffineTransform LayoutSVGRoot::LocalToSVGParentTransform() const {
+  CheckIsNotDestroyed();
   return AffineTransform::Translation(RoundToInt(Location().X()),
                                       RoundToInt(Location().Y())) *
          local_to_border_box_transform_;
@@ -490,17 +517,20 @@
 void LayoutSVGRoot::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                                        TransformState& transform_state,
                                        MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   LayoutReplaced::MapLocalToAncestor(ancestor, transform_state, mode);
 }
 
 const LayoutObject* LayoutSVGRoot::PushMappingToContainer(
     const LayoutBoxModelObject* ancestor_to_stop_at,
     LayoutGeometryMap& geometry_map) const {
+  CheckIsNotDestroyed();
   return LayoutReplaced::PushMappingToContainer(ancestor_to_stop_at,
                                                 geometry_map);
 }
 
 void LayoutSVGRoot::UpdateCachedBoundaries() {
+  CheckIsNotDestroyed();
   SVGLayoutSupport::ComputeContainerBoundingBoxes(
       this, object_bounding_box_, object_bounding_box_valid_,
       stroke_bounding_box_, visual_rect_in_local_svg_coordinates_);
@@ -510,6 +540,7 @@
                                 const HitTestLocation& hit_test_location,
                                 const PhysicalOffset& accumulated_offset,
                                 HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   HitTestLocation local_border_box_location(hit_test_location,
                                             -accumulated_offset);
 
@@ -559,6 +590,7 @@
 }
 
 void LayoutSVGRoot::NotifyDescendantCompositingReasonsChanged() {
+  CheckIsNotDestroyed();
   if (has_descendant_with_compositing_reason_dirty_)
     return;
   has_descendant_with_compositing_reason_dirty_ = true;
@@ -566,6 +598,7 @@
 }
 
 PaintLayerType LayoutSVGRoot::LayerTypeRequired() const {
+  CheckIsNotDestroyed();
   auto layer_type_required = LayoutReplaced::LayerTypeRequired();
   if (layer_type_required == kNoPaintLayer) {
     // Force a paint layer so,
@@ -579,6 +612,7 @@
 }
 
 CompositingReasons LayoutSVGRoot::AdditionalCompositingReasons() const {
+  CheckIsNotDestroyed();
   return RuntimeEnabledFeatures::CompositeSVGEnabled() &&
                  HasDescendantWithCompositingReason()
              ? CompositingReason::kSVGRoot
@@ -586,6 +620,7 @@
 }
 
 bool LayoutSVGRoot::HasDescendantWithCompositingReason() const {
+  CheckIsNotDestroyed();
   if (has_descendant_with_compositing_reason_dirty_) {
     has_descendant_with_compositing_reason_ = false;
     for (const LayoutObject* object = FirstChild(); object;
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 14e07d5..9c3f15a 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
@@ -46,27 +46,39 @@
   void SlowLastChild() const = delete;
 
   LayoutObject* FirstChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->FirstChild();
   }
   LayoutObject* LastChild() const {
+    CheckIsNotDestroyed();
     DCHECK_EQ(Children(), VirtualChildren());
     return Children()->LastChild();
   }
 
-  bool IsLayoutSizeChanged() const { return is_layout_size_changed_; }
+  bool IsLayoutSizeChanged() const {
+    CheckIsNotDestroyed();
+    return is_layout_size_changed_;
+  }
   bool DidScreenScaleFactorChange() const {
+    CheckIsNotDestroyed();
     return did_screen_scale_factor_change_;
   }
   void SetNeedsBoundariesUpdate() override {
+    CheckIsNotDestroyed();
     needs_boundaries_or_transform_update_ = true;
   }
   void SetNeedsTransformUpdate() override {
+    CheckIsNotDestroyed();
     needs_boundaries_or_transform_update_ = true;
   }
 
-  LayoutSize ContainerSize() const { return container_size_; }
+  LayoutSize ContainerSize() const {
+    CheckIsNotDestroyed();
+    return container_size_;
+  }
   void SetContainerSize(const LayoutSize& container_size) {
+    CheckIsNotDestroyed();
     // SVGImage::draw() does a view layout prior to painting,
     // and we need that layout to know of the new size otherwise
     // the layout may be incorrectly using the old size.
@@ -80,6 +92,7 @@
   // localToBorderBoxTransform maps local SVG viewport coordinates to local CSS
   // box coordinates.
   const AffineTransform& LocalToBorderBoxTransform() const {
+    CheckIsNotDestroyed();
     return local_to_border_box_transform_;
   }
 
@@ -90,27 +103,43 @@
   bool HasNonIsolatedBlendingDescendants() const final;
 
   bool HasDescendantCompositingReasons() const {
+    CheckIsNotDestroyed();
     return AdditionalCompositingReasons() != CompositingReason::kNone;
   }
   void NotifyDescendantCompositingReasonsChanged();
 
-  const char* GetName() const override { return "LayoutSVGRoot"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGRoot";
+  }
 
  private:
   bool ComputeShouldClipOverflow() const override {
+    CheckIsNotDestroyed();
     return LayoutBox::ComputeShouldClipOverflow() || ShouldApplyViewportClip();
   }
   LayoutRect ComputeContentsVisualOverflow() const;
 
-  const LayoutObjectChildList* Children() const { return &children_; }
-  LayoutObjectChildList* Children() { return &children_; }
+  const LayoutObjectChildList* Children() const {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
+  LayoutObjectChildList* Children() {
+    CheckIsNotDestroyed();
+    return &children_;
+  }
 
-  LayoutObjectChildList* VirtualChildren() override { return Children(); }
+  LayoutObjectChildList* VirtualChildren() override {
+    CheckIsNotDestroyed();
+    return Children();
+  }
   const LayoutObjectChildList* VirtualChildren() const override {
+    CheckIsNotDestroyed();
     return Children();
   }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVG || type == kLayoutObjectSVGRoot ||
            LayoutReplaced::IsOfType(type);
   }
@@ -136,9 +165,16 @@
 
   AffineTransform LocalToSVGParentTransform() const override;
 
-  FloatRect ObjectBoundingBox() const override { return object_bounding_box_; }
-  FloatRect StrokeBoundingBox() const override { return stroke_bounding_box_; }
+  FloatRect ObjectBoundingBox() const override {
+    CheckIsNotDestroyed();
+    return object_bounding_box_;
+  }
+  FloatRect StrokeBoundingBox() const override {
+    CheckIsNotDestroyed();
+    return stroke_bounding_box_;
+  }
   FloatRect VisualRectInLocalSVGCoordinates() const override {
+    CheckIsNotDestroyed();
     return visual_rect_in_local_svg_coordinates_;
   }
 
@@ -154,7 +190,10 @@
       const LayoutBoxModelObject* ancestor_to_stop_at,
       LayoutGeometryMap&) const override;
 
-  bool CanHaveChildren() const override { return true; }
+  bool CanHaveChildren() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
 
   void DescendantIsolationRequirementsChanged(DescendantIsolationState) final;
 
@@ -171,7 +210,10 @@
   double LogicalSizeScaleFactorForPercentageLengths() const;
 
   PaintLayerType LayerTypeRequired() const override;
-  bool CanHaveAdditionalCompositingReasons() const override { return true; }
+  bool CanHaveAdditionalCompositingReasons() const override {
+    CheckIsNotDestroyed();
+    return true;
+  }
   CompositingReasons AdditionalCompositingReasons() const override;
   bool HasDescendantWithCompositingReason() const;
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc
index f42c103..094c4cb 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc
@@ -65,6 +65,7 @@
 
 void LayoutSVGShape::StyleDidChange(StyleDifference diff,
                                     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   transform_uses_reference_box_ =
       TransformHelper::DependsOnReferenceBox(StyleRef());
   LayoutSVGModelObject::StyleDidChange(diff, old_style);
@@ -85,16 +86,19 @@
 }
 
 void LayoutSVGShape::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   SVGResources::ClearPaints(*GetElement(), Style());
   LayoutSVGModelObject::WillBeDestroyed();
 }
 
 void LayoutSVGShape::ClearPath() {
+  CheckIsNotDestroyed();
   path_.reset();
   stroke_path_cache_.reset();
 }
 
 void LayoutSVGShape::CreatePath() {
+  CheckIsNotDestroyed();
   if (!path_)
     path_ = std::make_unique<Path>();
   *path_ = To<SVGGeometryElement>(GetElement())->AsPath();
@@ -106,12 +110,14 @@
 }
 
 float LayoutSVGShape::DashScaleFactor() const {
+  CheckIsNotDestroyed();
   if (StyleRef().SvgStyle().StrokeDashArray()->data.IsEmpty())
     return 1;
   return To<SVGGeometryElement>(*GetElement()).PathLengthScaleFactor();
 }
 
 void LayoutSVGShape::UpdateShapeFromElement() {
+  CheckIsNotDestroyed();
   CreatePath();
   fill_bounding_box_ = GetPath().BoundingRect();
 
@@ -138,6 +144,7 @@
 
 FloatRect LayoutSVGShape::ApproximateStrokeBoundingBox(
     const FloatRect& shape_bounds) const {
+  CheckIsNotDestroyed();
   FloatRect stroke_box = shape_bounds;
 
   // Implementation of
@@ -166,6 +173,7 @@
 }
 
 FloatRect LayoutSVGShape::HitTestStrokeBoundingBox() const {
+  CheckIsNotDestroyed();
   if (StyleRef().SvgStyle().HasStroke())
     return stroke_bounding_box_;
   return ApproximateStrokeBoundingBox(fill_bounding_box_);
@@ -173,6 +181,7 @@
 
 bool LayoutSVGShape::ShapeDependentStrokeContains(
     const HitTestLocation& location) {
+  CheckIsNotDestroyed();
   if (!stroke_path_cache_) {
     // In case the subclass didn't create path during UpdateShapeFromElement()
     // for optimization but still calls this method.
@@ -212,12 +221,14 @@
 bool LayoutSVGShape::ShapeDependentFillContains(
     const HitTestLocation& location,
     const WindRule fill_rule) const {
+  CheckIsNotDestroyed();
   return GetPath().Contains(location.TransformedPoint(), fill_rule);
 }
 
 bool LayoutSVGShape::FillContains(const HitTestLocation& location,
                                   bool requires_fill,
                                   const WindRule fill_rule) {
+  CheckIsNotDestroyed();
   if (!fill_bounding_box_.Contains(location.TransformedPoint()))
     return false;
 
@@ -230,6 +241,7 @@
 
 bool LayoutSVGShape::StrokeContains(const HitTestLocation& location,
                                     bool requires_stroke) {
+  CheckIsNotDestroyed();
   // "A zero value causes no stroke to be painted."
   if (StyleRef().SvgStyle().StrokeWidth().IsZero())
     return false;
@@ -250,6 +262,7 @@
 }
 
 void LayoutSVGShape::UpdateLayout() {
+  CheckIsNotDestroyed();
   LayoutAnalyzer::Scope analyzer(*this);
 
   // Invalidate all resources of this client if our layout changed.
@@ -308,6 +321,7 @@
 }
 
 AffineTransform LayoutSVGShape::ComputeRootTransform() const {
+  CheckIsNotDestroyed();
   const LayoutObject* root = this;
   while (root && !root->IsSVGRoot())
     root = root->Parent();
@@ -315,6 +329,7 @@
 }
 
 AffineTransform LayoutSVGShape::ComputeNonScalingStrokeTransform() const {
+  CheckIsNotDestroyed();
   // Compute the CTM to the SVG root. This should probably be the CTM all the
   // way to the "canvas" of the page ("host" coordinate system), but with our
   // current approach of applying/painting non-scaling-stroke, that can break in
@@ -332,6 +347,7 @@
 }
 
 void LayoutSVGShape::UpdateNonScalingStrokeData() {
+  CheckIsNotDestroyed();
   DCHECK(HasNonScalingStroke());
 
   const AffineTransform transform = ComputeNonScalingStrokeTransform();
@@ -346,6 +362,7 @@
 }
 
 void LayoutSVGShape::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   SVGShapePainter(*this).Paint(paint_info);
 }
 
@@ -353,6 +370,7 @@
                                  const HitTestLocation& hit_test_location,
                                  const PhysicalOffset& accumulated_offset,
                                  HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(accumulated_offset, PhysicalOffset());
   // We only draw in the foreground phase, so we only hit-test then.
   if (hit_test_action != kHitTestForeground)
@@ -388,6 +406,7 @@
 bool LayoutSVGShape::HitTestShape(const HitTestRequest& request,
                                   const HitTestLocation& local_location,
                                   PointerEventsHitRules hit_rules) {
+  CheckIsNotDestroyed();
   if (hit_rules.can_hit_bounding_box &&
       local_location.Intersects(ObjectBoundingBox()))
     return true;
@@ -409,6 +428,7 @@
 }
 
 FloatRect LayoutSVGShape::CalculateStrokeBoundingBox() const {
+  CheckIsNotDestroyed();
   if (!StyleRef().SvgStyle().HasStroke() || IsShapeEmpty())
     return fill_bounding_box_;
   if (HasNonScalingStroke())
@@ -417,6 +437,7 @@
 }
 
 FloatRect LayoutSVGShape::CalculateNonScalingStrokeBoundingBox() const {
+  CheckIsNotDestroyed();
   DCHECK(path_);
   DCHECK(StyleRef().SvgStyle().HasStroke());
   DCHECK(HasNonScalingStroke());
@@ -435,11 +456,13 @@
 }
 
 float LayoutSVGShape::StrokeWidth() const {
+  CheckIsNotDestroyed();
   SVGLengthContext length_context(GetElement());
   return length_context.ValueForLength(StyleRef().SvgStyle().StrokeWidth());
 }
 
 float LayoutSVGShape::StrokeWidthForMarkerUnits() const {
+  CheckIsNotDestroyed();
   float stroke_width = StrokeWidth();
   if (HasNonScalingStroke()) {
     const auto& non_scaling_transform = NonScalingStrokeTransform();
@@ -455,12 +478,14 @@
 }
 
 LayoutSVGShapeRareData& LayoutSVGShape::EnsureRareData() const {
+  CheckIsNotDestroyed();
   if (!rare_data_)
     rare_data_ = std::make_unique<LayoutSVGShapeRareData>();
   return *rare_data_.get();
 }
 
 RasterEffectOutset LayoutSVGShape::VisualRectOutsetForRasterEffects() const {
+  CheckIsNotDestroyed();
   // Account for raster expansions due to SVG stroke hairline raster effects.
   if (StyleRef().SvgStyle().HasVisibleStroke()) {
     if (StyleRef().SvgStyle().CapStyle() != kButtCap)
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h b/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h
index db4452a..fed395c 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h
@@ -59,15 +59,28 @@
  public:
   ~LayoutSVGShape() override;
 
-  void SetNeedsShapeUpdate() { needs_shape_update_ = true; }
-  void SetNeedsBoundariesUpdate() final { needs_boundaries_update_ = true; }
-  void SetNeedsTransformUpdate() final { needs_transform_update_ = true; }
+  void SetNeedsShapeUpdate() {
+    CheckIsNotDestroyed();
+    needs_shape_update_ = true;
+  }
+  void SetNeedsBoundariesUpdate() final {
+    CheckIsNotDestroyed();
+    needs_boundaries_update_ = true;
+  }
+  void SetNeedsTransformUpdate() final {
+    CheckIsNotDestroyed();
+    needs_transform_update_ = true;
+  }
 
   Path& GetPath() const {
+    CheckIsNotDestroyed();
     DCHECK(path_);
     return *path_;
   }
-  bool HasPath() const { return path_.get(); }
+  bool HasPath() const {
+    CheckIsNotDestroyed();
+    return path_.get();
+  }
   float DashScaleFactor() const;
 
   // This method is sometimes (rarely) called with a null path and crashes. The
@@ -75,19 +88,23 @@
   // path but somehow that fails. The assert and check for hasPath() are
   // intended to detect and prevent crashes.
   virtual bool IsShapeEmpty() const {
+    CheckIsNotDestroyed();
     DCHECK(path_);
     return !HasPath() || GetPath().IsEmpty();
   }
 
   bool HasNonScalingStroke() const {
+    CheckIsNotDestroyed();
     return StyleRef().SvgStyle().VectorEffect() == VE_NON_SCALING_STROKE;
   }
   const Path& NonScalingStrokePath() const {
+    CheckIsNotDestroyed();
     DCHECK(HasNonScalingStroke());
     DCHECK(rare_data_);
     return rare_data_->non_scaling_stroke_path_;
   }
   const AffineTransform& NonScalingStrokeTransform() const {
+    CheckIsNotDestroyed();
     DCHECK(HasNonScalingStroke());
     DCHECK(rare_data_);
     return rare_data_->non_scaling_stroke_transform_;
@@ -95,9 +112,13 @@
 
   AffineTransform ComputeRootTransform() const;
   AffineTransform ComputeNonScalingStrokeTransform() const;
-  AffineTransform LocalSVGTransform() const final { return local_transform_; }
+  AffineTransform LocalSVGTransform() const final {
+    CheckIsNotDestroyed();
+    return local_transform_;
+  }
 
   virtual const Vector<MarkerPosition>* MarkerPositions() const {
+    CheckIsNotDestroyed();
     return nullptr;
   }
 
@@ -105,12 +126,19 @@
   float StrokeWidthForMarkerUnits() const;
 
   virtual ShapeGeometryCodePath GeometryCodePath() const {
+    CheckIsNotDestroyed();
     return kPathGeometry;
   }
 
-  FloatRect ObjectBoundingBox() const final { return fill_bounding_box_; }
+  FloatRect ObjectBoundingBox() const final {
+    CheckIsNotDestroyed();
+    return fill_bounding_box_;
+  }
 
-  const char* GetName() const override { return "LayoutSVGShape"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGShape";
+  }
 
  protected:
   // Description of the geometry of the shape for stroking.
@@ -155,6 +183,7 @@
   bool StrokeContains(const HitTestLocation&, bool requires_stroke = true);
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVGShape ||
            LayoutSVGModelObject::IsOfType(type);
   }
@@ -169,7 +198,10 @@
                     const HitTestLocation&,
                     PointerEventsHitRules);
 
-  FloatRect StrokeBoundingBox() const final { return stroke_bounding_box_; }
+  FloatRect StrokeBoundingBox() const final {
+    CheckIsNotDestroyed();
+    return stroke_bounding_box_;
+  }
 
   // Calculates an inclusive bounding box of this shape as if this shape has a
   // stroke. If this shape has a stroke, then |stroke_bounding_box_| is
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 9c995b69..61fdd32 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
@@ -75,11 +75,13 @@
 
 void LayoutSVGText::StyleDidChange(StyleDifference diff,
                                    const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutSVGBlock::StyleDidChange(diff, old_style);
   SVGResources::UpdatePaints(*GetElement(), old_style, StyleRef());
 }
 
 void LayoutSVGText::WillBeDestroyed() {
+  CheckIsNotDestroyed();
   descendant_text_nodes_.clear();
   SVGResources::ClearPaints(*GetElement(), Style());
   LayoutSVGBlock::WillBeDestroyed();
@@ -87,6 +89,7 @@
 
 bool LayoutSVGText::IsChildAllowed(LayoutObject* child,
                                    const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   return child->IsSVGInline() ||
          (child->IsText() && SVGLayoutSupport::IsLayoutableTextNode(child));
 }
@@ -112,6 +115,7 @@
 
 void LayoutSVGText::SubtreeStructureChanged(
     LayoutInvalidationReasonForTracing reason) {
+  CheckIsNotDestroyed();
   if (BeingDestroyed() || !EverHadLayout()) {
     DCHECK(descendant_text_nodes_.IsEmpty());
     return;
@@ -159,6 +163,7 @@
 }
 
 void LayoutSVGText::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
   // This flag is set and reset as needed only within this function.
   DCHECK(!needs_reordering_);
@@ -274,6 +279,7 @@
 }
 
 void LayoutSVGText::RecalcVisualOverflow() {
+  CheckIsNotDestroyed();
   ClearVisualOverflow();
   LayoutObject::RecalcVisualOverflow();
   AddSelfVisualOverflow(LayoutRect(ObjectBoundingBox()));
@@ -281,6 +287,7 @@
 }
 
 RootInlineBox* LayoutSVGText::CreateRootInlineBox() {
+  CheckIsNotDestroyed();
   RootInlineBox* box = new SVGRootInlineBox(LineLayoutItem(this));
   box->SetHasVirtualLogicalHeight();
   return box;
@@ -290,6 +297,7 @@
                                 const HitTestLocation& hit_test_location,
                                 const PhysicalOffset& accumulated_offset,
                                 HitTestAction hit_test_action) {
+  CheckIsNotDestroyed();
   DCHECK_EQ(accumulated_offset, PhysicalOffset());
   // We only draw in the foreground phase, so we only hit-test then.
   if (hit_test_action != kHitTestForeground)
@@ -323,6 +331,7 @@
 
 PositionWithAffinity LayoutSVGText::PositionForPoint(
     const PhysicalOffset& point_in_contents) const {
+  CheckIsNotDestroyed();
   RootInlineBox* root_box = FirstRootBox();
   if (!root_box)
     return CreatePositionWithAffinity(0);
@@ -347,26 +356,31 @@
 
 void LayoutSVGText::AbsoluteQuads(Vector<FloatQuad>& quads,
                                   MapCoordinatesFlags mode) const {
+  CheckIsNotDestroyed();
   quads.push_back(LocalToAbsoluteQuad(StrokeBoundingBox(), mode));
 }
 
 void LayoutSVGText::Paint(const PaintInfo& paint_info) const {
+  CheckIsNotDestroyed();
   SVGTextPainter(*this).Paint(paint_info);
 }
 
 FloatRect LayoutSVGText::ObjectBoundingBox() const {
+  CheckIsNotDestroyed();
   if (const RootInlineBox* box = FirstRootBox())
     return FloatRect(box->FrameRect());
   return FloatRect();
 }
 
 FloatRect LayoutSVGText::StrokeBoundingBox() const {
+  CheckIsNotDestroyed();
   if (!FirstRootBox())
     return FloatRect();
   return SVGLayoutSupport::ExtendTextBBoxWithStroke(*this, ObjectBoundingBox());
 }
 
 FloatRect LayoutSVGText::VisualRectInLocalSVGCoordinates() const {
+  CheckIsNotDestroyed();
   if (!FirstRootBox())
     return FloatRect();
   const FloatRect object_bounds = ObjectBoundingBox();
@@ -377,15 +391,18 @@
 void LayoutSVGText::AddOutlineRects(Vector<PhysicalRect>& rects,
                                     const PhysicalOffset&,
                                     NGOutlineType) const {
+  CheckIsNotDestroyed();
   rects.push_back(PhysicalRect::EnclosingRect(ObjectBoundingBox()));
 }
 
 bool LayoutSVGText::IsObjectBoundingBoxValid() const {
+  CheckIsNotDestroyed();
   // If we don't have any line boxes, then consider the bbox invalid.
   return FirstLineBox();
 }
 
 void LayoutSVGText::AddChild(LayoutObject* child, LayoutObject* before_child) {
+  CheckIsNotDestroyed();
   LayoutSVGBlock::AddChild(child, before_child);
 
   SVGResourcesCache::ClientWasAddedToTree(*child);
@@ -393,6 +410,7 @@
 }
 
 void LayoutSVGText::RemoveChild(LayoutObject* child) {
+  CheckIsNotDestroyed();
   SVGResourcesCache::ClientWillBeRemovedFromTree(*child);
   SubtreeStructureChanged(layout_invalidation_reason::kChildChanged);
 
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 b0478f6..087fdd634 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
@@ -37,9 +37,13 @@
   bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
 
   void SetNeedsPositioningValuesUpdate() {
+    CheckIsNotDestroyed();
     needs_positioning_values_update_ = true;
   }
-  void SetNeedsTextMetricsUpdate() { needs_text_metrics_update_ = true; }
+  void SetNeedsTextMetricsUpdate() {
+    CheckIsNotDestroyed();
+    needs_text_metrics_update_ = true;
+  }
   FloatRect VisualRectInLocalSVGCoordinates() const override;
   FloatRect ObjectBoundingBox() const override;
   FloatRect StrokeBoundingBox() const override;
@@ -55,19 +59,30 @@
   static void NotifySubtreeStructureChanged(LayoutObject*,
                                             LayoutInvalidationReasonForTracing);
 
-  bool NeedsReordering() const { return needs_reordering_; }
+  bool NeedsReordering() const {
+    CheckIsNotDestroyed();
+    return needs_reordering_;
+  }
   const Vector<LayoutSVGInlineText*>& DescendantTextNodes() const {
+    CheckIsNotDestroyed();
     return descendant_text_nodes_;
   }
 
   void RecalcVisualOverflow() override;
 
-  const char* GetName() const override { return "LayoutSVGText"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGText";
+  }
 
  private:
-  bool AllowsNonVisibleOverflow() const override { return false; }
+  bool AllowsNonVisibleOverflow() const override {
+    CheckIsNotDestroyed();
+    return false;
+  }
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVGText || LayoutSVGBlock::IsOfType(type);
   }
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.cc
index d3035ebf..6ab1238f 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.cc
@@ -54,6 +54,7 @@
 
 bool LayoutSVGTextPath::IsChildAllowed(LayoutObject* child,
                                        const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   if (child->IsText())
     return SVGLayoutSupport::IsLayoutableTextNode(child);
 
@@ -61,6 +62,7 @@
 }
 
 std::unique_ptr<PathPositionMapper> LayoutSVGTextPath::LayoutPath() const {
+  CheckIsNotDestroyed();
   const auto& text_path_element = To<SVGTextPathElement>(*GetNode());
   Element* target_element = SVGURIReference::TargetElementFromIRIString(
       text_path_element.HrefString(), text_path_element.OriginatingTreeScope());
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.h b/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.h
index 92ccd99..523981a1 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.h
@@ -63,10 +63,14 @@
   bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVGTextPath || LayoutSVGInline::IsOfType(type);
   }
 
-  const char* GetName() const override { return "LayoutSVGTextPath"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGTextPath";
+  }
 };
 
 DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSVGTextPath, IsSVGTextPath());
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc
index 5ea8c6cc..254ec7d 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.cc
@@ -48,6 +48,7 @@
 bool LayoutSVGTransformableContainer::IsChildAllowed(
     LayoutObject* child,
     const ComputedStyle& style) const {
+  CheckIsNotDestroyed();
   DCHECK(GetElement());
   Node* child_node = child->GetNode();
   if (IsA<SVGSwitchElement>(*GetElement())) {
@@ -72,6 +73,7 @@
 }
 
 void LayoutSVGTransformableContainer::SetNeedsTransformUpdate() {
+  CheckIsNotDestroyed();
   // The transform paint property relies on the SVG transform being up-to-date
   // (see: PaintPropertyTreeBuilder::updateTransformForNonRootSVG).
   SetNeedsPaintPropertyUpdate();
@@ -79,6 +81,7 @@
 }
 
 bool LayoutSVGTransformableContainer::IsUseElement() const {
+  CheckIsNotDestroyed();
   const SVGElement& element = *GetElement();
   if (IsA<SVGUseElement>(element))
     return true;
@@ -90,6 +93,7 @@
 
 SVGTransformChange LayoutSVGTransformableContainer::CalculateLocalTransform(
     bool bounds_changed) {
+  CheckIsNotDestroyed();
   SVGElement* element = GetElement();
   DCHECK(element);
 
@@ -129,6 +133,7 @@
 void LayoutSVGTransformableContainer::StyleDidChange(
     StyleDifference diff,
     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   transform_uses_reference_box_ =
       TransformHelper::DependsOnReferenceBox(StyleRef());
   LayoutSVGContainer::StyleDidChange(diff, old_style);
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.h b/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.h
index 347cf8b..f20099c 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.h
@@ -34,10 +34,12 @@
   bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
 
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVGTransformableContainer ||
            LayoutSVGContainer::IsOfType(type);
   }
   const FloatSize& AdditionalTranslation() const {
+    CheckIsNotDestroyed();
     return additional_translation_;
   }
 
@@ -47,6 +49,7 @@
   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
   SVGTransformChange CalculateLocalTransform(bool bounds_changed) override;
   AffineTransform LocalSVGTransform() const override {
+    CheckIsNotDestroyed();
     return local_transform_;
   }
   bool IsUseElement() const;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_tspan.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_tspan.cc
index c05deb4..fda6cf1 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_tspan.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_tspan.cc
@@ -30,6 +30,7 @@
 
 bool LayoutSVGTSpan::IsChildAllowed(LayoutObject* child,
                                     const ComputedStyle&) const {
+  CheckIsNotDestroyed();
   // Always allow text (except empty textnodes and <br>).
   if (child->IsText())
     return SVGLayoutSupport::IsLayoutableTextNode(child);
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_tspan.h b/third_party/blink/renderer/core/layout/svg/layout_svg_tspan.h
index f25019e1..1c9a2524 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_tspan.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_tspan.h
@@ -31,7 +31,10 @@
 
   bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
 
-  const char* GetName() const override { return "LayoutSVGTSpan"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGTSpan";
+  }
 };
 }
 
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.cc
index 97c01f49..f57ad79 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.cc
@@ -36,6 +36,7 @@
       needs_transform_update_(true) {}
 
 void LayoutSVGViewportContainer::UpdateLayout() {
+  CheckIsNotDestroyed();
   DCHECK(NeedsLayout());
 
   const auto* svg = To<SVGSVGElement>(GetElement());
@@ -59,6 +60,7 @@
 }
 
 void LayoutSVGViewportContainer::SetNeedsTransformUpdate() {
+  CheckIsNotDestroyed();
   // The transform paint property relies on the SVG transform being up-to-date
   // (see: PaintPropertyTreeBuilder::updateTransformForNonRootSVG).
   SetNeedsPaintPropertyUpdate();
@@ -67,6 +69,7 @@
 
 SVGTransformChange LayoutSVGViewportContainer::CalculateLocalTransform(
     bool bounds_changed) {
+  CheckIsNotDestroyed();
   if (!needs_transform_update_)
     return SVGTransformChange::kNone;
 
@@ -84,6 +87,7 @@
     const HitTestLocation& hit_test_location,
     const PhysicalOffset& accumulated_offset,
     HitTestAction action) {
+  CheckIsNotDestroyed();
   // Respect the viewport clip which is in parent coordinates.
   if (SVGLayoutSupport::IsOverflowHidden(*this)) {
     if (!hit_test_location.Intersects(viewport_))
@@ -96,6 +100,7 @@
 void LayoutSVGViewportContainer::StyleDidChange(
     StyleDifference diff,
     const ComputedStyle* old_style) {
+  CheckIsNotDestroyed();
   LayoutSVGContainer::StyleDidChange(diff, old_style);
 
   if (old_style && (SVGLayoutSupport::IsOverflowHidden(*old_style) !=
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.h b/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.h
index 9835f9be..3c121f9 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.h
@@ -34,20 +34,31 @@
 class LayoutSVGViewportContainer final : public LayoutSVGContainer {
  public:
   explicit LayoutSVGViewportContainer(SVGSVGElement*);
-  FloatRect Viewport() const { return viewport_; }
+  FloatRect Viewport() const {
+    CheckIsNotDestroyed();
+    return viewport_;
+  }
 
-  bool IsLayoutSizeChanged() const { return is_layout_size_changed_; }
+  bool IsLayoutSizeChanged() const {
+    CheckIsNotDestroyed();
+    return is_layout_size_changed_;
+  }
 
   void SetNeedsTransformUpdate() override;
 
-  const char* GetName() const override { return "LayoutSVGViewportContainer"; }
+  const char* GetName() const override {
+    CheckIsNotDestroyed();
+    return "LayoutSVGViewportContainer";
+  }
 
   AffineTransform LocalToSVGParentTransform() const override {
+    CheckIsNotDestroyed();
     return local_to_parent_transform_;
   }
 
  private:
   bool IsOfType(LayoutObjectType type) const override {
+    CheckIsNotDestroyed();
     return type == kLayoutObjectSVGViewportContainer ||
            LayoutSVGContainer::IsOfType(type);
   }
diff --git a/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc b/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc
index 026281b..e0f4822 100644
--- a/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc
+++ b/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc
@@ -155,12 +155,12 @@
 
     if (RuntimeEnabledFeatures::SignedExchangeSubresourcePrefetchEnabled(
             document_->GetExecutionContext()) &&
-        resource->LastResourceResponse()) {
+        resource->RedirectChainSize() > 0) {
       // See if the outer response (which must be the last response in
       // the redirect chain) had provided alternate links for the prefetch.
       alternate_resource_info =
           AlternateSignedExchangeResourceInfo::CreateIfValid(
-              resource->LastResourceResponse()->HttpHeaderField(
+              resource->LastResourceResponse().HttpHeaderField(
                   http_names::kLink),
               response.HttpHeaderField(http_names::kLink));
     }
diff --git a/third_party/blink/renderer/core/script/classic_pending_script.h b/third_party/blink/renderer/core/script/classic_pending_script.h
index bb2a8ec..eaf1500 100644
--- a/third_party/blink/renderer/core/script/classic_pending_script.h
+++ b/third_party/blink/renderer/core/script/classic_pending_script.h
@@ -58,8 +58,8 @@
 
   void Trace(Visitor*) const override;
 
-  mojom::ScriptType GetScriptType() const override {
-    return mojom::ScriptType::kClassic;
+  mojom::blink::ScriptType GetScriptType() const override {
+    return mojom::blink::ScriptType::kClassic;
   }
 
   ClassicScript* GetSource(const KURL& document_url) const override;
diff --git a/third_party/blink/renderer/core/script/classic_script.h b/third_party/blink/renderer/core/script/classic_script.h
index 309ba7f..ea0ccbd 100644
--- a/third_party/blink/renderer/core/script/classic_script.h
+++ b/third_party/blink/renderer/core/script/classic_script.h
@@ -62,8 +62,8 @@
                                                               int32_t world_id);
 
  private:
-  mojom::ScriptType GetScriptType() const override {
-    return mojom::ScriptType::kClassic;
+  mojom::blink::ScriptType GetScriptType() const override {
+    return mojom::blink::ScriptType::kClassic;
   }
 
   std::pair<size_t, size_t> GetClassicScriptSizes() const override;
diff --git a/third_party/blink/renderer/core/script/module_pending_script.h b/third_party/blink/renderer/core/script/module_pending_script.h
index d128a3a..73805e5 100644
--- a/third_party/blink/renderer/core/script/module_pending_script.h
+++ b/third_party/blink/renderer/core/script/module_pending_script.h
@@ -59,8 +59,8 @@
 
  private:
   // PendingScript
-  mojom::ScriptType GetScriptType() const override {
-    return mojom::ScriptType::kModule;
+  mojom::blink::ScriptType GetScriptType() const override {
+    return mojom::blink::ScriptType::kModule;
   }
   Script* GetSource(const KURL& document_url) const override;
   bool IsReady() const override { return ready_; }
diff --git a/third_party/blink/renderer/core/script/module_script.h b/third_party/blink/renderer/core/script/module_script.h
index 646a00c..4147915 100644
--- a/third_party/blink/renderer/core/script/module_script.h
+++ b/third_party/blink/renderer/core/script/module_script.h
@@ -64,8 +64,8 @@
   Modulator* SettingsObject() const { return settings_object_; }
 
  private:
-  mojom::ScriptType GetScriptType() const override {
-    return mojom::ScriptType::kModule;
+  mojom::blink::ScriptType GetScriptType() const override {
+    return mojom::blink::ScriptType::kModule;
   }
   void RunScript(LocalFrame*) override;
   bool RunScriptOnWorkerOrWorklet(WorkerOrWorkletGlobalScope&) override;
diff --git a/third_party/blink/renderer/core/script/pending_script.cc b/third_party/blink/renderer/core/script/pending_script.cc
index 9787590..ba76932 100644
--- a/third_party/blink/renderer/core/script/pending_script.cc
+++ b/third_party/blink/renderer/core/script/pending_script.cc
@@ -246,7 +246,7 @@
     // <spec step="4.B.1">Assert: The script element's node document's
     // currentScript attribute is null.</spec>
     ScriptElementBase* current_script = nullptr;
-    if (script->GetScriptType() == mojom::ScriptType::kClassic)
+    if (script->GetScriptType() == mojom::blink::ScriptType::kClassic)
       current_script = element;
     context_document->PushCurrentScript(current_script);
 
diff --git a/third_party/blink/renderer/core/script/pending_script.h b/third_party/blink/renderer/core/script/pending_script.h
index 206c9d97..5b448694 100644
--- a/third_party/blink/renderer/core/script/pending_script.h
+++ b/third_party/blink/renderer/core/script/pending_script.h
@@ -83,7 +83,7 @@
 
   ScriptElementBase* GetElement() const;
 
-  virtual mojom::ScriptType GetScriptType() const = 0;
+  virtual mojom::blink::ScriptType GetScriptType() const = 0;
 
   virtual void Trace(Visitor*) const;
   const char* NameInHeapSnapshot() const override { return "PendingScript"; }
@@ -104,7 +104,7 @@
 
   // Used for DCHECK()s.
   bool IsExternalOrModule() const {
-    return IsExternal() || GetScriptType() == mojom::ScriptType::kModule;
+    return IsExternal() || GetScriptType() == mojom::blink::ScriptType::kModule;
   }
 
   void Dispose();
diff --git a/third_party/blink/renderer/core/script/script.cc b/third_party/blink/renderer/core/script/script.cc
index bfa6a5f..3c2f207 100644
--- a/third_party/blink/renderer/core/script/script.cc
+++ b/third_party/blink/renderer/core/script/script.cc
@@ -8,12 +8,12 @@
 
 namespace blink {
 
-base::Optional<mojom::ScriptType> Script::ParseScriptType(
+base::Optional<mojom::blink::ScriptType> Script::ParseScriptType(
     const String& script_type) {
   if (script_type == "classic")
-    return mojom::ScriptType::kClassic;
+    return mojom::blink::ScriptType::kClassic;
   if (script_type == "module")
-    return mojom::ScriptType::kModule;
+    return mojom::blink::ScriptType::kModule;
   return base::nullopt;
 }
 
diff --git a/third_party/blink/renderer/core/script/script.h b/third_party/blink/renderer/core/script/script.h
index 3d19ef8..05ec402b 100644
--- a/third_party/blink/renderer/core/script/script.h
+++ b/third_party/blink/renderer/core/script/script.h
@@ -25,8 +25,8 @@
 
   virtual ~Script() {}
 
-  virtual mojom::ScriptType GetScriptType() const = 0;
-  static base::Optional<mojom::ScriptType> ParseScriptType(
+  virtual mojom::blink::ScriptType GetScriptType() const = 0;
+  static base::Optional<mojom::blink::ScriptType> ParseScriptType(
       const String& script_type);
 
   // https://html.spec.whatwg.org/C/#run-a-classic-script
diff --git a/third_party/blink/renderer/core/script/script_loader.cc b/third_party/blink/renderer/core/script/script_loader.cc
index 5da944d6..59234b5 100644
--- a/third_party/blink/renderer/core/script/script_loader.cc
+++ b/third_party/blink/renderer/core/script/script_loader.cc
@@ -194,7 +194,7 @@
     const String& type,
     const String& language,
     LegacyTypeSupport support_legacy_types,
-    mojom::ScriptType* out_script_type,
+    mojom::blink::ScriptType* out_script_type,
     bool* out_is_import_map) {
   if (IsValidClassicScriptTypeAndLanguage(type, language,
                                           support_legacy_types)) {
@@ -203,7 +203,7 @@
     //
     // TODO(hiroshige): Annotate and/or cleanup this step.
     if (out_script_type)
-      *out_script_type = mojom::ScriptType::kClassic;
+      *out_script_type = mojom::blink::ScriptType::kClassic;
     if (out_is_import_map)
       *out_is_import_map = false;
     return true;
@@ -214,7 +214,7 @@
     // case-insensitive match for the string "module", the script's type is
     // "module". ...</spec>
     if (out_script_type)
-      *out_script_type = mojom::ScriptType::kModule;
+      *out_script_type = mojom::blink::ScriptType::kModule;
     if (out_is_import_map)
       *out_is_import_map = false;
     return true;
@@ -231,9 +231,9 @@
   return false;
 }
 
-bool ScriptLoader::BlockForNoModule(mojom::ScriptType script_type,
+bool ScriptLoader::BlockForNoModule(mojom::blink::ScriptType script_type,
                                     bool nomodule) {
-  return nomodule && script_type == mojom::ScriptType::kClassic;
+  return nomodule && script_type == mojom::blink::ScriptType::kClassic;
 }
 
 // Corresponds to
@@ -258,16 +258,17 @@
 }
 
 // https://github.com/w3c/webappsec-permissions-policy/issues/135
-bool ShouldBlockSyncScriptForDocumentPolicy(const ScriptElementBase* element,
-                                            mojom::ScriptType script_type,
-                                            bool parser_inserted) {
+bool ShouldBlockSyncScriptForDocumentPolicy(
+    const ScriptElementBase* element,
+    mojom::blink::ScriptType script_type,
+    bool parser_inserted) {
   if (element->GetExecutionContext()->IsFeatureEnabled(
           mojom::blink::DocumentPolicyFeature::kSyncScript)) {
     return false;
   }
 
   // Module scripts never block parsing.
-  if (script_type == mojom::ScriptType::kModule || !parser_inserted)
+  if (script_type == mojom::blink::ScriptType::kModule || !parser_inserted)
     return false;
 
   if (!element->HasSourceAttribute())
@@ -476,7 +477,7 @@
   ParserDisposition parser_state =
       IsParserInserted() ? kParserInserted : kNotParserInserted;
 
-  if (GetScriptType() == mojom::ScriptType::kModule)
+  if (GetScriptType() == mojom::blink::ScriptType::kModule)
     UseCounter::Count(*context_window, WebFeature::kPrepareModuleScript);
 
   DCHECK(!prepared_pending_script_);
@@ -567,7 +568,7 @@
       return false;
     }
 
-    if (GetScriptType() == mojom::ScriptType::kClassic) {
+    if (GetScriptType() == mojom::blink::ScriptType::kClassic) {
       // - "classic":
 
       // <spec step="15">If the script element has a charset attribute, then let
@@ -661,7 +662,7 @@
 
     switch (GetScriptType()) {
         // <spec step="25.2.A">"classic"</spec>
-      case mojom::ScriptType::kClassic: {
+      case mojom::blink::ScriptType::kClassic: {
         // <spec step="25.2.A.1">Let script be the result of creating a classic
         // script using source text, settings object, base URL, and
         // options.</spec>
@@ -689,7 +690,7 @@
       }
 
         // <spec step="25.2.B">"module"</spec>
-      case mojom::ScriptType::kModule: {
+      case mojom::blink::ScriptType::kModule: {
         // <spec step="25.2.B.1">Fetch an inline module script graph, given
         // source text, base URL, settings object, and options. When this
         // asynchronously completes, set the script's script to the result. At
@@ -753,11 +754,11 @@
   // If the script's type is "module", and the element has been flagged as
   // "parser-inserted", and the element does not have an async attribute
   // ...</spec>
-  if ((GetScriptType() == mojom::ScriptType::kClassic &&
+  if ((GetScriptType() == mojom::blink::ScriptType::kClassic &&
        element_->HasSourceAttribute() && element_->DeferAttributeValue() &&
        parser_inserted_ && !element_->AsyncAttributeValue()) ||
-      (GetScriptType() == mojom::ScriptType::kModule && parser_inserted_ &&
-       !element_->AsyncAttributeValue())) {
+      (GetScriptType() == mojom::blink::ScriptType::kModule &&
+       parser_inserted_ && !element_->AsyncAttributeValue())) {
     // This clause is implemented by the caller-side of prepareScript():
     // - HTMLParserScriptRunner::requestDeferredScript(), and
     // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
@@ -768,7 +769,7 @@
   }
 
   // Check for external script that should be force deferred.
-  if (GetScriptType() == mojom::ScriptType::kClassic &&
+  if (GetScriptType() == mojom::blink::ScriptType::kClassic &&
       element_->HasSourceAttribute() &&
       context_window->GetFrame()->ShouldForceDeferScript() &&
       IsA<HTMLDocument>(context_window->document()) && parser_inserted_ &&
@@ -789,7 +790,7 @@
   // <spec step="26.B">If the script's type is "classic", and the element has a
   // src attribute, and the element has been flagged as "parser-inserted", and
   // the element does not have an async attribute ...</spec>
-  if (GetScriptType() == mojom::ScriptType::kClassic &&
+  if (GetScriptType() == mojom::blink::ScriptType::kClassic &&
       element_->HasSourceAttribute() && parser_inserted_ &&
       !element_->AsyncAttributeValue()) {
     // This clause is implemented by the caller-side of prepareScript():
@@ -807,10 +808,10 @@
   // If the script's type is "module", and the element does not have an async
   // attribute, and the element does not have the "non-blocking" flag set
   // ...</spec>
-  if ((GetScriptType() == mojom::ScriptType::kClassic &&
+  if ((GetScriptType() == mojom::blink::ScriptType::kClassic &&
        element_->HasSourceAttribute() && !element_->AsyncAttributeValue() &&
        !non_blocking_) ||
-      (GetScriptType() == mojom::ScriptType::kModule &&
+      (GetScriptType() == mojom::blink::ScriptType::kModule &&
        !element_->AsyncAttributeValue() && !non_blocking_)) {
     // <spec step="26.C">... Add the element to the end of the list of scripts
     // that will execute in order as soon as possible associated with the node
@@ -834,9 +835,9 @@
   // src attribute
   //
   // If the script's type is "module" ...</spec>
-  if ((GetScriptType() == mojom::ScriptType::kClassic &&
+  if ((GetScriptType() == mojom::blink::ScriptType::kClassic &&
        element_->HasSourceAttribute()) ||
-      GetScriptType() == mojom::ScriptType::kModule) {
+      GetScriptType() == mojom::blink::ScriptType::kModule) {
     // <spec step="26.D">... The element must be added to the set of scripts
     // that will execute as soon as possible of the node document of the script
     // element at the time the prepare a script algorithm started. When the
@@ -860,7 +861,7 @@
 
   // The following clauses are executed only if the script's type is "classic"
   // and the element doesn't have a src attribute.
-  DCHECK_EQ(GetScriptType(), mojom::ScriptType::kClassic);
+  DCHECK_EQ(GetScriptType(), mojom::blink::ScriptType::kClassic);
   DCHECK(!is_external_script_);
 
   // Check for inline script that should be force deferred.
@@ -1013,7 +1014,7 @@
 
   // <spec step="14">If the script element has an event attribute and a for
   // attribute, and the script's type is "classic", then:</spec>
-  if (GetScriptType() != mojom::ScriptType::kClassic ||
+  if (GetScriptType() != mojom::blink::ScriptType::kClassic ||
       event_attribute.IsNull() || for_attribute.IsNull())
     return true;
 
diff --git a/third_party/blink/renderer/core/script/script_loader.h b/third_party/blink/renderer/core/script/script_loader.h
index dddfeb9..9a2d1c5 100644
--- a/third_party/blink/renderer/core/script/script_loader.h
+++ b/third_party/blink/renderer/core/script/script_loader.h
@@ -62,18 +62,18 @@
   };
 
   // |out_is_import_map| is set separately from |out_script_type| in order
-  // to avoid adding import maps as a mojom::ScriptType enum, because import
-  // maps are processed quite differently from classic/module scripts.
+  // to avoid adding import maps as a mojom::blink::ScriptType enum, because
+  // import maps are processed quite differently from classic/module scripts.
   //
   // TODO(hiroshige, kouhei): Make the method signature simpler.
   static bool IsValidScriptTypeAndLanguage(
       const String& type_attribute_value,
       const String& language_attribute_value,
       LegacyTypeSupport support_legacy_types,
-      mojom::ScriptType* out_script_type = nullptr,
+      mojom::blink::ScriptType* out_script_type = nullptr,
       bool* out_is_import_map = nullptr);
 
-  static bool BlockForNoModule(mojom::ScriptType, bool nomodule);
+  static bool BlockForNoModule(mojom::blink::ScriptType, bool nomodule);
 
   static network::mojom::CredentialsMode ModuleScriptCredentialsMode(
       CrossOriginAttributeValue);
@@ -97,7 +97,7 @@
   bool IsParserInserted() const { return parser_inserted_; }
   bool AlreadyStarted() const { return already_started_; }
   bool IsNonBlocking() const { return non_blocking_; }
-  mojom::ScriptType GetScriptType() const { return script_type_; }
+  mojom::blink::ScriptType GetScriptType() const { return script_type_; }
 
   // Helper functions used by our parent classes.
   void DidNotifySubtreeInsertionsToDocument();
@@ -178,7 +178,7 @@
 
   // <spec href="https://html.spec.whatwg.org/C/#concept-script-type">... It is
   // determined when the script is prepared, ...</spec>
-  mojom::ScriptType script_type_ = mojom::ScriptType::kClassic;
+  mojom::blink::ScriptType script_type_ = mojom::blink::ScriptType::kClassic;
 
   // <spec href="https://html.spec.whatwg.org/C/#concept-script-external">
   // ... It is determined when the script is prepared, ...</spec>
diff --git a/third_party/blink/renderer/core/script/script_runner_test.cc b/third_party/blink/renderer/core/script/script_runner_test.cc
index 266233e9..a68dafd 100644
--- a/third_party/blink/renderer/core/script/script_runner_test.cc
+++ b/third_party/blink/renderer/core/script/script_runner_test.cc
@@ -41,7 +41,7 @@
   }
   ~MockPendingScript() override {}
 
-  MOCK_CONST_METHOD0(GetScriptType, mojom::ScriptType());
+  MOCK_CONST_METHOD0(GetScriptType, mojom::blink::ScriptType());
   MOCK_CONST_METHOD1(CheckMIMETypeBeforeRunScript, bool(Document*));
   MOCK_CONST_METHOD1(GetSource, Script*(const KURL&));
   MOCK_CONST_METHOD0(IsExternal, bool());
diff --git a/third_party/blink/renderer/core/script/xml_parser_script_runner.cc b/third_party/blink/renderer/core/script/xml_parser_script_runner.cc
index 01b2e9c..1b1617b 100644
--- a/third_party/blink/renderer/core/script/xml_parser_script_runner.cc
+++ b/third_party/blink/renderer/core/script/xml_parser_script_runner.cc
@@ -47,7 +47,7 @@
 
   pending_script->StopWatchingForLoad();
 
-  CHECK_EQ(pending_script->GetScriptType(), mojom::ScriptType::kClassic);
+  CHECK_EQ(pending_script->GetScriptType(), mojom::blink::ScriptType::kClassic);
 
   // <spec label="Parsing" step="4">Execute the pending parsing-blocking
   // script.</spec>
@@ -77,7 +77,7 @@
   bool success = script_loader->PrepareScript(
       script_start_position, ScriptLoader::kAllowLegacyTypeInTypeAttribute);
 
-  if (script_loader->GetScriptType() != mojom::ScriptType::kClassic) {
+  if (script_loader->GetScriptType() != mojom::blink::ScriptType::kClassic) {
     // XMLDocumentParser does not support a module script, and thus ignores it.
     success = false;
     document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.cc b/third_party/blink/renderer/core/workers/dedicated_worker.cc
index 70ec512..342acee 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker.cc
@@ -429,9 +429,9 @@
     settings = WorkerSettings::Copy(worker_global_scope->GetWorkerSettings());
   }
 
-  mojom::ScriptType script_type = (options_->type() == "classic")
-                                      ? mojom::ScriptType::kClassic
-                                      : mojom::ScriptType::kModule;
+  mojom::blink::ScriptType script_type =
+      (options_->type() == "classic") ? mojom::blink::ScriptType::kClassic
+                                      : mojom::blink::ScriptType::kModule;
 
   return std::make_unique<GlobalScopeCreationParams>(
       script_url, script_type, options_->name(),
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_test.cc b/third_party/blink/renderer/core/workers/dedicated_worker_test.cc
index df3b904..61fa4d89 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_test.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_test.cc
@@ -130,8 +130,8 @@
     auto worker_settings = std::make_unique<WorkerSettings>(
         To<LocalDOMWindow>(GetExecutionContext())->GetFrame()->GetSettings());
     auto params = std::make_unique<GlobalScopeCreationParams>(
-        script_url, mojom::ScriptType::kClassic, "fake global scope name",
-        "fake user agent", UserAgentMetadata(),
+        script_url, mojom::blink::ScriptType::kClassic,
+        "fake global scope name", "fake user agent", UserAgentMetadata(),
         nullptr /* web_worker_fetch_context */, headers,
         network::mojom::ReferrerPolicy::kDefault, security_origin_.get(),
         false /* starter_secure_context */,
diff --git a/third_party/blink/renderer/core/workers/global_scope_creation_params.cc b/third_party/blink/renderer/core/workers/global_scope_creation_params.cc
index 77fb76e..8cb40161 100644
--- a/third_party/blink/renderer/core/workers/global_scope_creation_params.cc
+++ b/third_party/blink/renderer/core/workers/global_scope_creation_params.cc
@@ -15,7 +15,7 @@
 
 GlobalScopeCreationParams::GlobalScopeCreationParams(
     const KURL& script_url,
-    mojom::ScriptType script_type,
+    mojom::blink::ScriptType script_type,
     const String& global_scope_name,
     const String& user_agent,
     const base::Optional<UserAgentMetadata>& ua_metadata,
diff --git a/third_party/blink/renderer/core/workers/global_scope_creation_params.h b/third_party/blink/renderer/core/workers/global_scope_creation_params.h
index af807289..c473093 100644
--- a/third_party/blink/renderer/core/workers/global_scope_creation_params.h
+++ b/third_party/blink/renderer/core/workers/global_scope_creation_params.h
@@ -42,7 +42,7 @@
  public:
   GlobalScopeCreationParams(
       const KURL& script_url,
-      mojom::ScriptType script_type,
+      mojom::blink::ScriptType script_type,
       const String& global_scope_name,
       const String& user_agent,
       const base::Optional<UserAgentMetadata>& ua_metadata,
@@ -84,7 +84,7 @@
   // workers.
   KURL script_url;
 
-  mojom::ScriptType script_type;
+  mojom::blink::ScriptType script_type;
 
   String global_scope_name;
   String user_agent;
diff --git a/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc b/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc
index cadbf885..89e91e8 100644
--- a/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc
+++ b/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc
@@ -60,7 +60,7 @@
     reporting_proxy_ =
         std::make_unique<MainThreadWorkletReportingProxyForTest>(window);
     auto creation_params = std::make_unique<GlobalScopeCreationParams>(
-        window->Url(), mojom::ScriptType::kModule, "MainThreadWorklet",
+        window->Url(), mojom::blink::ScriptType::kModule, "MainThreadWorklet",
         window->UserAgent(), window->GetFrame()->Loader().UserAgentMetadata(),
         nullptr /* web_worker_fetch_context */,
         window->GetContentSecurityPolicy()->Headers(),
diff --git a/third_party/blink/renderer/core/workers/shared_worker.cc b/third_party/blink/renderer/core/workers/shared_worker.cc
index c4586bb..7886a7c5 100644
--- a/third_party/blink/renderer/core/workers/shared_worker.cc
+++ b/third_party/blink/renderer/core/workers/shared_worker.cc
@@ -122,7 +122,7 @@
       return nullptr;
     }
     options->name = worker_options->name();
-    base::Optional<mojom::ScriptType> type_result =
+    base::Optional<mojom::blink::ScriptType> type_result =
         Script::ParseScriptType(worker_options->type());
     DCHECK(type_result);
     options->type = type_result.value();
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.cc b/third_party/blink/renderer/core/workers/worker_global_scope.cc
index d369189..c1e4291 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.cc
@@ -248,7 +248,7 @@
 
   // Step 1: "If worker global scope's type is "module", throw a TypeError
   // exception."
-  if (script_type_ == mojom::ScriptType::kModule) {
+  if (script_type_ == mojom::blink::ScriptType::kModule) {
     V8ThrowException::ThrowTypeError(
         isolate, ExceptionMessages::FailedToExecute(
                      property_name, interface_name,
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.h b/third_party/blink/renderer/core/workers/worker_global_scope.h
index d4b5f097..9f76a716 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -240,7 +240,7 @@
 
   void InitializeURL(const KURL& url);
 
-  mojom::ScriptType GetScriptType() const { return script_type_; }
+  mojom::blink::ScriptType GetScriptType() const { return script_type_; }
 
   // Sets the parameters for the worker main module script loaded by the browser
   // process.
@@ -261,7 +261,7 @@
   EventTarget* ErrorEventTarget() final { return this; }
 
   KURL url_;
-  const mojom::ScriptType script_type_;
+  const mojom::blink::ScriptType script_type_;
   const String user_agent_;
   const UserAgentMetadata ua_metadata_;
   std::unique_ptr<WorkerSettings> worker_settings_;
diff --git a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
index bfd79bc1..da9e4d57 100644
--- a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
+++ b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
@@ -264,7 +264,7 @@
     // > "classic": Fetch a classic worker script given job's serialized script
     // > url, job's client, "serviceworker", and the to-be-created environment
     // > settings object for this service worker.
-    case mojom::ScriptType::kClassic:
+    case mojom::blink::ScriptType::kClassic:
       worker_thread_->FetchAndRunClassicScript(
           worker_start_data->script_url,
           nullptr /* worker_main_script_load_params */,
@@ -276,7 +276,7 @@
     // > "module": Fetch a module worker script graph given job’s serialized
     // > script url, job’s client, "serviceworker", "omit", and the
     // > to-be-created environment settings object for this service worker.
-    case mojom::ScriptType::kModule:
+    case mojom::blink::ScriptType::kModule:
       worker_thread_->FetchAndRunModuleScript(
           worker_start_data->script_url,
           nullptr /* worker_main_script_load_params */,
diff --git a/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc b/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc
index fc3eeeb..ee50257 100644
--- a/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc
+++ b/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc
@@ -81,85 +81,6 @@
   EXPECT_FALSE(sensor->hasReading());
 }
 
-TEST(AmbientLightSensorTest, IlluminanceRounding) {
-  SensorTestContext context;
-  NonThrowableExceptionState exception_state;
-
-  auto* sensor = AmbientLightSensor::Create(context.GetExecutionContext(),
-                                            exception_state);
-  sensor->start();
-  SensorTestUtils::WaitForEvent(sensor, event_type_names::kActivate);
-  EXPECT_FALSE(sensor->hasReading());
-
-  // At this point, we have received an 'activate' event, so the sensor is
-  // initialized and it is connected to a SensorProxy that we can retrieve
-  // here. We then attach a new SensorProxy::Observer that we use to
-  // synchronously wait for OnSensorReadingChanged() to be called. Even though
-  // the order that each observer is notified is arbitrary, we know that by the
-  // time we get to the next call here all observers will have been called.
-  auto* sensor_proxy =
-      SensorProviderProxy::From(
-          To<LocalDOMWindow>(context.GetExecutionContext()))
-          ->GetSensorProxy(device::mojom::blink::SensorType::AMBIENT_LIGHT);
-  ASSERT_NE(sensor_proxy, nullptr);
-  auto* mock_observer = MakeGarbageCollected<MockSensorProxyObserver>();
-  sensor_proxy->AddObserver(mock_observer);
-
-  auto* event_counter = MakeGarbageCollected<SensorTestUtils::EventCounter>();
-  sensor->addEventListener(event_type_names::kReading, event_counter);
-
-  // Go from no reading to 24. This will cause a new "reading" event to be
-  // emitted, and the rounding will cause illuminance() to return 0.
-  context.sensor_provider()->UpdateAmbientLightSensorData(24);
-  mock_observer->WaitForOnSensorReadingChanged();
-  SensorTestUtils::WaitForEvent(sensor, event_type_names::kReading);
-  EXPECT_EQ(24, sensor->latest_reading_);
-  ASSERT_TRUE(sensor->illuminance().has_value());
-  EXPECT_EQ(0, sensor->illuminance().value());
-
-  // Go from 24 to 35. The difference is not significant enough, so we will not
-  // emit any "reading" event or store the new raw reading, as if the new
-  // reading had never existed.
-  context.sensor_provider()->UpdateAmbientLightSensorData(35);
-  mock_observer->WaitForOnSensorReadingChanged();
-  EXPECT_EQ(24, sensor->latest_reading_);
-  ASSERT_TRUE(sensor->illuminance().has_value());
-  EXPECT_EQ(0, sensor->illuminance().value());
-
-  // Go from 24 to 49. The difference is significant enough, so we will emit a
-  // new "reading" event, update our raw reading and return a rounded value of
-  // 50 in illuminance().
-  context.sensor_provider()->UpdateAmbientLightSensorData(49);
-  mock_observer->WaitForOnSensorReadingChanged();
-  SensorTestUtils::WaitForEvent(sensor, event_type_names::kReading);
-  EXPECT_EQ(49, sensor->latest_reading_);
-  ASSERT_TRUE(sensor->illuminance().has_value());
-  EXPECT_EQ(50, sensor->illuminance().value());
-
-  // Go from 49 to 35. The difference is not significant enough, so we will not
-  // emit any "reading" event or store the new raw reading, as if the new
-  // reading had never existed.
-  context.sensor_provider()->UpdateAmbientLightSensorData(35);
-  mock_observer->WaitForOnSensorReadingChanged();
-  EXPECT_EQ(49, sensor->latest_reading_);
-  ASSERT_TRUE(sensor->illuminance().has_value());
-  EXPECT_EQ(50, sensor->illuminance().value());
-
-  // Go from 49 to 24. The difference is significant enough, so we will emit a
-  // new "reading" event, update our raw reading and return a rounded value of
-  // 0 in illuminance().
-  context.sensor_provider()->UpdateAmbientLightSensorData(24);
-  mock_observer->WaitForOnSensorReadingChanged();
-  SensorTestUtils::WaitForEvent(sensor, event_type_names::kReading);
-  EXPECT_EQ(24, sensor->latest_reading_);
-  ASSERT_TRUE(sensor->illuminance().has_value());
-  EXPECT_EQ(0, sensor->illuminance().value());
-
-  // Make sure there were no stray "reading" events besides those we expected
-  // above.
-  EXPECT_EQ(3U, event_counter->event_count());
-}
-
 TEST(AmbientLightSensorTest, PlatformSensorReadingsBeforeActivation) {
   SensorTestContext context;
   NonThrowableExceptionState exception_state;
diff --git a/third_party/blink/renderer/modules/sensor/sensor.cc b/third_party/blink/renderer/modules/sensor/sensor.cc
index 3c05cf3..89e9e77 100644
--- a/third_party/blink/renderer/modules/sensor/sensor.cc
+++ b/third_party/blink/renderer/modules/sensor/sensor.cc
@@ -263,11 +263,7 @@
   DCHECK_EQ(state_, SensorState::kActivating);
 
   InitSensorProxyIfNeeded();
-  if (!sensor_proxy_) {
-    HandleError(DOMExceptionCode::kInvalidStateError,
-                "The Sensor is no longer associated to a frame.");
-    return;
-  }
+  DCHECK(sensor_proxy_);
 
   if (sensor_proxy_->IsInitialized())
     RequestAddConfiguration();
diff --git a/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h b/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h
index c51f783..f427ad7 100644
--- a/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h
+++ b/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h
@@ -48,15 +48,13 @@
     return sensor_provider_.get();
   }
   void RemoveSensorProxy(SensorProxy* proxy);
-  using SensorsSet = HeapHashSet<WeakMember<SensorProxy>>;
-  const SensorsSet& sensor_proxies() const { return sensor_proxies_; }
 
   // For SensorProviderProxy personal use.
   void InitializeIfNeeded();
   bool IsInitialized() const { return sensor_provider_.is_bound(); }
   void OnSensorProviderConnectionError();
-  SensorsSet sensor_proxies_;
 
+  HeapHashSet<WeakMember<SensorProxy>> sensor_proxies_;
   HeapMojoRemote<device::mojom::blink::SensorProvider,
                  HeapMojoWrapperMode::kWithoutContextObserver>
       sensor_provider_;
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_container.cc b/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
index a4a827a..b162f4b2 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
@@ -342,7 +342,7 @@
 
   mojom::ServiceWorkerUpdateViaCache update_via_cache =
       ParseUpdateViaCache(options->updateViaCache());
-  base::Optional<mojom::ScriptType> script_type =
+  base::Optional<mojom::blink::ScriptType> script_type =
       Script::ParseScriptType(options->type());
   DCHECK(script_type);
 
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc b/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
index 9fbb0ab..b1e9b67a 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
@@ -161,7 +161,7 @@
   void RegisterServiceWorker(
       const WebURL& scope,
       const WebURL& script_url,
-      blink::mojom::ScriptType script_type,
+      blink::mojom::blink::ScriptType script_type,
       mojom::ServiceWorkerUpdateViaCache update_via_cache,
       const WebFetchClientSettingsObject& fetch_client_settings_object,
       std::unique_ptr<WebServiceWorkerRegistrationCallbacks> callbacks)
@@ -276,7 +276,7 @@
   StubWebServiceWorkerProvider()
       : register_call_count_(0),
         get_registration_call_count_(0),
-        script_type_(mojom::ScriptType::kClassic),
+        script_type_(mojom::blink::ScriptType::kClassic),
         update_via_cache_(mojom::ServiceWorkerUpdateViaCache::kImports) {}
 
   // Creates a WebServiceWorkerProvider. This can outlive the
@@ -292,7 +292,7 @@
   const WebURL& RegisterScriptURL() { return register_script_url_; }
   size_t GetRegistrationCallCount() { return get_registration_call_count_; }
   const WebURL& GetRegistrationURL() { return get_registration_url_; }
-  mojom::ScriptType ScriptType() const { return script_type_; }
+  mojom::blink::ScriptType ScriptType() const { return script_type_; }
   mojom::ServiceWorkerUpdateViaCache UpdateViaCache() const {
     return update_via_cache_;
   }
@@ -308,7 +308,7 @@
     void RegisterServiceWorker(
         const WebURL& scope,
         const WebURL& script_url,
-        blink::mojom::ScriptType script_type,
+        blink::mojom::blink::ScriptType script_type,
         mojom::ServiceWorkerUpdateViaCache update_via_cache,
         const WebFetchClientSettingsObject& fetch_client_settings_object,
         std::unique_ptr<WebServiceWorkerRegistrationCallbacks> callbacks)
@@ -350,7 +350,7 @@
   WebURL register_script_url_;
   size_t get_registration_call_count_;
   WebURL get_registration_url_;
-  mojom::ScriptType script_type_;
+  mojom::blink::ScriptType script_type_;
   mojom::ServiceWorkerUpdateViaCache update_via_cache_;
 };
 
@@ -375,7 +375,7 @@
               stub_provider.RegisterScope());
     EXPECT_EQ(WebURL(KURL("http://localhost/x/y/worker.js")),
               stub_provider.RegisterScriptURL());
-    EXPECT_EQ(mojom::ScriptType::kClassic, stub_provider.ScriptType());
+    EXPECT_EQ(mojom::blink::ScriptType::kClassic, stub_provider.ScriptType());
     EXPECT_EQ(mojom::ServiceWorkerUpdateViaCache::kImports,
               stub_provider.UpdateViaCache());
   }
@@ -395,7 +395,7 @@
     EXPECT_EQ(1ul, stub_provider.GetRegistrationCallCount());
     EXPECT_EQ(WebURL(KURL("http://localhost/x/index.html")),
               stub_provider.GetRegistrationURL());
-    EXPECT_EQ(mojom::ScriptType::kClassic, stub_provider.ScriptType());
+    EXPECT_EQ(mojom::blink::ScriptType::kClassic, stub_provider.ScriptType());
     EXPECT_EQ(mojom::ServiceWorkerUpdateViaCache::kImports,
               stub_provider.UpdateViaCache());
   }
@@ -422,7 +422,7 @@
               stub_provider.RegisterScope());
     EXPECT_EQ(WebURL(KURL(KURL(), "http://localhost/x/y/worker.js")),
               stub_provider.RegisterScriptURL());
-    EXPECT_EQ(mojom::ScriptType::kClassic, stub_provider.ScriptType());
+    EXPECT_EQ(mojom::blink::ScriptType::kClassic, stub_provider.ScriptType());
     EXPECT_EQ(mojom::ServiceWorkerUpdateViaCache::kNone,
               stub_provider.UpdateViaCache());
   }
@@ -448,7 +448,7 @@
               stub_provider.RegisterScope());
     EXPECT_EQ(WebURL(KURL(KURL(), "http://localhost/x/y/worker.js")),
               stub_provider.RegisterScriptURL());
-    EXPECT_EQ(mojom::ScriptType::kModule, stub_provider.ScriptType());
+    EXPECT_EQ(mojom::blink::ScriptType::kModule, stub_provider.ScriptType());
     EXPECT_EQ(mojom::ServiceWorkerUpdateViaCache::kImports,
               stub_provider.UpdateViaCache());
   }
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 bd425f6f..07e760c8 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
@@ -356,7 +356,7 @@
 
 void ServiceWorkerGlobalScope::CountWorkerScript(size_t script_size,
                                                  size_t cached_metadata_size) {
-  DCHECK_EQ(GetScriptType(), mojom::ScriptType::kClassic);
+  DCHECK_EQ(GetScriptType(), mojom::blink::ScriptType::kClassic);
   base::UmaHistogramCustomCounts(
       "ServiceWorker.ScriptSize",
       base::saturated_cast<base::Histogram::Sample>(script_size), 1000, 5000000,
@@ -375,7 +375,7 @@
 void ServiceWorkerGlobalScope::CountImportedScript(
     size_t script_size,
     size_t cached_metadata_size) {
-  DCHECK_EQ(GetScriptType(), mojom::ScriptType::kClassic);
+  DCHECK_EQ(GetScriptType(), mojom::blink::ScriptType::kClassic);
   CountScriptInternal(script_size, cached_metadata_size);
 }
 
@@ -388,7 +388,7 @@
   // Skip recording UMAs for module scripts because there're no ways to get the
   // number of static-imported scripts and the total size of the imported
   // scripts.
-  if (GetScriptType() == mojom::ScriptType::kModule) {
+  if (GetScriptType() == mojom::blink::ScriptType::kModule) {
     return;
   }
 
diff --git a/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc b/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
index 43bf734..5135b55c 100644
--- a/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
+++ b/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
@@ -270,7 +270,7 @@
         std::move(outside_settings_object));
     start_data->script_url = script_url_;
     start_data->user_agent = WebString("dummy user agent");
-    start_data->script_type = mojom::ScriptType::kClassic;
+    start_data->script_type = mojom::blink::ScriptType::kClassic;
     start_data->wait_for_debugger_mode =
         WebEmbeddedWorkerStartData::kDontWaitForDebugger;
     return start_data;
diff --git a/third_party/blink/renderer/modules/webgpu/BUILD.gn b/third_party/blink/renderer/modules/webgpu/BUILD.gn
index 5854ec22..1099c436 100644
--- a/third_party/blink/renderer/modules/webgpu/BUILD.gn
+++ b/third_party/blink/renderer/modules/webgpu/BUILD.gn
@@ -48,6 +48,8 @@
     "gpu_pipeline_layout.h",
     "gpu_programmable_pass_encoder.cc",
     "gpu_programmable_pass_encoder.h",
+    "gpu_query_set.cc",
+    "gpu_query_set.h",
     "gpu_queue.cc",
     "gpu_queue.h",
     "gpu_render_bundle.cc",
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
index 823232b..b3290fd 100644
--- a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
+++ b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
@@ -97,6 +97,43 @@
 }
 
 template <>
+WGPUQueryType AsDawnEnum<WGPUQueryType>(const WTF::String& webgpu_enum) {
+  if (webgpu_enum == "occlusion") {
+    return WGPUQueryType_Occlusion;
+  }
+  if (webgpu_enum == "pipeline-statistics") {
+    return WGPUQueryType_PipelineStatistics;
+  }
+  if (webgpu_enum == "timestamp") {
+    return WGPUQueryType_Timestamp;
+  }
+  NOTREACHED();
+  return WGPUQueryType_Force32;
+}
+
+template <>
+WGPUPipelineStatisticName AsDawnEnum<WGPUPipelineStatisticName>(
+    const WTF::String& webgpu_enum) {
+  if (webgpu_enum == "vertex-shader-invocations") {
+    return WGPUPipelineStatisticName_VertexShaderInvocations;
+  }
+  if (webgpu_enum == "clipper-invocations") {
+    return WGPUPipelineStatisticName_ClipperInvocations;
+  }
+  if (webgpu_enum == "clipper-primitives-out") {
+    return WGPUPipelineStatisticName_ClipperPrimitivesOut;
+  }
+  if (webgpu_enum == "fragment-shader-invocations") {
+    return WGPUPipelineStatisticName_FragmentShaderInvocations;
+  }
+  if (webgpu_enum == "compute-shader-invocations") {
+    return WGPUPipelineStatisticName_ComputeShaderInvocations;
+  }
+  NOTREACHED();
+  return WGPUPipelineStatisticName_Force32;
+}
+
+template <>
 WGPUTextureFormat AsDawnEnum<WGPUTextureFormat>(
     const WTF::String& webgpu_enum) {
   if (webgpu_enum.IsNull()) {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
index 969f89b..d868a34 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
@@ -30,6 +30,8 @@
       extension_set.Contains("textureCompressionBC");
   requested_device_properties.shaderFloat16 =
       extension_set.Contains("shader-float16");
+  requested_device_properties.timestampQuery =
+      extension_set.Contains("timestamp-query");
 
   return requested_device_properties;
 }
@@ -81,6 +83,9 @@
   if (adapter_properties_.shaderFloat16) {
     extension_name_list_.emplace_back("shader-float16");
   }
+  if (adapter_properties_.timestampQuery) {
+    extension_name_list_.emplace_back("timestamp-query");
+  }
 }
 
 ScriptPromise GPUAdapter::requestDevice(ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl b/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl
index 4c71723..16b2ead 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl
+++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl
@@ -6,6 +6,7 @@
 
 enum GPUExtensionName {
     "texture-compression-bc",
+    "timestamp-query",
     // Non-standard extension name string. Remove after a transition period.
     "textureCompressionBC",
     "shader-float16"
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 482c48f2..6569866 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
@@ -21,6 +21,7 @@
 #include "third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
+#include "third_party/blink/renderer/modules/webgpu/gpu_query_set.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_texture_view.h"
@@ -323,6 +324,22 @@
   GetProcs().commandEncoderInsertDebugMarker(GetHandle(), label.c_str());
 }
 
+void GPUCommandEncoder::resolveQuerySet(GPUQuerySet* querySet,
+                                        uint32_t firstQuery,
+                                        uint32_t queryCount,
+                                        GPUBuffer* destination,
+                                        uint64_t destinationOffset) {
+  GetProcs().commandEncoderResolveQuerySet(
+      GetHandle(), querySet->GetHandle(), firstQuery, queryCount,
+      destination->GetHandle(), destinationOffset);
+}
+
+void GPUCommandEncoder::writeTimestamp(GPUQuerySet* querySet,
+                                       uint32_t queryIndex) {
+  GetProcs().commandEncoderWriteTimestamp(GetHandle(), querySet->GetHandle(),
+                                          queryIndex);
+}
+
 GPUCommandBuffer* GPUCommandEncoder::finish(
     const GPUCommandBufferDescriptor* descriptor) {
   std::string label;
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 04b36eba..92d221f 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h
@@ -18,6 +18,7 @@
 class GPUCommandEncoderDescriptor;
 class GPUComputePassDescriptor;
 class GPUComputePassEncoder;
+class GPUQuerySet;
 class GPURenderPassDescriptor;
 class GPURenderPassEncoder;
 class GPUTextureCopyView;
@@ -63,6 +64,12 @@
   void pushDebugGroup(String groupLabel);
   void popDebugGroup();
   void insertDebugMarker(String markerLabel);
+  void resolveQuerySet(GPUQuerySet* querySet,
+                       uint32_t firstQuery,
+                       uint32_t queryCount,
+                       GPUBuffer* destination,
+                       uint64_t destinationOffset);
+  void writeTimestamp(GPUQuerySet* querySet, uint32_t queryIndex);
   GPUCommandBuffer* finish(const GPUCommandBufferDescriptor* descriptor);
 
  private:
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl
index 97600ac9..d054757 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl
+++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl
@@ -36,5 +36,14 @@
     void popDebugGroup();
     void insertDebugMarker(USVString markerLabel);
 
+    void resolveQuerySet(
+        GPUQuerySet querySet,
+        GPUSize32 firstQuery,
+        GPUSize32 queryCount,
+        GPUBuffer destination,
+        GPUSize64 destinationOffset);
+
+    void writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex);
+
     GPUCommandBuffer finish(optional GPUCommandBufferDescriptor descriptor = {});
 };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc
index f8baf246..7e4738d4 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc
@@ -8,6 +8,7 @@
 #include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
+#include "third_party/blink/renderer/modules/webgpu/gpu_query_set.h"
 
 namespace blink {
 
@@ -81,6 +82,12 @@
       GetHandle(), indirectBuffer->GetHandle(), indirectOffset);
 }
 
+void GPUComputePassEncoder::writeTimestamp(GPUQuerySet* querySet,
+                                           uint32_t queryIndex) {
+  GetProcs().computePassEncoderWriteTimestamp(
+      GetHandle(), querySet->GetHandle(), queryIndex);
+}
+
 void GPUComputePassEncoder::endPass() {
   GetProcs().computePassEncoderEndPass(GetHandle());
 }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h
index 7d8dead..26cc4d9 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h
@@ -14,6 +14,7 @@
 class GPUBindGroup;
 class GPUBuffer;
 class GPUComputePipeline;
+class GPUQuerySet;
 
 class GPUComputePassEncoder : public DawnObject<WGPUComputePassEncoder>,
                               public GPUProgrammablePassEncoder {
@@ -40,6 +41,7 @@
   void setPipeline(GPUComputePipeline* pipeline);
   void dispatch(uint32_t x, uint32_t y, uint32_t z);
   void dispatchIndirect(GPUBuffer* indirectBuffer, uint64_t indirectOffset);
+  void writeTimestamp(GPUQuerySet* querySet, uint32_t queryIndex);
   void endPass();
 
  private:
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl
index ad0cc80..858b075 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl
+++ b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl
@@ -13,7 +13,7 @@
                   optional GPUSize32 z = 1);
     void dispatchIndirect(GPUBuffer indirectBuffer,
                           GPUSize64 indirectOffset);
-
+    void writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex);
     void endPass();
 };
 GPUComputePassEncoder includes GPUProgrammablePassEncoder;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
index 2202b89..15fb088 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -22,6 +22,7 @@
 #include "third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.h"
+#include "third_party/blink/renderer/modules/webgpu/gpu_query_set.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_queue.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.h"
@@ -220,6 +221,11 @@
   return GPURenderBundleEncoder::Create(this, descriptor);
 }
 
+GPUQuerySet* GPUDevice::createQuerySet(
+    const GPUQuerySetDescriptor* descriptor) {
+  return GPUQuerySet::Create(this, descriptor);
+}
+
 void GPUDevice::pushErrorScope(const WTF::String& filter) {
   GetProcs().devicePushErrorScope(GetHandle(),
                                   AsDawnEnum<WGPUErrorFilter>(filter));
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.h b/third_party/blink/renderer/modules/webgpu/gpu_device.h
index 61d4f8a1..2ebe2bde 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_device.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_device.h
@@ -33,6 +33,8 @@
 class GPUDeviceLostInfo;
 class GPUPipelineLayout;
 class GPUPipelineLayoutDescriptor;
+class GPUQuerySet;
+class GPUQuerySetDescriptor;
 class GPUQueue;
 class GPURenderBundleEncoder;
 class GPURenderBundleEncoderDescriptor;
@@ -96,6 +98,8 @@
   GPURenderBundleEncoder* createRenderBundleEncoder(
       const GPURenderBundleEncoderDescriptor* descriptor);
 
+  GPUQuerySet* createQuerySet(const GPUQuerySetDescriptor* descriptor);
+
   void pushErrorScope(const WTF::String& filter);
   ScriptPromise popErrorScope(ScriptState* script_state);
 
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.idl b/third_party/blink/renderer/modules/webgpu/gpu_device.idl
index 338fe76..aa1da249d 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_device.idl
+++ b/third_party/blink/renderer/modules/webgpu/gpu_device.idl
@@ -28,6 +28,8 @@
     GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {});
     GPURenderBundleEncoder createRenderBundleEncoder(GPURenderBundleEncoderDescriptor descriptor);
 
+    GPUQuerySet createQuerySet(GPUQuerySetDescriptor descriptor);
+
     void pushErrorScope(GPUErrorFilter filter);
     [CallWith=ScriptState] Promise<GPUError?> popErrorScope();
 
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_query_set.cc b/third_party/blink/renderer/modules/webgpu/gpu_query_set.cc
new file mode 100644
index 0000000..ddd49f6
--- /dev/null
+++ b/third_party/blink/renderer/modules/webgpu/gpu_query_set.cc
@@ -0,0 +1,59 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/webgpu/gpu_query_set.h"
+
+#include "gpu/command_buffer/client/webgpu_interface.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_query_set_descriptor.h"
+#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
+#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
+
+namespace blink {
+
+// static
+GPUQuerySet* GPUQuerySet::Create(GPUDevice* device,
+                                 const GPUQuerySetDescriptor* webgpu_desc) {
+  DCHECK(device);
+  DCHECK(webgpu_desc);
+
+  WGPUQuerySetDescriptor dawn_desc = {};
+  dawn_desc.nextInChain = nullptr;
+  dawn_desc.type = AsDawnEnum<WGPUQueryType>(webgpu_desc->type());
+  dawn_desc.count = webgpu_desc->count();
+
+  std::unique_ptr<WGPUPipelineStatisticName[]> pipeline_statistics;
+  if (webgpu_desc->hasPipelineStatistics()) {
+    pipeline_statistics = AsDawnEnum<WGPUPipelineStatisticName>(
+        webgpu_desc->pipelineStatistics());
+    dawn_desc.pipelineStatistics = pipeline_statistics.get();
+    dawn_desc.pipelineStatisticsCount =
+        webgpu_desc->pipelineStatistics().size();
+  }
+
+  std::string label;
+  if (webgpu_desc->hasLabel()) {
+    label = webgpu_desc->label().Utf8();
+    dawn_desc.label = label.c_str();
+  }
+
+  return MakeGarbageCollected<GPUQuerySet>(
+      device,
+      device->GetProcs().deviceCreateQuerySet(device->GetHandle(), &dawn_desc));
+}
+
+GPUQuerySet::GPUQuerySet(GPUDevice* device, WGPUQuerySet querySet)
+    : DawnObject<WGPUQuerySet>(device, querySet) {}
+
+GPUQuerySet::~GPUQuerySet() {
+  if (IsDawnControlClientDestroyed()) {
+    return;
+  }
+  GetProcs().querySetRelease(GetHandle());
+}
+
+void GPUQuerySet::destroy() {
+  GetProcs().querySetDestroy(GetHandle());
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_query_set.h b/third_party/blink/renderer/modules/webgpu/gpu_query_set.h
new file mode 100644
index 0000000..c2674938
--- /dev/null
+++ b/third_party/blink/renderer/modules/webgpu/gpu_query_set.h
@@ -0,0 +1,33 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_QUERY_SET_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_QUERY_SET_H_
+
+#include "third_party/blink/renderer/modules/webgpu/dawn_object.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+
+namespace blink {
+
+class GPUQuerySetDescriptor;
+
+class GPUQuerySet : public DawnObject<WGPUQuerySet> {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  static GPUQuerySet* Create(GPUDevice* device,
+                             const GPUQuerySetDescriptor* webgpu_desc);
+  explicit GPUQuerySet(GPUDevice* device, WGPUQuerySet querySet);
+  ~GPUQuerySet() override;
+
+  // gpu_queryset.idl
+  void destroy();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GPUQuerySet);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_QUERY_SET_H_
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_query_set.idl b/third_party/blink/renderer/modules/webgpu/gpu_query_set.idl
new file mode 100644
index 0000000..d9457806
--- /dev/null
+++ b/third_party/blink/renderer/modules/webgpu/gpu_query_set.idl
@@ -0,0 +1,11 @@
+// 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.
+
+// https://gpuweb.github.io/gpuweb/
+
+[
+    Exposed(Window WebGPU, Worker WebGPU)
+] interface GPUQuerySet {
+    void destroy();
+};
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_query_set_descriptor.idl b/third_party/blink/renderer/modules/webgpu/gpu_query_set_descriptor.idl
new file mode 100644
index 0000000..727f98de
--- /dev/null
+++ b/third_party/blink/renderer/modules/webgpu/gpu_query_set_descriptor.idl
@@ -0,0 +1,25 @@
+// 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.
+
+// https://gpuweb.github.io/gpuweb/
+
+dictionary GPUQuerySetDescriptor : GPUObjectDescriptorBase {
+    required GPUQueryType type;
+    required GPUSize32 count;
+    sequence<GPUPipelineStatisticName> pipelineStatistics = [];
+};
+
+enum GPUQueryType {
+    "occlusion",
+    "pipeline-statistics",
+    "timestamp"
+};
+
+enum GPUPipelineStatisticName {
+    "vertex-shader-invocations",
+    "clipper-invocations",
+    "clipper-primitives-out",
+    "fragment-shader-invocations",
+    "compute-shader-invocations"
+};
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
index 474d871..4ae0188 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -337,6 +337,13 @@
     return;
   }
 
+  // ImageBitmap shouldn't in closed state.
+  if (source->imageBitmap()->IsNeutered()) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+                                      "ImageBitmap is closed.");
+    return;
+  }
+
   scoped_refptr<StaticBitmapImage> image = source->imageBitmap()->BitmapImage();
 
 
@@ -350,10 +357,18 @@
   WGPUOrigin3D origin_in_image_bitmap =
       GPUOrigin2DToWGPUOrigin3D(&(source->origin()));
 
+  // Validate copy depth
+  if (dawn_copy_size.depth > 1) {
+    GetProcs().deviceInjectError(device_->GetHandle(), WGPUErrorType_Validation,
+                                 "Copy depth is out of bounds of imageBitmap.");
+    return;
+  }
+
   // Validate origin value
-  if (static_cast<uint32_t>(image->width()) <= origin_in_image_bitmap.x ||
-      static_cast<uint32_t>(image->height()) <= origin_in_image_bitmap.y) {
-    exception_state.ThrowRangeError(
+  if (static_cast<uint32_t>(image->width()) < origin_in_image_bitmap.x ||
+      static_cast<uint32_t>(image->height()) < origin_in_image_bitmap.y) {
+    GetProcs().deviceInjectError(
+        device_->GetHandle(), WGPUErrorType_Validation,
         "Copy origin is out of bounds of imageBitmap.");
     return;
   }
@@ -361,8 +376,8 @@
   // Validate the copy rect is inside the imageBitmap
   if (image->width() - origin_in_image_bitmap.x < dawn_copy_size.width ||
       image->height() - origin_in_image_bitmap.y < dawn_copy_size.height) {
-    exception_state.ThrowRangeError(
-        "Copy rect is out of bounds of imageBitmap.");
+    GetProcs().deviceInjectError(device_->GetHandle(), WGPUErrorType_Validation,
+                                 "Copy rect is out of bounds of imageBitmap.");
     return;
   }
 
@@ -373,9 +388,12 @@
     return;
   }
 
+  bool isNoopCopy = dawn_copy_size.width == 0 || dawn_copy_size.height == 0 ||
+                    dawn_copy_size.depth == 0;
+
   // TODO(shaobo.yan@intel.com): Implement GPU copy path
-  // Try GPU path first.
-  if (image->IsTextureBacked()) {  // Try GPU uploading path.
+  // Try GPU path first and delegate noop copy to CPU path.
+  if (image->IsTextureBacked() && !isNoopCopy) {  // Try GPU uploading path.
     if (CanUploadThroughGPU(image.get(), destination->texture())) {
       if (CopyContentFromGPU(image.get(), origin_in_image_bitmap,
                              dawn_copy_size, dawn_destination)) {
@@ -405,11 +423,13 @@
   WebGPUImageUploadSizeInfo info = ComputeImageBitmapWebGPUUploadSizeInfo(
       image_data_rect, dest_texture_format);
 
+  bool isNoopCopy = info.size_in_bytes == 0 || copy_size.depth == 0;
+
   // Create a mapped buffer to receive image bitmap contents
   WGPUBufferDescriptor buffer_desc = {};
   buffer_desc.usage = WGPUBufferUsage_CopySrc;
   buffer_desc.size = info.size_in_bytes;
-  buffer_desc.mappedAtCreation = true;
+  buffer_desc.mappedAtCreation = !isNoopCopy;
 
   if (buffer_desc.size > uint64_t(std::numeric_limits<size_t>::max())) {
     return false;
@@ -418,18 +438,23 @@
 
   WGPUBuffer buffer =
       GetProcs().deviceCreateBuffer(device_->GetHandle(), &buffer_desc);
-  void* data = GetProcs().bufferGetMappedRange(buffer, 0, size);
 
-  if (!CopyBytesFromImageBitmapForWebGPU(
-          image, base::span<uint8_t>(static_cast<uint8_t*>(data), size),
-          image_data_rect, dest_texture_format)) {
-    // Release the buffer.
-    GetProcs().bufferRelease(buffer);
-    return false;
+  // Bypass extract source content in noop copy but follow the copy path
+  // for validation.
+  if (!isNoopCopy) {
+    void* data = GetProcs().bufferGetMappedRange(buffer, 0, size);
+
+    if (!CopyBytesFromImageBitmapForWebGPU(
+            image, base::span<uint8_t>(static_cast<uint8_t*>(data), size),
+            image_data_rect, dest_texture_format)) {
+      // Release the buffer.
+      GetProcs().bufferRelease(buffer);
+      return false;
+    }
+
+    GetProcs().bufferUnmap(buffer);
   }
 
-  GetProcs().bufferUnmap(buffer);
-
   // Start a B2T copy to move contents from buffer to destination texture
   WGPUBufferCopyView dawn_intermediate = {};
   dawn_intermediate.nextInChain = nullptr;
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 128382c..d13bb104 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
@@ -10,6 +10,7 @@
 #include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
+#include "third_party/blink/renderer/modules/webgpu/gpu_query_set.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.h"
 
@@ -178,6 +179,12 @@
                                              dawn_bundles.get());
 }
 
+void GPURenderPassEncoder::writeTimestamp(GPUQuerySet* querySet,
+                                          uint32_t queryIndex) {
+  GetProcs().renderPassEncoderWriteTimestamp(GetHandle(), querySet->GetHandle(),
+                                             queryIndex);
+}
+
 void GPURenderPassEncoder::endPass() {
   GetProcs().renderPassEncoderEndPass(GetHandle());
 }
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 c92a1941..cfbb33e 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
@@ -16,6 +16,7 @@
 class DoubleSequenceOrGPUColorDict;
 class GPURenderBundle;
 class GPURenderPipeline;
+class GPUQuerySet;
 
 class GPURenderPassEncoder : public DawnObject<WGPURenderPassEncoder>,
                              public GPUProgrammablePassEncoder {
@@ -73,6 +74,7 @@
   void drawIndirect(GPUBuffer* indirectBuffer, uint64_t indirectOffset);
   void drawIndexedIndirect(GPUBuffer* indirectBuffer, uint64_t indirectOffset);
   void executeBundles(const HeapVector<Member<GPURenderBundle>>& bundles);
+  void writeTimestamp(GPUQuerySet* querySet, uint32_t queryIndex);
   void endPass();
 
  private:
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl
index 6d817591..6ac8535e 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl
+++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl
@@ -18,6 +18,7 @@
     void setStencilReference(GPUStencilValue reference);
 
     void executeBundles(sequence<GPURenderBundle> bundles);
+    void writeTimestamp(GPUQuerySet querySet, GPUSize32 queryIndex);
     void endPass();
 };
 GPURenderPassEncoder includes GPUProgrammablePassEncoder;
diff --git a/third_party/blink/renderer/modules/webgpu/idls.gni b/third_party/blink/renderer/modules/webgpu/idls.gni
index c4cc0634..31dad915 100644
--- a/third_party/blink/renderer/modules/webgpu/idls.gni
+++ b/third_party/blink/renderer/modules/webgpu/idls.gni
@@ -21,6 +21,7 @@
   "gpu_map_mode.idl",
   "gpu_out_of_memory_error.idl",
   "gpu_pipeline_layout.idl",
+  "gpu_query_set.idl",
   "gpu_queue.idl",
   "gpu_render_bundle.idl",
   "gpu_render_bundle_encoder.idl",
@@ -64,6 +65,7 @@
   "gpu_pipeline_descriptor_base.idl",
   "gpu_pipeline_layout_descriptor.idl",
   "gpu_programmable_stage_descriptor.idl",
+  "gpu_query_set_descriptor.idl",
   "gpu_rasterization_state_descriptor.idl",
   "gpu_render_bundle_descriptor.idl",
   "gpu_render_bundle_encoder_descriptor.idl",
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc
index fe097f83..03e2f22c 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc
@@ -80,6 +80,8 @@
   DCHECK_GT(dst.size(), static_cast<size_t>(0));
   DCHECK(image->width() - rect.X() >= rect.Width());
   DCHECK(image->height() - rect.Y() >= rect.Height());
+  DCHECK(rect.Width());
+  DCHECK(rect.Height());
 
   WebGPUImageUploadSizeInfo wgpu_info =
       ComputeImageBitmapWebGPUUploadSizeInfo(rect, destination_format);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.cc b/third_party/blink/renderer/platform/loader/fetch/resource.cc
index ecb254c3..3265d12 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -477,10 +477,14 @@
   return redirect_chain_.back().request_;
 }
 
-const ResourceResponse* Resource::LastResourceResponse() const {
+const ResourceResponse& Resource::LastResourceResponse() const {
   if (!redirect_chain_.size())
-    return nullptr;
-  return &redirect_chain_.back().redirect_response_;
+    return GetResponse();
+  return redirect_chain_.back().redirect_response_;
+}
+
+size_t Resource::RedirectChainSize() const {
+  return redirect_chain_.size();
 }
 
 void Resource::SetRevalidatingRequest(const ResourceRequestHead& request) {
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.h b/third_party/blink/renderer/platform/loader/fetch/resource.h
index e9ef3dba..5ef043e5 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -169,7 +169,9 @@
     return resource_request_;
   }
   const ResourceRequestHead& LastResourceRequest() const;
-  const ResourceResponse* LastResourceResponse() const;
+  const ResourceResponse& LastResourceResponse() const;
+  // Returns zero if there are no redirects.
+  size_t RedirectChainSize() const;
 
   virtual void SetRevalidatingRequest(const ResourceRequestHead&);
 
diff --git a/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-iframe-tests.sub.js b/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-iframe-tests.sub.js
index 513b4c7..11c9f50 100644
--- a/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-iframe-tests.sub.js
+++ b/third_party/blink/web_tests/external/wpt/generic-sensor/generic-sensor-iframe-tests.sub.js
@@ -126,7 +126,6 @@
     await sensorWatcher.wait_for('reading');
     assert_greater_than(sensor.timestamp, cachedTimeStamp);
     sensor.stop();
-    await send_message_to_iframe(iframe, {command: 'reset_sensor_backend'});
   }, `${sensorName}: sensor is not suspended when focus traverses from\
  to same-origin frame`);
 
diff --git a/third_party/blink/web_tests/external/wpt/generic-sensor/resources/iframe_sensor_handler.html b/third_party/blink/web_tests/external/wpt/generic-sensor/resources/iframe_sensor_handler.html
index e2dfab5..23e8e1b 100644
--- a/third_party/blink/web_tests/external/wpt/generic-sensor/resources/iframe_sensor_handler.html
+++ b/third_party/blink/web_tests/external/wpt/generic-sensor/resources/iframe_sensor_handler.html
@@ -7,52 +7,33 @@
   let sensor = null;
   let sensorType = null;
 
-  function postReply(event, reply) {
-    event.source.postMessage({ command: event.data.command, result: reply }, '*');
-  }
-
-  window.onmessage = async (e) => {
+  async function messageHandler(e) {
     if (e.data.command === 'create_sensor') {
-      if (sensor) {
-        postReply(e, 'success');
-        return;
-      }
-
-      try {
+      if (!sensor) {
         mockBackend = await initialize_generic_sensor_tests();
         sensor = new self[e.data.type]();
         sensorType = e.data.type;
-
-        postReply(e, 'success');
-      } catch (error) {
-        postReply(e, error);
       }
+
+      return Promise.resolve('success');
     } else if (e.data.command === 'start_sensor') {
       if (!sensor) {
-        postReply(e, '"create_sensor" must be called first');
-        return;
+        return Promise.reject('"create_sensor" must be called first');
       }
 
-      try {
+      return new Promise(resolve => {
         sensor.addEventListener('reading', () => {
-          postReply(e, 'success');
+          resolve('success');
         }, { once: true });
         sensor.start();
-      } catch (error) {
-        postReply(e, error);
-      }
+      });
     } else if (e.data.command === 'is_sensor_suspended') {
       if (!mockBackend) {
-        postReply(e, '"create_sensor" must be called first');
-        return;
+        return Promise.reject('"create_sensor" must be called first');
       }
 
-      try {
-        const mockPlatformSensor = await mockBackend.getSensorProvider().getCreatedSensor(sensorType);
-        postReply(e, !mockPlatformSensor.isReadingData());
-      } catch (error) {
-        postReply(e, error);
-      }
+      const mockPlatformSensor = await mockBackend.getSensorProvider().getCreatedSensor(sensorType);
+      return Promise.resolve(!mockPlatformSensor.isReadingData());
     } else if (e.data.command === 'reset_sensor_backend') {
       if (sensor) {
         sensor.stop();
@@ -61,8 +42,19 @@
         sensor = null;
         mockBackend = null;
       }
-
-      postReply(e, 'success');
+      return Promise.resolve('success');
+    } else {
+      return Promise.reject(`unknown command "${e.data.command}"`);
     }
   }
+
+  window.onmessage = async (e) => {
+    let reply;
+    try {
+      reply = await messageHandler(e);
+    } catch (error) {
+      reply = error;
+    }
+    e.source.postMessage({ command: e.data.command, result: reply }, '*');
+  }
 </script>
diff --git a/third_party/blink/web_tests/wpt_internal/ambient-light/illuminance-rounding.https.window.js b/third_party/blink/web_tests/wpt_internal/ambient-light/illuminance-rounding.https.window.js
new file mode 100644
index 0000000..d4a0cbc
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/ambient-light/illuminance-rounding.https.window.js
@@ -0,0 +1,51 @@
+// META: script=/generic-sensor/resources/generic-sensor-helpers.js
+
+'use strict';
+
+sensor_test(async (t, sensorProvider) => {
+  const sensor = new AmbientLightSensor({
+    frequency: 10  // 10Hz is the maximum frequency allowed by the Blink
+                   // implementation.
+  });
+  t.add_cleanup(() => {
+    sensor.stop();
+  });
+  const eventWatcher =
+      new EventWatcher(t, sensor, ['activate', 'reading', 'error']);
+
+  sensor.start();
+  await eventWatcher.wait_for('activate');
+  assert_false(
+      sensor.hasReading, 'Sensor has no readings immediately after activation');
+  assert_equals(
+      sensor.illuminance, null,
+      'Sensor must have no illuminance immediately after activation');
+
+  const mockSensor =
+      await sensorProvider.getCreatedSensor('AmbientLightSensor');
+  await mockSensor.setSensorReading([[24], [35], [49], [35], [24]]);
+
+  // This loop checks that illuminance rounding causes the following to happen:
+  // 1. The first ever reading goes from nothing to 24. A new "reading" event is
+  // emitted and the rounded illuminance value is 0.
+  // 2. Going from 24 to 35 is not significant enough. No "reading" event is
+  // emitted and the illuminance value remains the same.
+  // 3. Going from 24 to 49 is significant enough. A "reading" event is emitted
+  // and the rounded illuminance value is 50.
+  // 4. Going from 49 to 35 is not significant enough. No "reading" event is
+  // emitted and the illuminance value remains the same.
+  // 5. Going from 49 to 24 is significant enough. A "reading" event is emitted
+  // and the rounded illuminance value is 0.
+  // 6. We are back to the first raw reading value. We are at 24 and get 24, so
+  // nothing happens.
+  // 7. Go to step 3.
+  for (let i = 0; i < 3; i++) {
+    await eventWatcher.wait_for('reading');
+    assert_true(sensor.hasReading);
+    assert_equals(sensor.illuminance, 0, 'Rounded illuminance should be 0');
+
+    await eventWatcher.wait_for('reading');
+    assert_true(sensor.hasReading);
+    assert_equals(sensor.illuminance, 50, 'Rounded illuminance should be 50');
+  }
+}, 'Illuminance rounding');
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index e64bd11..fed5580 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -43704,6 +43704,8 @@
       label="HappinessTrackingSurveysForDesktopSettingsPrivacy:disabled"/>
   <int value="966415988" label="SyncPseudoUSSPasswords:enabled"/>
   <int value="968355926" label="ExportTaggedPDF:enabled"/>
+  <int value="968715406"
+      label="enable-experimental-accessibility-magnifier-new-focus-following"/>
   <int value="969340095" label="EnableDspHotword:disabled"/>
   <int value="972228058" label="SyncUSSSessions:disabled"/>
   <int value="973601997" label="SafeBrowsingUseLocalBlacklistsV2:disabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 8854b8f8..99274dbf 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -59058,6 +59058,19 @@
   </summary>
 </histogram>
 
+<histogram name="FamilyUser.SessionEngagement.Duration" units="ms"
+    expires_after="2021-07-14">
+  <owner>agawronska@chromium.org</owner>
+  <owner>tobyhuang@chromium.org</owner>
+  <owner>xiqiruan@chromium.org</owner>
+  <owner>cros-families-eng@google.com</owner>
+  <summary>
+    Records the Chrome OS user session duration in milliseconds. Reports current
+    daily duration at the first session start on next day. This is only logged
+    for active usage time of device, determined by UsageTimeState::ACTIVE.
+  </summary>
+</histogram>
+
 <histogram name="FamilyUser.SessionEngagement.Total" units="Hour of day"
     expires_after="2021-07-14">
   <owner>agawronska@chromium.org</owner>
@@ -69076,8 +69089,9 @@
 </histogram>
 
 <histogram name="Installer.Recovery.Reason" enum="ChromeOSRecoveryReason"
-    expires_after="M85">
-  <owner>lannm@chromium.org</owner>
+    expires_after="2021-12-29">
+  <owner>kimjae@chromium.org</owner>
+  <owner>chromeos-core-services@google.com</owner>
   <summary>
     The reason for entering recovery mode immediately prior to a recovery.
 
@@ -89651,8 +89665,9 @@
 </histogram>
 
 <histogram name="NativeSmbFileShare.AuthenticationMethod"
-    enum="NativeSmbFileShare_AuthMethod" expires_after="M85">
-  <owner>zentaro@chromium.org</owner>
+    enum="NativeSmbFileShare_AuthMethod" expires_after="M94">
+  <owner>simmonsjosh@google.com</owner>
+  <owner>src/chrome/browser/chromeos/smb_client/OWNERS</owner>
   <summary>
     The method used to authenticate to a share. This is called on each attempted
     mount.
@@ -118944,7 +118959,8 @@
   </summary>
 </histogram>
 
-<histogram name="P2P.Server.ClientCount" units="count" expires_after="M85">
+<histogram name="P2P.Server.ClientCount" units="count"
+    expires_after="2021-12-29">
   <owner>ahassani@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -121942,7 +121958,7 @@
 
 <histogram
     name="PageLoad.Experimental.PaintTiming.ParseStartToFirstMeaningfulPaint"
-    units="ms" expires_after="2020-09-27">
+    units="ms" expires_after="2021-03-27">
   <owner>ksakamoto@chromium.org</owner>
   <owner>speed-metrics-dev@chromium.org</owner>
   <summary>
@@ -147036,8 +147052,8 @@
 </histogram>
 
 <histogram name="SafeBrowsing.AdvancedProtection.APTokenFetchStatus"
-    enum="GoogleServiceAuthError" expires_after="M85">
-  <owner>vakh@chromium.org</owner>
+    enum="GoogleServiceAuthError" expires_after="M90">
+  <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
     For users known to be already enrolled in Advanced Proection, records the
@@ -147049,8 +147065,8 @@
 </histogram>
 
 <histogram name="SafeBrowsing.AdvancedProtection.TokenFetchStatus"
-    enum="GoogleServiceAuthError" expires_after="M85">
-  <owner>vakh@chromium.org</owner>
+    enum="GoogleServiceAuthError" expires_after="M90">
+  <owner>drubey@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
     Records the service error of refreshing OAuth2 access token during fetching
@@ -149345,7 +149361,7 @@
 </histogram>
 
 <histogram name="SafeBrowsingBinaryUploadRequest.DlpResult"
-    enum="BooleanSuccess" expires_after="M85">
+    enum="BooleanSuccess" expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -149356,7 +149372,7 @@
 </histogram>
 
 <histogram name="SafeBrowsingBinaryUploadRequest.Duration" units="ms"
-    expires_after="M85">
+    expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -149367,7 +149383,7 @@
 </histogram>
 
 <histogram name="SafeBrowsingBinaryUploadRequest.MalwareResult"
-    enum="BooleanSuccess" expires_after="M85">
+    enum="BooleanSuccess" expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -149390,7 +149406,7 @@
 </histogram>
 
 <histogram name="SafeBrowsingBinaryUploadRequest.Result"
-    enum="SafeBrowsingBinaryUploadResult" expires_after="M85">
+    enum="SafeBrowsingBinaryUploadResult" expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -149411,7 +149427,7 @@
 </histogram>
 
 <histogram name="SafeBrowsingBinaryUploadRequest.TimeToGetToken" units="ms"
-    expires_after="M85">
+    expires_after="M90">
   <obsolete>
     Removed 06/2020 as SafeBrowsingBinaryUploadRequest.TimeToGetFCMToken
     provides the same information with a better range of durations.
@@ -149425,7 +149441,7 @@
 </histogram>
 
 <histogram name="SafeBrowsingFCMService.IncomingMessageHasKey" enum="Boolean"
-    expires_after="M85">
+    expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -149435,7 +149451,7 @@
 </histogram>
 
 <histogram name="SafeBrowsingFCMService.IncomingMessageHasValidToken"
-    enum="Boolean" expires_after="M85">
+    enum="Boolean" expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -149446,7 +149462,7 @@
 </histogram>
 
 <histogram name="SafeBrowsingFCMService.IncomingMessageParsedBase64"
-    enum="BooleanSuccess" expires_after="M85">
+    enum="BooleanSuccess" expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -149457,7 +149473,7 @@
 </histogram>
 
 <histogram name="SafeBrowsingFCMService.IncomingMessageParsedProto"
-    enum="BooleanSuccess" expires_after="M85">
+    enum="BooleanSuccess" expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -152652,7 +152668,7 @@
 </histogram>
 
 <histogram name="SBMultipartUploader.FailedUploadDuration" units="s"
-    expires_after="M85">
+    expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -152663,7 +152679,7 @@
 </histogram>
 
 <histogram name="SBMultipartUploader.NetworkRequestResponseCodeOrError"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="M85">
+    enum="CombinedHttpResponseAndNetErrorCode" expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -152675,7 +152691,7 @@
 </histogram>
 
 <histogram name="SBMultipartUploader.RetriesNeeded" units="retries"
-    expires_after="M85">
+    expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -152685,7 +152701,7 @@
 </histogram>
 
 <histogram name="SBMultipartUploader.SuccessfulUploadDuration" units="s"
-    expires_after="M85">
+    expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -152695,7 +152711,7 @@
 </histogram>
 
 <histogram name="SBMultipartUploader.UploadSize" units="bytes"
-    expires_after="M85">
+    expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -152706,7 +152722,7 @@
 </histogram>
 
 <histogram name="SBMultipartUploader.UploadSuccess" enum="BooleanSuccess"
-    expires_after="M85">
+    expires_after="M90">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -173965,7 +173981,7 @@
 </histogram>
 
 <histogram name="Sync.BookmarksWithoutFullTitle.OnInitialMerge"
-    units="bookmarks" expires_after="M87">
+    units="bookmarks" expires_after="M89">
   <owner>rushans@google.com</owner>
   <owner>mastiz@chromiumg.org</owner>
   <summary>
@@ -173975,7 +173991,7 @@
 </histogram>
 
 <histogram name="Sync.BookmarksWithoutFullTitle.OnRemoteUpdate"
-    units="bookmarks" expires_after="M87">
+    units="bookmarks" expires_after="M89">
   <owner>rushans@google.com</owner>
   <owner>mastiz@chromiumg.org</owner>
   <summary>
@@ -182330,7 +182346,7 @@
 </histogram>
 
 <histogram name="Translate.ExplicitLanguageAsk.Event"
-    enum="TranslateExplicitAskPromptEventType" expires_after="M85">
+    enum="TranslateExplicitAskPromptEventType" expires_after="2021-01-31">
   <owner>yyushkina@google.com</owner>
   <owner>anthonyvd@google.com</owner>
   <owner>chrome-language@google.com</owner>
@@ -182341,7 +182357,7 @@
 </histogram>
 
 <histogram name="Translate.ExplicitLanguageAsk.LanguageAdded"
-    enum="CLD3LanguageCode" expires_after="M85">
+    enum="CLD3LanguageCode" expires_after="2021-01-31">
   <owner>yyushkina@google.com</owner>
   <owner>anthonyvd@google.com</owner>
   <owner>chrome-language@google.com</owner>
@@ -182352,7 +182368,7 @@
 </histogram>
 
 <histogram name="Translate.ExplicitLanguageAsk.LanguageRemoved"
-    enum="CLD3LanguageCode" expires_after="M85">
+    enum="CLD3LanguageCode" expires_after="2021-01-31">
   <owner>yyushkina@google.com</owner>
   <owner>anthonyvd@google.com</owner>
   <owner>chrome-language@google.com</owner>
@@ -182522,7 +182538,7 @@
 </histogram>
 
 <histogram name="Translate.LocalesOnDisabledByPrefs" enum="LanguageCode"
-    expires_after="M85">
+    expires_after="2021-01-31">
   <owner>kenjibaheux@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -182694,7 +182710,7 @@
 </histogram>
 
 <histogram name="Translate.ReportLanguageDetectionError" units="units"
-    expires_after="2020-12-01">
+    expires_after="2021-01-31">
   <owner>kenjibaheux@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -182739,9 +182755,9 @@
 </histogram>
 
 <histogram name="Translate.ShowErrorInfobar" enum="TranslateError"
-    expires_after="2020-12-01">
+    expires_after="2020-09-18">
   <obsolete>
-    Removed 6/2020. Duplicate of Translate.ShowErrorUI
+    Removed 06/2020. Duplicate of Translate.ShowErrorUI
   </obsolete>
   <owner>chrome-language@google.com</owner>
   <owner>kenjibaheux@google.com</owner>
diff --git a/ui/accessibility/accessibility_switches.cc b/ui/accessibility/accessibility_switches.cc
index 3fa41e0..09ce94e 100644
--- a/ui/accessibility/accessibility_switches.cc
+++ b/ui/accessibility/accessibility_switches.cc
@@ -40,6 +40,11 @@
 const char kEnableExperimentalAccessibilityChromeVoxTutorial[] =
     "enable-experimental-accessibility-chromevox-tutorial";
 
+// Enables new magnifier focus following feature, which provides richer focus
+// following experience.
+const char kEnableExperimentalAccessibilityMagnifierNewFocusFollowing[] =
+    "enable-experimental-accessibility-magnifier-new-focus-following";
+
 // Enables Switch Access point scanning. This feature hasn't launched yet.
 const char kEnableSwitchAccessPointScanning[] =
     "enable-switch-access-point-scanning";
diff --git a/ui/accessibility/accessibility_switches.h b/ui/accessibility/accessibility_switches.h
index 9142a13..ad01597 100644
--- a/ui/accessibility/accessibility_switches.h
+++ b/ui/accessibility/accessibility_switches.h
@@ -24,6 +24,8 @@
     kEnableExperimentalAccessibilityChromeVoxAnnotations[];
 AX_BASE_EXPORT extern const char
     kEnableExperimentalAccessibilityChromeVoxTutorial[];
+AX_BASE_EXPORT extern const char
+    kEnableExperimentalAccessibilityMagnifierNewFocusFollowing[];
 AX_BASE_EXPORT extern const char kEnableSwitchAccessPointScanning[];
 
 // Returns true if experimental accessibility language detection is enabled.
diff --git a/ui/base/ime/chromeos/input_method_util.cc b/ui/base/ime/chromeos/input_method_util.cc
index 51334fd..6277435 100644
--- a/ui/base/ime/chromeos/input_method_util.cc
+++ b/ui/base/ime/chromeos/input_method_util.cc
@@ -230,7 +230,9 @@
     {"__MSG_KEYBOARD_ARMENIAN_PHONETIC__",
      IDS_IME_NAME_KEYBOARD_ARMENIAN_PHONETIC},
     {"__MSG_KEYBOARD_BELARUSIAN__", IDS_IME_NAME_KEYBOARD_BELARUSIAN},
-    {"__MSG_KEYBOARD_BELGIAN__", IDS_IME_NAME_KEYBOARD_BELGIAN},
+    {"__MSG_KEYBOARD_BELGIAN_DUTCH__", IDS_IME_NAME_KEYBOARD_BELGIAN_DUTCH},
+    {"__MSG_KEYBOARD_BELGIAN_FRENCH__", IDS_IME_NAME_KEYBOARD_BELGIAN_FRENCH},
+    {"__MSG_KEYBOARD_BELGIAN_GERMAN__", IDS_IME_NAME_KEYBOARD_BELGIAN_GERMAN},
     {"__MSG_KEYBOARD_BENGALI_PHONETIC__",
      IDS_IME_NAME_KEYBOARD_BENGALI_PHONETIC},
     {"__MSG_KEYBOARD_BRAZILIAN__", IDS_IME_NAME_KEYBOARD_BRAZILIAN},
@@ -280,19 +282,25 @@
     {"__MSG_KEYBOARD_LATVIAN__", IDS_IME_NAME_KEYBOARD_LATVIAN},
     {"__MSG_KEYBOARD_LITHUANIAN__", IDS_IME_NAME_KEYBOARD_LITHUANIAN},
     {"__MSG_KEYBOARD_MACEDONIAN__", IDS_IME_NAME_KEYBOARD_MACEDONIAN},
-    {"__MSG_KEYBOARD_MALAY__", IDS_IME_NAME_KEYBOARD_MALAY},
     {"__MSG_KEYBOARD_MALAYALAM_PHONETIC__",
      IDS_IME_NAME_KEYBOARD_MALAYALAM_PHONETIC},
+    {"__MSG_KEYBOARD_MALAY__", IDS_IME_NAME_KEYBOARD_MALAY},
     {"__MSG_KEYBOARD_MALTESE__", IDS_IME_NAME_KEYBOARD_MALTESE},
     {"__MSG_KEYBOARD_MONGOLIAN__", IDS_IME_NAME_KEYBOARD_MONGOLIAN},
     {"__MSG_KEYBOARD_MYANMAR_MYANSAN__", IDS_IME_NAME_KEYBOARD_MYANMAR_MYANSAN},
     {"__MSG_KEYBOARD_MYANMAR__", IDS_IME_NAME_KEYBOARD_MYANMAR},
     {"__MSG_KEYBOARD_NEPALI_INSCRIPT__", IDS_IME_NAME_KEYBOARD_NEPALI_INSCRIPT},
     {"__MSG_KEYBOARD_NEPALI_PHONETIC__", IDS_IME_NAME_KEYBOARD_NEPALI_PHONETIC},
+    {"__MSG_KEYBOARD_NETHERLANDS_US_INTERNATIONAL_PC__",
+     IDS_IME_NAME_KEYBOARD_NETHERLANDS_US_INTERNATIONAL_PC},
     {"__MSG_KEYBOARD_NETHERLANDS__", IDS_IME_NAME_KEYBOARD_NETHERLANDS},
     {"__MSG_KEYBOARD_NORWEGIAN__", IDS_IME_NAME_KEYBOARD_NORWEGIAN},
     {"__MSG_KEYBOARD_PERSIAN__", IDS_IME_NAME_KEYBOARD_PERSIAN},
     {"__MSG_KEYBOARD_POLISH__", IDS_IME_NAME_KEYBOARD_POLISH},
+    {"__MSG_KEYBOARD_PORTUGUESE_US_INTERNATIONAL_PC__",
+     IDS_IME_NAME_KEYBOARD_PORTUGUESE_US_INTERNATIONAL_PC},
+    {"__MSG_KEYBOARD_PORTUGUESE_US_INTERNATIONAL__",
+     IDS_IME_NAME_KEYBOARD_PORTUGUESE_US_INTERNATIONAL},
     {"__MSG_KEYBOARD_PORTUGUESE__", IDS_IME_NAME_KEYBOARD_PORTUGUESE},
     {"__MSG_KEYBOARD_ROMANIAN_STANDARD__",
      IDS_IME_NAME_KEYBOARD_ROMANIAN_STANDARD},
@@ -517,23 +525,9 @@
     return base::UTF8ToUTF16(localized_display_name);
   }
 
-  // We don't show language here.  Name of keyboard layout or input method
-  // usually imply (or explicitly include) its language.
-  // Special case for German, French and Dutch: these languages have multiple
-  // keyboard layouts and share the same layout of keyboard (Belgian). We need
-  // to show explicitly the language for the layout.
-  DCHECK(!input_method.language_codes().empty());
-  const std::string language_code = input_method.language_codes().at(0);
-
   base::string16 text = (short_name || localized_display_name.empty())
                             ? TranslateString(input_method.id())
                             : base::UTF8ToUTF16(localized_display_name);
-  if (language_code == "de" || language_code == "fr" || language_code == "nl") {
-    const base::string16 language_name = delegate_->GetDisplayLanguageName(
-        language_code);
-    text = language_name + base::UTF8ToUTF16(" - ") + text;
-  }
-
   DCHECK(!text.empty());
   return text;
 }
diff --git a/ui/base/ime/chromeos/input_method_util_unittest.cc b/ui/base/ime/chromeos/input_method_util_unittest.cc
index 38d42bbd..b51c1df 100644
--- a/ui/base/ime/chromeos/input_method_util_unittest.cc
+++ b/ui/base/ime/chromeos/input_method_util_unittest.cc
@@ -205,8 +205,7 @@
 }
 
 TEST_F(InputMethodUtilTest, GetInputMethodLongNameTest) {
-  // For most languages input method or keyboard layout name is returned.
-  // See below for exceptions.
+  // Input method or keyboard layout name is returned.
   {
     InputMethodDescriptor desc = GetDesc("xkb:jp::jpn", "jp", "ja", "");
     EXPECT_EQ(ASCIIToUTF16("Japanese"), util_.GetInputMethodLongName(desc));
@@ -221,35 +220,6 @@
         GetDesc("xkb:gb:dvorak:eng", "gb(dvorak)", "en-US", "");
     EXPECT_EQ(ASCIIToUTF16("UK Dvorak"), util_.GetInputMethodLongName(desc));
   }
-
-  // For Dutch, French, German and Hindi,
-  // "language - keyboard layout" pair is returned.
-  {
-    InputMethodDescriptor desc = GetDesc("xkb:be::nld", "be", "nl", "");
-    EXPECT_EQ(ASCIIToUTF16("Dutch - Belgian"),
-              util_.GetInputMethodLongName(desc));
-  }
-  {
-    InputMethodDescriptor desc = GetDesc("xkb:fr::fra", "fr", "fr", "");
-    EXPECT_EQ(ASCIIToUTF16("French - French"),
-              util_.GetInputMethodLongName(desc));
-  }
-  {
-    InputMethodDescriptor desc = GetDesc("xkb:be::fra", "be", "fr", "");
-    EXPECT_EQ(ASCIIToUTF16("French - Belgian"),
-              util_.GetInputMethodLongName(desc));
-  }
-  {
-    InputMethodDescriptor desc = GetDesc("xkb:de::ger", "de", "de", "");
-    EXPECT_EQ(ASCIIToUTF16("German - German"),
-              util_.GetInputMethodLongName(desc));
-  }
-  {
-    InputMethodDescriptor desc = GetDesc("xkb:be::ger", "be", "de", "");
-    EXPECT_EQ(ASCIIToUTF16("German - Belgian"),
-              util_.GetInputMethodLongName(desc));
-  }
-
   {
     InputMethodDescriptor desc = GetDesc("invalid-id", "us", "xx", "");
     // You can safely ignore the "Resouce ID is not found for: invalid-id"
diff --git a/ui/chromeos/ui_chromeos_strings.grd b/ui/chromeos/ui_chromeos_strings.grd
index 0c1b696..8834625 100644
--- a/ui/chromeos/ui_chromeos_strings.grd
+++ b/ui/chromeos/ui_chromeos_strings.grd
@@ -713,8 +713,14 @@
       <message name="IDS_IME_NAME_KEYBOARD_BELARUSIAN" desc="The input method name shows in system tray menu, this shows [Belarusian keyboard].">
         Belarusian keyboard
       </message>
-      <message name="IDS_IME_NAME_KEYBOARD_BELGIAN" desc="The input method name shows in system tray menu, this shows [Belgian keyboard].">
-        Belgian keyboard
+      <message name="IDS_IME_NAME_KEYBOARD_BELGIAN_DUTCH" desc="The input method name shows in system tray menu and settings page.">
+        Dutch (Belgium)
+      </message>
+      <message name="IDS_IME_NAME_KEYBOARD_BELGIAN_FRENCH" desc="The input method name shows in system tray menu and settings page.">
+        French (Belgium)
+      </message>
+      <message name="IDS_IME_NAME_KEYBOARD_BELGIAN_GERMAN" desc="The input method name shows in system tray menu and settings page.">
+        German (Belgium)
       </message>
       <message name="IDS_IME_NAME_KEYBOARD_BRAZILIAN" desc="The input method name shows in system tray menu, this shows [Brazilian keyboard].">
         Brazilian keyboard
@@ -827,6 +833,9 @@
       <message name="IDS_IME_NAME_KEYBOARD_MONGOLIAN" desc="The input method name shows in system tray menu, this shows [Mongolian keyboard].">
         Mongolian keyboard
       </message>
+      <message name="IDS_IME_NAME_KEYBOARD_NETHERLANDS_US_INTERNATIONAL_PC" desc="The input method name shows in system tray menu and settings page.">
+        Dutch (Netherlands) with US International PC keyboard
+      </message>
       <message name="IDS_IME_NAME_KEYBOARD_NETHERLANDS" desc="The input method name shows in system tray menu, this shows [Netherlands keyboard].">
         Netherlands keyboard
       </message>
@@ -839,6 +848,12 @@
       <message name="IDS_IME_NAME_KEYBOARD_PORTUGUESE" desc="The input method name shows in system tray menu, this shows [Portuguese keyboard].">
         Portuguese keyboard
       </message>
+      <message name="IDS_IME_NAME_KEYBOARD_PORTUGUESE_US_INTERNATIONAL" desc="The input method name shows in system tray menu and settings page.">
+        Portuguese with US International keyboard
+      </message>
+      <message name="IDS_IME_NAME_KEYBOARD_PORTUGUESE_US_INTERNATIONAL_PC" desc="The input method name shows in system tray menu and settings page.">
+        Portuguese with US International PC keyboard
+      </message>
       <message name="IDS_IME_NAME_KEYBOARD_ROMANIAN" desc="The input method name shows in system tray menu, this shows [Romanian keyboard].">
         Romanian keyboard
       </message>
diff --git a/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_BELGIAN_DUTCH.png.sha1 b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_BELGIAN_DUTCH.png.sha1
new file mode 100644
index 0000000..913e4af
--- /dev/null
+++ b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_BELGIAN_DUTCH.png.sha1
@@ -0,0 +1 @@
+ffc8137ab73851b32db79559d9245fad97f8017f
\ No newline at end of file
diff --git a/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_BELGIAN_FRENCH.png.sha1 b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_BELGIAN_FRENCH.png.sha1
new file mode 100644
index 0000000..913e4af
--- /dev/null
+++ b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_BELGIAN_FRENCH.png.sha1
@@ -0,0 +1 @@
+ffc8137ab73851b32db79559d9245fad97f8017f
\ No newline at end of file
diff --git a/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_BELGIAN_GERMAN.png.sha1 b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_BELGIAN_GERMAN.png.sha1
new file mode 100644
index 0000000..913e4af
--- /dev/null
+++ b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_BELGIAN_GERMAN.png.sha1
@@ -0,0 +1 @@
+ffc8137ab73851b32db79559d9245fad97f8017f
\ No newline at end of file
diff --git a/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_NETHERLANDS_US_INTERNATIONAL_PC.png.sha1 b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_NETHERLANDS_US_INTERNATIONAL_PC.png.sha1
new file mode 100644
index 0000000..45f79d5
--- /dev/null
+++ b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_NETHERLANDS_US_INTERNATIONAL_PC.png.sha1
@@ -0,0 +1 @@
+fd5c82f95ac16720f0be8706484fe32311d4bc0c
\ No newline at end of file
diff --git a/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_PORTUGUESE_US_INTERNATIONAL.png.sha1 b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_PORTUGUESE_US_INTERNATIONAL.png.sha1
new file mode 100644
index 0000000..45f79d5
--- /dev/null
+++ b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_PORTUGUESE_US_INTERNATIONAL.png.sha1
@@ -0,0 +1 @@
+fd5c82f95ac16720f0be8706484fe32311d4bc0c
\ No newline at end of file
diff --git a/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_PORTUGUESE_US_INTERNATIONAL_PC.png.sha1 b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_PORTUGUESE_US_INTERNATIONAL_PC.png.sha1
new file mode 100644
index 0000000..45f79d5
--- /dev/null
+++ b/ui/chromeos/ui_chromeos_strings_grd/IDS_IME_NAME_KEYBOARD_PORTUGUESE_US_INTERNATIONAL_PC.png.sha1
@@ -0,0 +1 @@
+fd5c82f95ac16720f0be8706484fe32311d4bc0c
\ No newline at end of file
diff --git a/ui/file_manager/file_manager/foreground/js/quick_view_controller.js b/ui/file_manager/file_manager/foreground/js/quick_view_controller.js
index 86ab1f6..e41ffe3 100644
--- a/ui/file_manager/file_manager/foreground/js/quick_view_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/quick_view_controller.js
@@ -603,16 +603,40 @@
               } else {
                 break;
               }
+            case 'text':
+              if (typeInfo.subtype === 'TXT') {
+                return file
+                    .text()  // Convert file content to utf-8.
+                    .then(text => {
+                      return new Blob(
+                          [text], {type: 'text/plain;charset=utf-8'});
+                    })
+                    .then(blob => {
+                      params.contentUrl = URL.createObjectURL(blob);
+                      params.browsable = true;
+                      return params;
+                    })
+                    .catch(e => {
+                      console.error(e);
+                      return params;
+                    });
+              } else {
+                break;
+              }
           }
-          const browsable = tasks.some(task => {
-            return ['view-in-browser', 'view-pdf'].includes(
-                task.taskId.split('|')[2]);
+
+          params.browsable = tasks.some(task => {
+            const verb = task.taskId.split('|')[2];
+            return ['view-in-browser', 'view-pdf'].includes(verb);
           });
-          params.browsable = browsable;
-          params.contentUrl = browsable ? URL.createObjectURL(file) : '';
-          if (params.subtype == 'PDF') {
-            params.contentUrl += '#view=FitH';
+
+          if (params.browsable) {
+            params.contentUrl = URL.createObjectURL(file);
+            if (params.subtype === 'PDF') {
+              params.contentUrl += '#view=FitH';
+            }
           }
+
           return params;
         })
         .catch(e => {
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js
index 8fb00bd..a5bb1d7 100644
--- a/ui/file_manager/integration_tests/file_manager/quick_view.js
+++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -528,6 +528,10 @@
 
     // Open a DocumentsProvider file in Quick View.
     await openQuickView(appId, ENTRIES.hello.nameText);
+
+    // crbug.com/1131298 The text file content is not displayed. The <webview>
+    // instead shows a "site cannot be reached" error.
+    return IGNORE_APP_ERRORS;
   };
 
   /**
@@ -2358,6 +2362,43 @@
   };
 
   /**
+   * Tests the tab-index focus order when sending tab keys when an HTML file is
+   * shown in Quick View.
+   */
+  testcase.openQuickViewTabIndexHtml = async () => {
+    // Prepare a list of tab-index focus queries.
+    const tabQueries = [
+      {'query': ['#quick-view', '[aria-label="Back"]:focus']},
+      {'query': ['#quick-view', '[aria-label="Open"]:focus']},
+      {'query': ['#quick-view', '[aria-label="Delete"]:focus']},
+      {'query': ['#quick-view', '[aria-label="File info"]:focus']},
+      {'query': ['#quick-view', '[aria-label="Back"]:focus']},
+    ];
+
+    // Open Files app on Downloads containing ENTRIES.tallHtml.
+    const appId = await setupAndWaitUntilReady(
+        RootPath.DOWNLOADS, [ENTRIES.tallHtml], []);
+
+    // Open the file in Quick View.
+    await openQuickView(appId, ENTRIES.tallHtml.nameText);
+
+    for (const query of tabQueries) {
+      // Make the browser dispatch a tab key event to FilesApp.
+      const result = await sendTestMessage(
+          {name: 'dispatchTabKey', shift: query.shift || false});
+      chrome.test.assertEq(
+          result, 'tabKeyDispatched', 'Tab key dispatch failure');
+
+      // Note: Allow 500ms between key events to filter out the focus
+      // traversal problems noted in crbug.com/907380#c10.
+      await wait(500);
+
+      // Check: the queried element should gain the focus.
+      await remoteCall.waitForElement(appId, query.query);
+    }
+  };
+
+  /**
    * Tests the tab-index focus order when sending tab keys when an audio file is
    * shown in Quick View.
    */
diff --git a/ui/file_manager/integration_tests/test_util.js b/ui/file_manager/integration_tests/test_util.js
index 8389b8d..fb52b42 100644
--- a/ui/file_manager/integration_tests/test_util.js
+++ b/ui/file_manager/integration_tests/test_util.js
@@ -724,6 +724,17 @@
     typeText: 'Plain text',
   }),
 
+  utf8Text: new TestEntryInfo({
+    type: EntryType.FILE,
+    sourceFileName: 'utf8.txt',
+    targetPath: 'utf8.txt',
+    mimeType: 'text/plain',
+    lastModifiedTime: 'Sep 4, 1998, 12:34 PM',
+    nameText: 'utf8.txt',
+    sizeText: '191 bytes',
+    typeText: 'Plain text',
+  }),
+
   mHtml: new TestEntryInfo({
     type: EntryType.FILE,
     sourceFileName: 'page.mhtml',
diff --git a/ui/ozone/platform_selection.cc b/ui/ozone/platform_selection.cc
index 1b49a08..eb8e85ed 100644
--- a/ui/ozone/platform_selection.cc
+++ b/ui/ozone/platform_selection.cc
@@ -33,6 +33,9 @@
     return g_selected_platform;
 
   std::string platform_name = GetPlatformName();
+  // TODO(b/169115289) remove once all Tast tests use "drm".
+  if (platform_name == "gbm")
+    platform_name = "drm";
 
   // Search for a matching platform in the list.
   for (int platform_id = 0; platform_id < kPlatformCount; ++platform_id) {
diff --git a/ui/views/background.cc b/ui/views/background.cc
index ed6a43f..7ab9015 100644
--- a/ui/views/background.cc
+++ b/ui/views/background.cc
@@ -13,7 +13,6 @@
 #include "cc/paint/paint_flags.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/color_utils.h"
-#include "ui/native_theme/native_theme_color_id.h"
 #include "ui/views/painter.h"
 #include "ui/views/view.h"
 #include "ui/views/view_observer.h"
@@ -62,6 +61,33 @@
   DISALLOW_COPY_AND_ASSIGN(RoundedRectBackground);
 };
 
+// ThemedVectorIconBackground is an image drawn on the view's background using
+// ThemedVectorIcon to react to theme changes.
+class ThemedVectorIconBackground : public Background, public ViewObserver {
+ public:
+  explicit ThemedVectorIconBackground(View* view,
+                                      const ui::ThemedVectorIcon& icon)
+      : icon_(icon), observer_(this) {
+    DCHECK(!icon_.empty());
+    observer_.Add(view);
+    OnViewThemeChanged(view);
+  }
+
+  // ViewObserver:
+  void OnViewThemeChanged(View* view) override { view->SchedulePaint(); }
+  void OnViewIsDeleting(View* view) override { observer_.Remove(view); }
+
+  void Paint(gfx::Canvas* canvas, View* view) const override {
+    canvas->DrawImageInt(icon_.GetImageSkia(view->GetNativeTheme()), 0, 0);
+  }
+
+ private:
+  const ui::ThemedVectorIcon icon_;
+  ScopedObserver<View, ViewObserver> observer_;
+
+  DISALLOW_COPY_AND_ASSIGN(ThemedVectorIconBackground);
+};
+
 // ThemedSolidBackground is a solid background that stays in sync with a view's
 // native theme.
 class ThemedSolidBackground : public SolidBackground, public ViewObserver {
@@ -125,6 +151,12 @@
   return std::make_unique<RoundedRectBackground>(color, radius);
 }
 
+std::unique_ptr<Background> CreateThemedVectorIconBackground(
+    View* view,
+    const ui::ThemedVectorIcon& icon) {
+  return std::make_unique<ThemedVectorIconBackground>(view, icon);
+}
+
 std::unique_ptr<Background> CreateThemedSolidBackground(
     View* view,
     ui::NativeTheme::ColorId color_id) {
diff --git a/ui/views/background.h b/ui/views/background.h
index 366ce9d..1218d80 100644
--- a/ui/views/background.h
+++ b/ui/views/background.h
@@ -14,6 +14,7 @@
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/native_theme/native_theme.h"
+#include "ui/native_theme/themed_vector_icon.h"
 #include "ui/views/views_export.h"
 
 #if defined(OS_WIN)
@@ -24,6 +25,10 @@
 class Canvas;
 }
 
+namespace ui {
+class ThemedVectorIcon;
+}
+
 namespace views {
 
 class Painter;
@@ -79,10 +84,15 @@
     View* view,
     ui::NativeTheme::ColorId color_id);
 
-// Creates a Background from the specified Painter.
+// Creates a background from the specified Painter.
 VIEWS_EXPORT std::unique_ptr<Background> CreateBackgroundFromPainter(
     std::unique_ptr<Painter> painter);
 
+// Creates a background from the specified ThemedVectorIcon.
+VIEWS_EXPORT std::unique_ptr<Background> CreateThemedVectorIconBackground(
+    View* view,
+    const ui::ThemedVectorIcon& icon);
+
 }  // namespace views
 
 #endif  // UI_VIEWS_BACKGROUND_H_
diff --git a/ui/views/controls/button/button.h b/ui/views/controls/button/button.h
index 184e736..4cbab27 100644
--- a/ui/views/controls/button/button.h
+++ b/ui/views/controls/button/button.h
@@ -117,6 +117,16 @@
     set_callback(ListenerToPressedCallback(this, listener));
   }
 
+  // Allow providing callbacks that expect either zero or one args, since many
+  // callers don't care about the argument and can avoid adapter functions this
+  // way.
+  void set_callback(base::RepeatingClosure callback) {
+    // Adapt this closure to a PressedCallback by discarding the extra arg.
+    callback_ =
+        base::BindRepeating([](base::RepeatingClosure closure,
+                               const ui::Event& event) { closure.Run(); },
+                            std::move(callback));
+  }
   void set_callback(PressedCallback callback) {
     callback_ = std::move(callback);
   }
diff --git a/ui/views/controls/link.h b/ui/views/controls/link.h
index cfaf72f..ee71c971 100644
--- a/ui/views/controls/link.h
+++ b/ui/views/controls/link.h
@@ -39,8 +39,8 @@
                 int text_style = style::STYLE_LINK);
   ~Link() override;
 
-  // Allow providing callbacks that expect either zero or two args, since many
-  // callers don't care about the arguments and can avoid adapter functions this
+  // Allow providing callbacks that expect either zero or one args, since many
+  // callers don't care about the argument and can avoid adapter functions this
   // way.
   void set_callback(base::RepeatingClosure callback) {
     // Adapt this closure to a ClickedCallback by discarding the extra arg.
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn
index 13312e9..f88fee2 100644
--- a/ui/webui/resources/BUILD.gn
+++ b/ui/webui/resources/BUILD.gn
@@ -140,9 +140,17 @@
     in_files += [
       "cr_components/chromeos/bluetooth/bluetooth_dialog.m.js",
       "cr_components/chromeos/cellular_setup/base_page.m.js",
+      "cr_components/chromeos/cellular_setup/button_bar.m.js",
+      "cr_components/chromeos/cellular_setup/cellular_setup.m.js",
+      "cr_components/chromeos/cellular_setup/cellular_types.m.js",
+      "cr_components/chromeos/cellular_setup/esim_flow_ui.m.js",
       "cr_components/chromeos/cellular_setup/final_page.m.js",
       "cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js",
+      "cr_components/chromeos/cellular_setup/provisioning_page.m.js",
+      "cr_components/chromeos/cellular_setup/psim_flow_ui.m.js",
+      "cr_components/chromeos/cellular_setup/setup_selection_flow.m.js",
       "cr_components/chromeos/cellular_setup/sim_detect_page.m.js",
+      "cr_components/chromeos/cellular_setup/subflow_behavior.m.js",
       "cr_components/chromeos/cellular_setup/webview_post_util.m.js",
       "cr_components/chromeos/network/cr_policy_network_behavior_mojo.m.js",
       "cr_components/chromeos/network/cr_policy_network_indicator_mojo.m.js",
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_config.js b/ui/webui/resources/cr_components/chromeos/network/network_config.js
index 65dc463a..d15f327 100644
--- a/ui/webui/resources/cr_components/chromeos/network/network_config.js
+++ b/ui/webui/resources/cr_components/chromeos/network/network_config.js
@@ -19,8 +19,6 @@
   OPEN_VPN: 'OpenVPN',
 };
 
-(function() {
-
 // Note: This pattern does not work for elements that are stamped on initial
 // load because chromeos.networkConfig is not defined yet. <network-config>
 // however is always embedded in a <cr-dialog> so it is not stamped immediately.
@@ -1740,4 +1738,3 @@
     return undefined;
   },
 });
-})();