[scheduler] Remove expensive task blocking logic.

Do not try to detect and block expensive tasks as it makes both
predictability and performance worse.

This is expected to reduce high percentiles scrolling latency on
Android by 3%.

Design doc:
https://docs.google.com/document/d/1EvAfCyQVCiZe5plx4CDX-CT3vnS-t7n6u9FOkwBm3MM

R=alexclarke@chromium.org,skyostil@chromium.org
BUG=874836

Change-Id: Ic3aa3f78586fe78b98efa9709dcc7bc61e799f3f
Reviewed-on: https://chromium-review.googlesource.com/c/1411882
Commit-Queue: Alexander Timin <altimin@chromium.org>
Reviewed-by: Sami Kyöstilä <skyostil@chromium.org>
Reviewed-by: Alex Clarke <alexclarke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#623789}
diff --git a/third_party/blink/renderer/platform/scheduler/BUILD.gn b/third_party/blink/renderer/platform/scheduler/BUILD.gn
index 88c1e04..786897f 100644
--- a/third_party/blink/renderer/platform/scheduler/BUILD.gn
+++ b/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -92,8 +92,6 @@
     "main_thread/render_widget_signals.h",
     "main_thread/resource_loading_task_runner_handle_impl.cc",
     "main_thread/resource_loading_task_runner_handle_impl.h",
-    "main_thread/task_cost_estimator.cc",
-    "main_thread/task_cost_estimator.h",
     "main_thread/task_type_names.cc",
     "main_thread/task_type_names.h",
     "main_thread/use_case.h",
@@ -199,7 +197,6 @@
     "main_thread/page_scheduler_impl_unittest.cc",
     "main_thread/queueing_time_estimator_unittest.cc",
     "main_thread/render_widget_signals_unittest.cc",
-    "main_thread/task_cost_estimator_unittest.cc",
     "main_thread/user_model_unittest.cc",
     "worker/compositor_thread_scheduler_unittest.cc",
     "worker/worker_scheduler_proxy_unittest.cc",
diff --git a/third_party/blink/renderer/platform/scheduler/common/features.h b/third_party/blink/renderer/platform/scheduler/common/features.h
index dd978f3..3ab46244 100644
--- a/third_party/blink/renderer/platform/scheduler/common/features.h
+++ b/third_party/blink/renderer/platform/scheduler/common/features.h
@@ -143,22 +143,6 @@
 extern const char PLATFORM_EXPORT kThrottleableTaskTypesListParam[];
 extern const char PLATFORM_EXPORT kFreezableTaskTypesListParam[];
 
-// https://crbug.com/874836: Experiment-controlled removal of input heuristics.
-// Expensive task blocking as a part of input handling heuristics, so disabling
-// input heuristics implicitly disables expensive task blocking. Expensive task
-// blocking is tested separately as it's less risky. Touchstart and
-// non-touchstart input heuristics are separated because non-touchstart are
-// seen as less ricky.
-const base::Feature kDisableExpensiveTaskBlocking{
-    "BlinkSchedulerDisableExpensiveTaskBlocking",
-    base::FEATURE_DISABLED_BY_DEFAULT};
-const base::Feature kDisableNonTouchstartInputHeuristics{
-    "BlinkSchedulerDisableNonTouchstartInputHeuristics",
-    base::FEATURE_DISABLED_BY_DEFAULT};
-const base::Feature kDisableTouchstartInputHeuristics{
-    "BlinkSchedulerDisableTouchstartInputHeuristics",
-    base::FEATURE_DISABLED_BY_DEFAULT};
-
 }  // namespace scheduler
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
index 47812d3..96df8a3 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -47,14 +47,6 @@
 using base::sequence_manager::TimeDomain;
 
 namespace {
-// The run time of loading tasks is strongly bimodal.  The vast majority are
-// very cheap, but there are usually a handful of very expensive tasks (e.g ~1
-// second on a mobile device) so we take a very pessimistic view when estimating
-// the cost of loading tasks.
-const int kLoadingTaskEstimationSampleCount = 1000;
-const double kLoadingTaskEstimationPercentile = 99;
-const int kTimerTaskEstimationSampleCount = 1000;
-const double kTimerTaskEstimationPercentile = 99;
 const int kShortIdlePeriodDurationSampleCount = 10;
 const double kShortIdlePeriodDurationPercentile = 50;
 // Amount of idle time left in a frame (as a ratio of the vsync interval) above
@@ -297,21 +289,6 @@
       this);
 
   for (auto& pair : task_runners_) {
-    TaskCostEstimator* observer = nullptr;
-    switch (pair.first->queue_class()) {
-      case MainThreadTaskQueue::QueueClass::kLoading:
-        observer = &main_thread_only().loading_task_cost_estimator;
-        break;
-      case MainThreadTaskQueue::QueueClass::kTimer:
-        observer = &main_thread_only().timer_task_cost_estimator;
-        break;
-      default:
-        observer = nullptr;
-    }
-
-    if (observer)
-      pair.first->RemoveTaskObserver(observer);
-
     pair.first->ShutdownTaskQueue();
   }
 
@@ -335,13 +312,7 @@
     const scoped_refptr<MainThreadTaskQueue>& compositor_task_runner,
     const base::TickClock* time_source,
     base::TimeTicks now)
-    : loading_task_cost_estimator(time_source,
-                                  kLoadingTaskEstimationSampleCount,
-                                  kLoadingTaskEstimationPercentile),
-      timer_task_cost_estimator(time_source,
-                                kTimerTaskEstimationSampleCount,
-                                kTimerTaskEstimationPercentile),
-      idle_time_estimator(compositor_task_runner,
+    : idle_time_estimator(compositor_task_runner,
                           time_source,
                           kShortIdlePeriodDurationSampleCount,
                           kShortIdlePeriodDurationPercentile),
@@ -360,11 +331,6 @@
                            "Scheduler.PauseCount",
                            main_thread_scheduler_impl,
                            &main_thread_scheduler_impl->tracing_controller_),
-      expensive_task_policy(ExpensiveTaskPolicy::kRun,
-                            "Scheduler.ExpensiveTaskPolicy",
-                            main_thread_scheduler_impl,
-                            &main_thread_scheduler_impl->tracing_controller_,
-                            ExpensiveTaskPolicyToString),
       rail_mode_for_tracing(current_policy.rail_mode(),
                             "Scheduler.RAILMode",
                             main_thread_scheduler_impl,
@@ -386,30 +352,6 @@
           main_thread_scheduler_impl,
           &main_thread_scheduler_impl->tracing_controller_,
           YesNoStateToString),
-      loading_task_estimated_cost(
-          base::TimeDelta(),
-          "Scheduler.LoadingTaskEstimatedCostMs",
-          main_thread_scheduler_impl,
-          &main_thread_scheduler_impl->tracing_controller_,
-          TimeDeltaToMilliseconds),
-      timer_task_estimated_cost(
-          base::TimeDelta(),
-          "Scheduler.TimerTaskEstimatedCostMs",
-          main_thread_scheduler_impl,
-          &main_thread_scheduler_impl->tracing_controller_,
-          TimeDeltaToMilliseconds),
-      loading_tasks_seem_expensive(
-          false,
-          "Scheduler.LoadingTasksSeemExpensive",
-          main_thread_scheduler_impl,
-          &main_thread_scheduler_impl->tracing_controller_,
-          YesNoStateToString),
-      timer_tasks_seem_expensive(
-          false,
-          "Scheduler.TimerTasksSeemExpensive",
-          main_thread_scheduler_impl,
-          &main_thread_scheduler_impl->tracing_controller_,
-          YesNoStateToString),
       blocking_input_expected_soon(
           false,
           "Scheduler.BlockingInputExpectedSoon",
@@ -617,13 +559,6 @@
 
   FrameSchedulerImpl::InitializeTaskTypeQueueTraitsMap(
       frame_task_types_to_queue_traits);
-
-  disable_expensive_task_blocking =
-      base::FeatureList::IsEnabled(kDisableExpensiveTaskBlocking);
-  disable_non_touchstart_input_heuristics =
-      base::FeatureList::IsEnabled(kDisableNonTouchstartInputHeuristics);
-  disable_touchstart_input_heuristics =
-      base::FeatureList::IsEnabled(kDisableTouchstartInputHeuristics);
 }
 
 MainThreadSchedulerImpl::AnyThread::~AnyThread() = default;
@@ -742,12 +677,6 @@
   auto insert_result =
       task_runners_.insert(std::make_pair(task_queue, std::move(voter)));
   auto queue_class = task_queue->queue_class();
-  if (queue_class == MainThreadTaskQueue::QueueClass::kTimer) {
-    task_queue->AddTaskObserver(&main_thread_only().timer_task_cost_estimator);
-  } else if (queue_class == MainThreadTaskQueue::QueueClass::kLoading) {
-    task_queue->AddTaskObserver(
-        &main_thread_only().loading_task_cost_estimator);
-  }
 
   ApplyTaskQueuePolicy(
       task_queue.get(), insert_result.first->second.get(), TaskQueuePolicy(),
@@ -808,20 +737,7 @@
   if (task_queue_throttler_)
     task_queue_throttler_->ShutdownTaskQueue(task_queue.get());
 
-  if (task_runners_.erase(task_queue)) {
-    switch (task_queue->queue_class()) {
-      case MainThreadTaskQueue::QueueClass::kTimer:
-        task_queue->RemoveTaskObserver(
-            &main_thread_only().timer_task_cost_estimator);
-        break;
-      case MainThreadTaskQueue::QueueClass::kLoading:
-        task_queue->RemoveTaskObserver(
-            &main_thread_only().loading_task_cost_estimator);
-        break;
-      default:
-        break;
-    }
-  }
+  task_runners_.erase(task_queue.get());
 }
 
 bool MainThreadSchedulerImpl::CanExceedIdleDeadlineIfRequired() const {
@@ -1408,22 +1324,6 @@
   main_thread_only().longest_jank_free_task_duration =
       longest_jank_free_task_duration;
 
-  main_thread_only().loading_task_estimated_cost =
-      main_thread_only().loading_task_cost_estimator.expected_task_duration();
-  bool loading_tasks_seem_expensive =
-      main_thread_only().loading_task_estimated_cost >
-      longest_jank_free_task_duration;
-
-  main_thread_only().timer_task_estimated_cost =
-      main_thread_only().timer_task_cost_estimator.expected_task_duration();
-  bool timer_tasks_seem_expensive =
-      main_thread_only().timer_task_estimated_cost >
-      longest_jank_free_task_duration;
-
-  main_thread_only().timer_tasks_seem_expensive = timer_tasks_seem_expensive;
-  main_thread_only().loading_tasks_seem_expensive =
-      loading_tasks_seem_expensive;
-
   // The |new_policy_duration| is the minimum of |expected_use_case_duration|
   // and |gesture_expected_flag_valid_for_duration| unless one is zero in
   // which case we choose the other.
@@ -1452,7 +1352,6 @@
           kFastCompositingIdleTimeThreshold;
 
   Policy new_policy;
-  ExpensiveTaskPolicy expensive_task_policy = ExpensiveTaskPolicy::kRun;
   new_policy.rail_mode() = v8::PERFORMANCE_ANIMATION;
   new_policy.use_case() = main_thread_only().current_use_case;
 
@@ -1460,7 +1359,6 @@
     case UseCase::kCompositorGesture:
       if (main_thread_only().blocking_input_expected_soon) {
         new_policy.rail_mode() = v8::PERFORMANCE_RESPONSE;
-        expensive_task_policy = ExpensiveTaskPolicy::kBlock;
         new_policy.compositor_priority() =
             TaskQueue::QueuePriority::kHighestPriority;
       } else {
@@ -1477,12 +1375,8 @@
       new_policy.compositor_priority() = main_thread_compositing_is_fast
                                              ? TaskQueue::kHighestPriority
                                              : TaskQueue::kNormalPriority;
-      if (main_thread_only().blocking_input_expected_soon) {
+      if (main_thread_only().blocking_input_expected_soon)
         new_policy.rail_mode() = v8::PERFORMANCE_RESPONSE;
-        expensive_task_policy = ExpensiveTaskPolicy::kBlock;
-      } else {
-        expensive_task_policy = ExpensiveTaskPolicy::kThrottle;
-      }
       break;
 
     case UseCase::kMainThreadCustomInputHandling:
@@ -1503,12 +1397,8 @@
       // handling over other tasks.
       new_policy.compositor_priority() =
           TaskQueue::QueuePriority::kHighestPriority;
-      if (main_thread_only().blocking_input_expected_soon) {
+      if (main_thread_only().blocking_input_expected_soon)
         new_policy.rail_mode() = v8::PERFORMANCE_RESPONSE;
-        expensive_task_policy = ExpensiveTaskPolicy::kBlock;
-      } else {
-        expensive_task_policy = ExpensiveTaskPolicy::kThrottle;
-      }
       break;
 
     case UseCase::kTouchstart:
@@ -1517,8 +1407,6 @@
       new_policy.rail_mode() = v8::PERFORMANCE_RESPONSE;
       new_policy.loading_queue_policy().is_deferred = true;
       new_policy.timer_queue_policy().is_deferred = true;
-      // NOTE this is a nop due to the above.
-      expensive_task_policy = ExpensiveTaskPolicy::kBlock;
       break;
 
     case UseCase::kNone:
@@ -1527,7 +1415,6 @@
       if (main_thread_only().blocking_input_expected_soon &&
           any_thread().last_gesture_was_compositor_driven) {
         new_policy.rail_mode() = v8::PERFORMANCE_RESPONSE;
-        expensive_task_policy = ExpensiveTaskPolicy::kBlock;
       }
       break;
 
@@ -1545,36 +1432,6 @@
   if (main_thread_only().renderer_hidden)
     new_policy.rail_mode() = v8::PERFORMANCE_IDLE;
 
-  if (expensive_task_policy == ExpensiveTaskPolicy::kBlock &&
-      !main_thread_only().have_seen_a_begin_main_frame) {
-    expensive_task_policy = ExpensiveTaskPolicy::kRun;
-  }
-
-  if (scheduling_settings().disable_expensive_task_blocking)
-    expensive_task_policy = ExpensiveTaskPolicy::kRun;
-
-  switch (expensive_task_policy) {
-    case ExpensiveTaskPolicy::kRun:
-      break;
-
-    case ExpensiveTaskPolicy::kBlock:
-      if (loading_tasks_seem_expensive)
-        new_policy.loading_queue_policy().is_deferred = true;
-      if (timer_tasks_seem_expensive)
-        new_policy.timer_queue_policy().is_deferred = true;
-      break;
-
-    case ExpensiveTaskPolicy::kThrottle:
-      if (loading_tasks_seem_expensive) {
-        new_policy.loading_queue_policy().is_throttled = true;
-      }
-      if (timer_tasks_seem_expensive) {
-        new_policy.timer_queue_policy().is_throttled = true;
-      }
-      break;
-  }
-  main_thread_only().expensive_task_policy = expensive_task_policy;
-
   if (main_thread_only().renderer_pause_count != 0) {
     new_policy.loading_queue_policy().is_paused = true;
     new_policy.timer_queue_policy().is_paused = true;
@@ -1694,8 +1551,7 @@
   // Special case for flings. This is needed because we don't get notification
   // of a fling ending (although we do for cancellation).
   if (any_thread().fling_compositor_escalation_deadline > now &&
-      !any_thread().awaiting_touch_start_response &&
-      !scheduling_settings().disable_non_touchstart_input_heuristics) {
+      !any_thread().awaiting_touch_start_response) {
     *expected_use_case_duration =
         any_thread().fling_compositor_escalation_deadline - now;
     return UseCase::kCompositorGesture;
@@ -1705,8 +1561,7 @@
       any_thread().user_model.TimeLeftInUserGesture(now);
   if (*expected_use_case_duration > base::TimeDelta()) {
     // Has a gesture been fully established?
-    if (any_thread().awaiting_touch_start_response &&
-        !scheduling_settings().disable_touchstart_input_heuristics) {
+    if (any_thread().awaiting_touch_start_response) {
       // No, so arrange for compositor tasks to be run at the highest priority.
       return UseCase::kTouchstart;
     }
@@ -1721,20 +1576,18 @@
     //    stream of input events and has prevented a default gesture from being
     //    started.
     // 4. SYNCHRONIZED_GESTURE where the gesture is processed on both threads.
-    if (!scheduling_settings().disable_non_touchstart_input_heuristics) {
-      if (any_thread().last_gesture_was_compositor_driven) {
-        if (any_thread().begin_main_frame_on_critical_path) {
-          return UseCase::kSynchronizedGesture;
-        } else {
-          return UseCase::kCompositorGesture;
-        }
-      }
-      if (any_thread().default_gesture_prevented) {
-        return UseCase::kMainThreadCustomInputHandling;
+    if (any_thread().last_gesture_was_compositor_driven) {
+      if (any_thread().begin_main_frame_on_critical_path) {
+        return UseCase::kSynchronizedGesture;
       } else {
-        return UseCase::kMainThreadGesture;
+        return UseCase::kCompositorGesture;
       }
     }
+    if (any_thread().default_gesture_prevented) {
+      return UseCase::kMainThreadCustomInputHandling;
+    } else {
+      return UseCase::kMainThreadGesture;
+    }
   }
 
   // Occasionally the meaningful paint fails to be detected, so as a fallback we
@@ -1794,16 +1647,6 @@
   return &helper_;
 }
 
-TaskCostEstimator*
-MainThreadSchedulerImpl::GetLoadingTaskCostEstimatorForTesting() {
-  return &main_thread_only().loading_task_cost_estimator;
-}
-
-TaskCostEstimator*
-MainThreadSchedulerImpl::GetTimerTaskCostEstimatorForTesting() {
-  return &main_thread_only().timer_task_cost_estimator;
-}
-
 IdleTimeEstimator* MainThreadSchedulerImpl::GetIdleTimeEstimatorForTesting() {
   return &main_thread_only().idle_time_estimator;
 }
@@ -2045,22 +1888,6 @@
       "MainThreadScheduler", this, AsValueLocked(helper_.NowTicks()));
 }
 
-// static
-const char* MainThreadSchedulerImpl::ExpensiveTaskPolicyToString(
-    ExpensiveTaskPolicy expensive_task_policy) {
-  switch (expensive_task_policy) {
-    case ExpensiveTaskPolicy::kRun:
-      return "run";
-    case ExpensiveTaskPolicy::kBlock:
-      return "block";
-    case ExpensiveTaskPolicy::kThrottle:
-      return "throttle";
-    default:
-      NOTREACHED();
-      return nullptr;
-  }
-}
-
 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
 MainThreadSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
   helper_.CheckOnValidThread();
@@ -2075,10 +1902,6 @@
       main_thread_only().has_visible_render_widget_with_touch_handler);
   state->SetString("current_use_case",
                    UseCaseToString(main_thread_only().current_use_case));
-  state->SetBoolean("loading_tasks_seem_expensive",
-                    main_thread_only().loading_tasks_seem_expensive);
-  state->SetBoolean("timer_tasks_seem_expensive",
-                    main_thread_only().timer_tasks_seem_expensive);
   state->SetBoolean("begin_frame_not_expected_soon",
                     main_thread_only().begin_frame_not_expected_soon);
   state->SetBoolean(
@@ -2122,14 +1945,6 @@
                     any_thread().last_gesture_was_compositor_driven);
   state->SetBoolean("default_gesture_prevented",
                     any_thread().default_gesture_prevented);
-  state->SetDouble("expected_loading_task_duration",
-                   main_thread_only()
-                       .loading_task_cost_estimator.expected_task_duration()
-                       .InMillisecondsF());
-  state->SetDouble("expected_timer_task_duration",
-                   main_thread_only()
-                       .timer_task_cost_estimator.expected_task_duration()
-                       .InMillisecondsF());
   state->SetBoolean("is_audio_playing", main_thread_only().is_audio_playing);
   state->SetBoolean("virtual_time_stopped",
                     main_thread_only().virtual_time_stopped);
@@ -2165,10 +1980,6 @@
           .InMillisecondsF());
   state->SetBoolean("in_idle_period", any_thread().in_idle_period);
 
-  state->SetString(
-      "expensive_task_policy",
-      ExpensiveTaskPolicyToString(main_thread_only().expensive_task_policy));
-
   any_thread().user_model.AsValueInto(state.get());
   render_widget_scheduler_signals_.AsValueInto(state.get());
 
@@ -2339,8 +2150,6 @@
   any_thread().have_seen_a_blocking_gesture = false;
   any_thread().waiting_for_meaningful_paint = true;
   any_thread().have_seen_input_since_navigation = false;
-  main_thread_only().loading_task_cost_estimator.Clear();
-  main_thread_only().timer_task_cost_estimator.Clear();
   main_thread_only().idle_time_estimator.Clear();
   main_thread_only().have_seen_a_begin_main_frame = false;
   main_thread_only().have_reported_blocking_intervention_since_navigation =
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
index 25e448a..04e1717 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -41,7 +41,6 @@
 #include "third_party/blink/renderer/platform/scheduler/main_thread/prioritize_compositing_after_input_experiment.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h"
-#include "third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/use_case.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/user_model.h"
 #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
@@ -132,10 +131,6 @@
     // entries. This is initialized early with all valid entries. Entries that
     // aren't valid task types, i.e. non-frame level, are base::nullopt.
     FrameTaskTypeToQueueTraitsArray frame_task_types_to_queue_traits;
-
-    bool disable_expensive_task_blocking;
-    bool disable_non_touchstart_input_heuristics;
-    bool disable_touchstart_input_heuristics;
   };
 
   static const char* UseCaseToString(UseCase use_case);
@@ -338,8 +333,6 @@
 
   // Test helpers.
   MainThreadSchedulerHelper* GetSchedulerHelperForTesting();
-  TaskCostEstimator* GetLoadingTaskCostEstimatorForTesting();
-  TaskCostEstimator* GetTimerTaskCostEstimatorForTesting();
   IdleTimeEstimator* GetIdleTimeEstimatorForTesting();
   base::TimeTicks CurrentIdleTaskDeadlineForTesting() const;
   void RunIdleTasksForTesting(base::OnceClosure callback);
@@ -422,8 +415,6 @@
       main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest,
       Tracing);
 
-  enum class ExpensiveTaskPolicy { kRun, kBlock, kThrottle };
-
   enum class TimeDomainType {
     kReal,
     kThrottled,
@@ -695,9 +686,6 @@
       const TaskQueuePolicy& old_task_queue_policy,
       const TaskQueuePolicy& new_task_queue_policy) const;
 
-  static const char* ExpensiveTaskPolicyToString(
-      ExpensiveTaskPolicy expensive_task_policy);
-
   void AddQueueToWakeUpBudgetPool(MainThreadTaskQueue* queue);
 
   void PauseRendererImpl();
@@ -812,8 +800,6 @@
         base::TimeTicks now);
     ~MainThreadOnly();
 
-    TaskCostEstimator loading_task_cost_estimator;
-    TaskCostEstimator timer_task_cost_estimator;
     IdleTimeEstimator idle_time_estimator;
     TraceableState<UseCase, TracingCategoryName::kDefault> current_use_case;
     Policy current_policy;
@@ -825,21 +811,12 @@
         longest_jank_free_task_duration;
     TraceableCounter<int, TracingCategoryName::kInfo>
         renderer_pause_count;  // Renderer is paused if non-zero.
-    TraceableState<ExpensiveTaskPolicy, TracingCategoryName::kInfo>
-        expensive_task_policy;
     TraceableState<v8::RAILMode, TracingCategoryName::kInfo>
         rail_mode_for_tracing;  // Don't use except for tracing.
     TraceableState<bool, TracingCategoryName::kDebug> renderer_hidden;
     TraceableState<bool, TracingCategoryName::kTopLevel> renderer_backgrounded;
     TraceableState<bool, TracingCategoryName::kDefault>
         keep_active_fetch_or_worker;
-    TraceableCounter<base::TimeDelta, TracingCategoryName::kInfo>
-        loading_task_estimated_cost;
-    TraceableCounter<base::TimeDelta, TracingCategoryName::kInfo>
-        timer_task_estimated_cost;
-    TraceableState<bool, TracingCategoryName::kInfo>
-        loading_tasks_seem_expensive;
-    TraceableState<bool, TracingCategoryName::kInfo> timer_tasks_seem_expensive;
     TraceableState<bool, TracingCategoryName::kDefault>
         blocking_input_expected_soon;
     TraceableState<bool, TracingCategoryName::kDebug>
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
index 4af2aa2..9bb201f 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -616,14 +616,6 @@
     return scheduler_->main_thread_only().have_seen_a_begin_main_frame;
   }
 
-  bool LoadingTasksSeemExpensive() {
-    return scheduler_->main_thread_only().loading_tasks_seem_expensive;
-  }
-
-  bool TimerTasksSeemExpensive() {
-    return scheduler_->main_thread_only().timer_tasks_seem_expensive;
-  }
-
   base::TimeTicks EstimatedNextFrameBegin() {
     return scheduler_->main_thread_only().estimated_next_frame_begin;
   }
@@ -808,27 +800,6 @@
   DISALLOW_COPY_AND_ASSIGN(MainThreadSchedulerImplTest);
 };
 
-class MainThreadSchedulerImplTestWithoutTouchstartInputHeuristics
-    : public MainThreadSchedulerImplTest {
- public:
-  MainThreadSchedulerImplTestWithoutTouchstartInputHeuristics()
-      : MainThreadSchedulerImplTest({kDisableTouchstartInputHeuristics,
-                                     kDisableNonTouchstartInputHeuristics},
-                                    {kPrioritizeCompositingAfterInput}) {}
-  ~MainThreadSchedulerImplTestWithoutTouchstartInputHeuristics() override =
-      default;
-};
-
-class MainThreadSchedulerImplTestWithoutNonTouchstartInputHeuristics
-    : public MainThreadSchedulerImplTest {
- public:
-  MainThreadSchedulerImplTestWithoutNonTouchstartInputHeuristics()
-      : MainThreadSchedulerImplTest({kDisableNonTouchstartInputHeuristics},
-                                    {kPrioritizeCompositingAfterInput}) {}
-  ~MainThreadSchedulerImplTestWithoutNonTouchstartInputHeuristics() override =
-      default;
-};
-
 TEST_F(MainThreadSchedulerImplTest, TestPostDefaultTask) {
   std::vector<std::string> run_order;
   PostTestTasks(&run_order, "D1 D2 D3 D4");
@@ -1032,22 +1003,6 @@
   EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase());
 }
 
-TEST_F(MainThreadSchedulerImplTestWithoutNonTouchstartInputHeuristics,
-       TestCompositorPolicy_CompositorHandlesInput_WithTouchHandler) {
-  std::vector<std::string> run_order;
-  PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
-
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  EnableIdleTasks();
-  SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
-  base::RunLoop().RunUntilIdle();
-  EXPECT_THAT(run_order,
-              testing::ElementsAre(std::string("L1"), std::string("D1"),
-                                   std::string("C1"), std::string("D2"),
-                                   std::string("C2"), std::string("I1")));
-  EXPECT_EQ(UseCase::kNone, CurrentUseCase());
-}
-
 TEST_F(MainThreadSchedulerImplTest,
        TestCompositorPolicy_MainThreadHandlesInput_WithoutScrollUpdates) {
   std::vector<std::string> run_order;
@@ -1214,52 +1169,6 @@
   EXPECT_EQ(UseCase::kTouchstart, CurrentUseCase());
 }
 
-TEST_F(
-    MainThreadSchedulerImplTestWithoutTouchstartInputHeuristics,
-    TestCompositorPolicy_MainThreadHandlesInput_SingleEvent_NoPreventDefault) {
-  std::vector<std::string> run_order;
-  PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
-
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  EnableIdleTasks();
-  scheduler_->DidHandleInputEventOnCompositorThread(
-      FakeTouchEvent(blink::WebInputEvent::kTouchStart),
-      InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  scheduler_->DidHandleInputEventOnMainThread(
-      FakeTouchEvent(blink::WebInputEvent::kTouchStart),
-      WebInputEventResult::kHandledSystem);
-  base::RunLoop().RunUntilIdle();
-  EXPECT_THAT(run_order,
-              testing::ElementsAre(std::string("L1"), std::string("D1"),
-                                   std::string("C1"), std::string("D2"),
-                                   std::string("C2"), std::string("I1")));
-  EXPECT_EQ(UseCase::kNone, CurrentUseCase());
-}
-
-TEST_F(
-    MainThreadSchedulerImplTestWithoutNonTouchstartInputHeuristics,
-    TestCompositorPolicy_MainThreadHandlesInput_SingleEvent_NoPreventDefault) {
-  std::vector<std::string> run_order;
-  PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
-
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  EnableIdleTasks();
-  scheduler_->DidHandleInputEventOnCompositorThread(
-      FakeTouchEvent(blink::WebInputEvent::kTouchStart),
-      InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  scheduler_->DidHandleInputEventOnMainThread(
-      FakeTouchEvent(blink::WebInputEvent::kTouchStart),
-      WebInputEventResult::kHandledSystem);
-  base::RunLoop().RunUntilIdle();
-  // Because we are still waiting for the touchstart to be processed,
-  // non-essential tasks like loading tasks are blocked.
-  EXPECT_THAT(run_order,
-              testing::ElementsAre(std::string("C1"), std::string("C2"),
-                                   std::string("D1"), std::string("D2"),
-                                   std::string("I1")));
-  EXPECT_EQ(UseCase::kTouchstart, CurrentUseCase());
-}
-
 TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) {
   std::vector<std::string> run_order;
   PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
@@ -1299,93 +1208,6 @@
               testing::ElementsAre(std::string("C1"), std::string("T1")));
 }
 
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveTimersDontRunWhenMainThreadScrolling) {
-  std::vector<std::string> run_order;
-
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  SimulateExpensiveTasks(timer_task_runner_);
-  DoMainFrame();
-  SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
-                                 blink::WebInputEvent::kGestureScrollUpdate);
-
-  PostTestTasks(&run_order, "C1 T1");
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(BlockingInputExpectedSoon());
-  EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase());
-
-  EXPECT_THAT(run_order, testing::ElementsAre(std::string("C1")));
-}
-
-class MainThreadSchedulerImplTestWithoutExpensiveTaskBlocking
-    : public MainThreadSchedulerImplTest {
- public:
-  MainThreadSchedulerImplTestWithoutExpensiveTaskBlocking()
-      : MainThreadSchedulerImplTest({kDisableExpensiveTaskBlocking}, {}) {}
-  ~MainThreadSchedulerImplTestWithoutExpensiveTaskBlocking() override = default;
-};
-
-TEST_F(MainThreadSchedulerImplTestWithoutExpensiveTaskBlocking,
-       ExpensiveTimersRunWhenMainThreadScrolling) {
-  std::vector<std::string> run_order;
-
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  SimulateExpensiveTasks(timer_task_runner_);
-  DoMainFrame();
-  SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
-                                 blink::WebInputEvent::kGestureScrollUpdate);
-
-  PostTestTasks(&run_order, "C1 T1");
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(BlockingInputExpectedSoon());
-  EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase());
-
-  EXPECT_THAT(run_order,
-              testing::ElementsAre(std::string("C1"), std::string("T1")));
-}
-
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveTimersDoRunWhenMainThreadInputHandling) {
-  std::vector<std::string> run_order;
-
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  SimulateExpensiveTasks(timer_task_runner_);
-  DoMainFrame();
-  SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
-                                 blink::WebInputEvent::kUndefined);
-
-  PostTestTasks(&run_order, "C1 T1");
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(BlockingInputExpectedSoon());
-  EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
-
-  EXPECT_THAT(run_order,
-              testing::ElementsAre(std::string("C1"), std::string("T1")));
-}
-
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveTimersDoRunWhenMainThreadScrolling_AndOnCriticalPath) {
-  std::vector<std::string> run_order;
-
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  SimulateExpensiveTasks(timer_task_runner_);
-  DoMainFrameOnCriticalPath();
-  SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
-                                 blink::WebInputEvent::kGestureScrollBegin);
-
-  PostTestTasks(&run_order, "C1 T1");
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(BlockingInputExpectedSoon());
-  EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
-
-  EXPECT_THAT(run_order,
-              testing::ElementsAre(std::string("C1"), std::string("T1")));
-}
-
 TEST_F(MainThreadSchedulerImplTest, TestTouchstartPolicy_Compositor) {
   std::vector<std::string> run_order;
   PostTestTasks(&run_order, "L1 D1 C1 D2 C2 T1 T2");
@@ -2686,326 +2508,6 @@
 }
 
 TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveLoadingTasksNotBlockedTillFirstBeginMainFrame) {
-  std::vector<std::string> run_order;
-
-  scheduler_->SetHaveSeenABlockingGestureForTesting(true);
-  SimulateExpensiveTasks(loading_task_queue_->task_runner());
-  ForceBlockingInputToBeExpectedSoon();
-  PostTestTasks(&run_order, "L1 D1");
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
-  EXPECT_FALSE(HaveSeenABeginMainframe());
-  EXPECT_TRUE(LoadingTasksSeemExpensive());
-  EXPECT_FALSE(TimerTasksSeemExpensive());
-  EXPECT_TRUE(BlockingInputExpectedSoon());
-  EXPECT_THAT(run_order,
-              testing::ElementsAre(std::string("L1"), std::string("D1")));
-
-  // Emit a BeginMainFrame, and the loading task should get blocked.
-  DoMainFrame();
-  run_order.clear();
-
-  PostTestTasks(&run_order, "L1 D1");
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(UseCase::kNone, CurrentUseCase());
-  EXPECT_TRUE(HaveSeenABeginMainframe());
-  EXPECT_TRUE(LoadingTasksSeemExpensive());
-  EXPECT_FALSE(TimerTasksSeemExpensive());
-  EXPECT_TRUE(BlockingInputExpectedSoon());
-  EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
-  EXPECT_EQ(v8::PERFORMANCE_RESPONSE, GetRAILMode());
-}
-
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveLoadingTasksNotBlockedIfNoTouchHandler) {
-  std::vector<std::string> run_order;
-
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(false);
-  DoMainFrame();
-  SimulateExpensiveTasks(loading_task_queue_->task_runner());
-  ForceBlockingInputToBeExpectedSoon();
-  PostTestTasks(&run_order, "L1 D1");
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
-  EXPECT_TRUE(HaveSeenABeginMainframe());
-  EXPECT_TRUE(LoadingTasksSeemExpensive());
-  EXPECT_FALSE(TimerTasksSeemExpensive());
-  EXPECT_FALSE(BlockingInputExpectedSoon());
-  EXPECT_THAT(run_order,
-              testing::ElementsAre(std::string("L1"), std::string("D1")));
-  EXPECT_EQ(v8::PERFORMANCE_ANIMATION, GetRAILMode());
-}
-
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveTimerTaskBlocked_UseCase_NONE_PreviousCompositorGesture) {
-  std::vector<std::string> run_order;
-
-  scheduler_->SetHaveSeenABlockingGestureForTesting(true);
-  DoMainFrame();
-  SimulateExpensiveTasks(timer_task_runner_);
-  ForceBlockingInputToBeExpectedSoon();
-
-  PostTestTasks(&run_order, "T1 D1");
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
-  EXPECT_TRUE(HaveSeenABeginMainframe());
-  EXPECT_FALSE(LoadingTasksSeemExpensive());
-  EXPECT_TRUE(TimerTasksSeemExpensive());
-  EXPECT_TRUE(BlockingInputExpectedSoon());
-  EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
-  EXPECT_EQ(v8::PERFORMANCE_RESPONSE, GetRAILMode());
-}
-
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveTimerTaskNotBlocked_UseCase_NONE_PreviousMainThreadGesture) {
-  std::vector<std::string> run_order;
-
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  DoMainFrame();
-  SimulateExpensiveTasks(timer_task_runner_);
-
-  SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
-                                 blink::WebInputEvent::kGestureScrollBegin);
-  EXPECT_EQ(UseCase::kMainThreadCustomInputHandling,
-            ForceUpdatePolicyAndGetCurrentUseCase());
-
-  scheduler_->DidHandleInputEventOnCompositorThread(
-      FakeInputEvent(blink::WebInputEvent::kTouchEnd),
-      InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  scheduler_->DidHandleInputEventOnMainThread(
-      FakeInputEvent(blink::WebInputEvent::kTouchEnd),
-      WebInputEventResult::kHandledSystem);
-
-  test_task_runner_->AdvanceMockTickClock(
-      priority_escalation_after_input_duration() * 2);
-  EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
-
-  PostTestTasks(&run_order, "T1 D1");
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
-  EXPECT_TRUE(HaveSeenABeginMainframe());
-  EXPECT_FALSE(LoadingTasksSeemExpensive());
-  EXPECT_TRUE(TimerTasksSeemExpensive());
-  EXPECT_TRUE(BlockingInputExpectedSoon());
-  EXPECT_THAT(run_order,
-              testing::ElementsAre(std::string("T1"), std::string("D1")));
-  EXPECT_EQ(v8::PERFORMANCE_ANIMATION, GetRAILMode());
-}
-
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveTimerTaskBlocked_UseCase_kCompositorGesture) {
-  std::vector<std::string> run_order;
-
-  scheduler_->SetHaveSeenABlockingGestureForTesting(true);
-  DoMainFrame();
-  SimulateExpensiveTasks(timer_task_runner_);
-  ForceBlockingInputToBeExpectedSoon();
-  scheduler_->DidAnimateForInputOnCompositorThread();
-
-  PostTestTasks(&run_order, "T1 D1");
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(UseCase::kCompositorGesture,
-            ForceUpdatePolicyAndGetCurrentUseCase());
-  EXPECT_TRUE(HaveSeenABeginMainframe());
-  EXPECT_FALSE(LoadingTasksSeemExpensive());
-  EXPECT_TRUE(TimerTasksSeemExpensive());
-  EXPECT_TRUE(BlockingInputExpectedSoon());
-  EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
-  EXPECT_EQ(v8::PERFORMANCE_RESPONSE, GetRAILMode());
-}
-
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveTimerTaskBlocked_EvenIfBeginMainFrameNotExpectedSoon) {
-  std::vector<std::string> run_order;
-
-  scheduler_->SetHaveSeenABlockingGestureForTesting(true);
-  DoMainFrame();
-  SimulateExpensiveTasks(timer_task_runner_);
-  ForceBlockingInputToBeExpectedSoon();
-  scheduler_->BeginFrameNotExpectedSoon();
-
-  PostTestTasks(&run_order, "T1 D1");
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
-  EXPECT_TRUE(HaveSeenABeginMainframe());
-  EXPECT_FALSE(LoadingTasksSeemExpensive());
-  EXPECT_TRUE(TimerTasksSeemExpensive());
-  EXPECT_TRUE(BlockingInputExpectedSoon());
-  EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
-  EXPECT_EQ(v8::PERFORMANCE_RESPONSE, GetRAILMode());
-}
-
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveLoadingTasksBlockedIfChildFrameNavigationExpected) {
-  std::vector<std::string> run_order;
-
-  DoMainFrame();
-  scheduler_->SetHaveSeenABlockingGestureForTesting(true);
-  SimulateExpensiveTasks(loading_task_queue_->task_runner());
-  ForceBlockingInputToBeExpectedSoon();
-
-  PostTestTasks(&run_order, "L1 D1");
-  base::RunLoop().RunUntilIdle();
-
-  // The expensive loading task gets blocked.
-  EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
-  EXPECT_EQ(v8::PERFORMANCE_RESPONSE, GetRAILMode());
-}
-
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveLoadingTasksNotBlockedDuringMainThreadGestures) {
-  std::vector<std::string> run_order;
-
-  SimulateExpensiveTasks(loading_task_queue_->task_runner());
-
-  // Loading tasks should not be disabled during main thread user interactions.
-  PostTestTasks(&run_order, "C1 L1");
-
-  // Trigger main_thread_gesture UseCase
-  SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
-                                 blink::WebInputEvent::kGestureScrollBegin);
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
-
-  EXPECT_TRUE(LoadingTasksSeemExpensive());
-  EXPECT_FALSE(TimerTasksSeemExpensive());
-  EXPECT_THAT(run_order,
-              testing::ElementsAre(std::string("C1"), std::string("L1")));
-  EXPECT_EQ(v8::PERFORMANCE_ANIMATION, GetRAILMode());
-}
-
-TEST_F(MainThreadSchedulerImplTest, ModeratelyExpensiveTimer_NotBlocked) {
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
-                                 blink::WebInputEvent::kTouchMove);
-  base::RunLoop().RunUntilIdle();
-  for (int i = 0; i < 20; i++) {
-    simulate_timer_task_ran_ = false;
-
-    viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
-        base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
-        viz::BeginFrameArgs::NORMAL);
-    begin_frame_args.on_critical_path = false;
-    scheduler_->WillBeginFrame(begin_frame_args);
-
-    compositor_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&MainThreadSchedulerImplTest::
-                           SimulateMainThreadInputHandlingCompositorTask,
-                       base::Unretained(this),
-                       base::TimeDelta::FromMilliseconds(8)));
-    timer_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&MainThreadSchedulerImplTest::SimulateTimerTask,
-                       base::Unretained(this),
-                       base::TimeDelta::FromMilliseconds(4)));
-
-    base::RunLoop().RunUntilIdle();
-    EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i;
-    EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase())
-        << " i = " << i;
-    EXPECT_FALSE(LoadingTasksSeemExpensive()) << " i = " << i;
-    EXPECT_FALSE(TimerTasksSeemExpensive()) << " i = " << i;
-
-    base::TimeDelta time_till_next_frame = EstimatedNextFrameBegin() - Now();
-    if (time_till_next_frame > base::TimeDelta())
-      test_task_runner_->AdvanceMockTickClock(time_till_next_frame);
-  }
-}
-
-TEST_F(MainThreadSchedulerImplTest,
-       FourtyMsTimer_NotBlocked_CompositorScrolling) {
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  base::RunLoop().RunUntilIdle();
-  for (int i = 0; i < 20; i++) {
-    simulate_timer_task_ran_ = false;
-
-    viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
-        base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
-        viz::BeginFrameArgs::NORMAL);
-    begin_frame_args.on_critical_path = false;
-    scheduler_->WillBeginFrame(begin_frame_args);
-    scheduler_->DidAnimateForInputOnCompositorThread();
-
-    compositor_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(
-            &MainThreadSchedulerImplTest::SimulateMainThreadCompositorTask,
-            base::Unretained(this), base::TimeDelta::FromMilliseconds(8)));
-    timer_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&MainThreadSchedulerImplTest::SimulateTimerTask,
-                       base::Unretained(this),
-                       base::TimeDelta::FromMilliseconds(40)));
-
-    base::RunLoop().RunUntilIdle();
-    EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i;
-    EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase()) << " i = " << i;
-    EXPECT_FALSE(LoadingTasksSeemExpensive()) << " i = " << i;
-    EXPECT_FALSE(TimerTasksSeemExpensive()) << " i = " << i;
-
-    base::TimeDelta time_till_next_frame = EstimatedNextFrameBegin() - Now();
-    if (time_till_next_frame > base::TimeDelta())
-      test_task_runner_->AdvanceMockTickClock(time_till_next_frame);
-  }
-}
-
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveTimer_NotBlocked_UseCase_MAIN_THREAD_CUSTOM_INPUT_HANDLING) {
-  scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
-                                 blink::WebInputEvent::kTouchMove);
-  base::RunLoop().RunUntilIdle();
-  for (int i = 0; i < 20; i++) {
-    simulate_timer_task_ran_ = false;
-
-    viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
-        base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
-        viz::BeginFrameArgs::NORMAL);
-    begin_frame_args.on_critical_path = false;
-    scheduler_->WillBeginFrame(begin_frame_args);
-
-    compositor_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&MainThreadSchedulerImplTest::
-                           SimulateMainThreadInputHandlingCompositorTask,
-                       base::Unretained(this),
-                       base::TimeDelta::FromMilliseconds(8)));
-    timer_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&MainThreadSchedulerImplTest::SimulateTimerTask,
-                       base::Unretained(this),
-                       base::TimeDelta::FromMilliseconds(10)));
-
-    base::RunLoop().RunUntilIdle();
-    EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase())
-        << " i = " << i;
-    EXPECT_FALSE(LoadingTasksSeemExpensive()) << " i = " << i;
-    if (i == 0) {
-      EXPECT_FALSE(TimerTasksSeemExpensive()) << " i = " << i;
-    } else {
-      EXPECT_TRUE(TimerTasksSeemExpensive()) << " i = " << i;
-    }
-    EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i;
-
-    base::TimeDelta time_till_next_frame = EstimatedNextFrameBegin() - Now();
-    if (time_till_next_frame > base::TimeDelta())
-      test_task_runner_->AdvanceMockTickClock(time_till_next_frame);
-  }
-}
-
-TEST_F(MainThreadSchedulerImplTest,
        EstimateLongestJankFreeTaskDuration_UseCase_NONE) {
   EXPECT_EQ(UseCase::kNone, CurrentUseCase());
   EXPECT_EQ(rails_response_time(),
@@ -3145,67 +2647,6 @@
 }  // namespace
 
 TEST_F(MainThreadSchedulerImplTest,
-       SYNCHRONIZED_GESTURE_TimerTaskThrottling_task_expensive) {
-  SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart);
-
-  base::TimeTicks first_throttled_run_time =
-      TaskQueueThrottler::AlignedThrottledRunTime(Now());
-
-  size_t count = 0;
-  // With the compositor task taking 10ms, there is not enough time to run this
-  // 7ms timer task in the 16ms frame.
-  timer_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(SlowCountingTask, &count, test_task_runner_, 7,
-                                timer_task_runner_));
-
-  for (int i = 0; i < 1000; i++) {
-    viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
-        base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
-        viz::BeginFrameArgs::NORMAL);
-    begin_frame_args.on_critical_path = true;
-    scheduler_->WillBeginFrame(begin_frame_args);
-    scheduler_->DidHandleInputEventOnCompositorThread(
-        FakeInputEvent(blink::WebInputEvent::kGestureScrollUpdate),
-        InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-
-    compositor_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&MainThreadSchedulerImplTest::
-                           SimulateMainThreadCompositorAndQuitRunLoopTask,
-                       base::Unretained(this),
-                       base::TimeDelta::FromMilliseconds(10)));
-
-    base::RunLoop().RunUntilIdle();
-    EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()) << "i = " << i;
-
-    // We expect the queue to get throttled on the second iteration which is
-    // when the system realizes the task is expensive.
-    bool expect_queue_throttled = (i > 0);
-    EXPECT_EQ(expect_queue_throttled,
-              scheduler_->task_queue_throttler()->IsThrottled(
-                  timer_task_queue_.get()))
-        << "i = " << i;
-
-    if (expect_queue_throttled) {
-      EXPECT_GE(count, 2u);
-    } else {
-      EXPECT_LE(count, 2u);
-    }
-
-    // The task runs twice before the system realizes it's too expensive.
-    bool throttled_task_has_run = count > 2;
-    bool throttled_task_expected_to_have_run =
-        (Now() > first_throttled_run_time);
-    EXPECT_EQ(throttled_task_expected_to_have_run, throttled_task_has_run)
-        << "i = " << i << " count = " << count;
-  }
-
-  // Task is throttled but not completely blocked.
-  EXPECT_EQ(12u, count);
-}
-
-TEST_F(MainThreadSchedulerImplTest,
        SYNCHRONIZED_GESTURE_TimerTaskThrottling_TimersStopped) {
   SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
 
@@ -3300,34 +2741,6 @@
   EXPECT_EQ(500u, count);
 }
 
-TEST_F(MainThreadSchedulerImplTest,
-       ExpensiveTimerTaskBlocked_SYNCHRONIZED_GESTURE_GestureExpected) {
-  SimulateExpensiveTasks(timer_task_runner_);
-  scheduler_->DidHandleInputEventOnCompositorThread(
-      FakeTouchEvent(blink::WebInputEvent::kTouchStart),
-      InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  ForceBlockingInputToBeExpectedSoon();
-
-  // Bump us into SYNCHRONIZED_GESTURE.
-  scheduler_->DidHandleInputEventOnCompositorThread(
-      FakeInputEvent(blink::WebInputEvent::kGestureScrollUpdate),
-      InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-
-  viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
-      base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
-      viz::BeginFrameArgs::NORMAL);
-  begin_frame_args.on_critical_path = true;
-  scheduler_->WillBeginFrame(begin_frame_args);
-
-  EXPECT_EQ(UseCase::kSynchronizedGesture,
-            ForceUpdatePolicyAndGetCurrentUseCase());
-
-  EXPECT_TRUE(TimerTasksSeemExpensive());
-  EXPECT_TRUE(BlockingInputExpectedSoon());
-  EXPECT_FALSE(timer_task_queue_->IsQueueEnabled());
-}
-
 TEST_F(MainThreadSchedulerImplTest, DenyLongIdleDuringTouchStart) {
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeTouchEvent(blink::WebInputEvent::kTouchStart),
@@ -4145,6 +3558,28 @@
                   base::TimeDelta::FromMicroseconds(400 + 50 + 50 + 1250)));
 }
 
+TEST_F(MainThreadSchedulerImplTest, TaskQueueReferenceClearedOnShutdown) {
+  // Ensure that the scheduler clears its references to a task queue after
+  // |shutdown| and doesn't try to update its policies.
+  scoped_refptr<MainThreadTaskQueue> queue1 = scheduler_->NewTimerTaskQueue(
+      MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr);
+  scoped_refptr<MainThreadTaskQueue> queue2 = scheduler_->NewTimerTaskQueue(
+      MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr);
+
+  EXPECT_EQ(queue1->GetTimeDomain(), scheduler_->real_time_domain());
+  EXPECT_EQ(queue2->GetTimeDomain(), scheduler_->real_time_domain());
+
+  scheduler_->OnShutdownTaskQueue(queue1);
+
+  scheduler_->EnableVirtualTime(
+      MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE);
+
+  // Virtual time should be enabled for queue2, as it is a regular queue and
+  // nothing should change for queue1 because it was shut down.
+  EXPECT_EQ(queue1->GetTimeDomain(), scheduler_->real_time_domain());
+  EXPECT_EQ(queue2->GetTimeDomain(), scheduler_->GetVirtualTimeDomain());
+}
+
 }  // namespace main_thread_scheduler_impl_unittest
 }  // namespace scheduler
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.cc b/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.cc
deleted file mode 100644
index 0686a1e..0000000
--- a/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h"
-
-#include "base/time/default_tick_clock.h"
-
-namespace blink {
-namespace scheduler {
-
-TaskCostEstimator::TaskCostEstimator(const base::TickClock* time_source,
-                                     int sample_count,
-                                     double estimation_percentile)
-    : rolling_time_delta_history_(sample_count),
-      time_source_(time_source),
-      outstanding_task_count_(0),
-      estimation_percentile_(estimation_percentile) {}
-
-TaskCostEstimator::~TaskCostEstimator() = default;
-
-void TaskCostEstimator::WillProcessTask(const base::PendingTask& pending_task) {
-  // Avoid measuring the duration in nested run loops.
-  if (++outstanding_task_count_ == 1)
-    task_start_time_ = time_source_->NowTicks();
-}
-
-void TaskCostEstimator::DidProcessTask(const base::PendingTask& pending_task) {
-  if (--outstanding_task_count_ == 0) {
-    base::TimeDelta duration = time_source_->NowTicks() - task_start_time_;
-    rolling_time_delta_history_.InsertSample(duration);
-  }
-}
-
-base::TimeDelta TaskCostEstimator::expected_task_duration() const {
-  return rolling_time_delta_history_.Percentile(estimation_percentile_);
-}
-
-void TaskCostEstimator::Clear() {
-  rolling_time_delta_history_.Clear();
-  expected_task_duration_ = base::TimeDelta();
-}
-
-}  // namespace scheduler
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h b/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h
deleted file mode 100644
index c3e54a3..0000000
--- a/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_TASK_COST_ESTIMATOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_TASK_COST_ESTIMATOR_H_
-
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/time/time.h"
-#include "cc/base/rolling_time_delta_history.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-
-namespace base {
-class TickClock;
-}
-
-namespace blink {
-namespace scheduler {
-
-// Estimates the cost of running tasks based on historical timing data.
-class PLATFORM_EXPORT TaskCostEstimator
-    : public base::MessageLoop::TaskObserver {
- public:
-  TaskCostEstimator(const base::TickClock* time_source,
-                    int sample_count,
-                    double estimation_percentile);
-  ~TaskCostEstimator() override;
-
-  base::TimeDelta expected_task_duration() const;
-
-  // TaskObserver implementation:
-  void WillProcessTask(const base::PendingTask& pending_task) override;
-  void DidProcessTask(const base::PendingTask& pending_task) override;
-
-  void Clear();
-
- private:
-  cc::RollingTimeDeltaHistory rolling_time_delta_history_;
-  const base::TickClock* time_source_;  // NOT OWNED
-  int outstanding_task_count_;
-  double estimation_percentile_;
-  base::TimeTicks task_start_time_;
-  base::TimeDelta expected_task_duration_;
-
-  DISALLOW_COPY_AND_ASSIGN(TaskCostEstimator);
-};
-
-}  // namespace scheduler
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_TASK_COST_ESTIMATOR_H_