Version 2.13.0-66.0.dev

Merge commit '9d03dd9378dba33c91f232b54ec53d09cb461116' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 6e9dc2f..a11211b 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-02-22T14:34:08.519603",
+  "generated": "2021-02-22T20:16:11.942470",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
diff --git a/DEPS b/DEPS
index deb7166..022463e 100644
--- a/DEPS
+++ b/DEPS
@@ -126,7 +126,7 @@
   "mime_rev": "c931f4bed87221beaece356494b43731445ce7b8",
   "mockito_rev": "d39ac507483b9891165e422ec98d9fb480037c8b",
   "mustache_rev": "664737ecad027e6b96d0d1e627257efa0e46fcb1",
-  "oauth2_tag": "1.6.0",
+  "oauth2_rev": "95b6c8d96dc37a1723480961665d3477a46dd303",
   "package_config_rev": "249af482de9ebabfc781bf10d6152c938e5ce45e",
   "path_rev": "407ab76187fade41c31e39c745b39661b710106c",
   "pedantic_rev": "df177f6ae531426aaf7bbf0121c90dc89d9c57bf",
@@ -381,7 +381,7 @@
       + "external/github.com/xxgreg/mustache"
       + "@" + Var("mustache_rev"),
   Var("dart_root") + "/third_party/pkg/oauth2":
-      Var("dart_git") + "oauth2.git" + "@" + Var("oauth2_tag"),
+      Var("dart_git") + "oauth2.git" + "@" + Var("oauth2_rev"),
   Var("dart_root") + "/third_party/pkg_tested/package_config":
       Var("dart_git") + "package_config.git" +
       "@" + Var("package_config_rev"),
diff --git a/benchmarks/FfiCall/dart/FfiCall.dart b/benchmarks/FfiCall/dart/FfiCall.dart
index ce48f50..6236369 100644
--- a/benchmarks/FfiCall/dart/FfiCall.dart
+++ b/benchmarks/FfiCall/dart/FfiCall.dart
@@ -208,11 +208,11 @@
 
 typedef NativeFunction2Double = Double Function(Double, Double);
 final function2Double = ffiTestFunctions
-    .lookupFunction<NativeFunction2Double, Function2double>('Function1Double');
+    .lookupFunction<NativeFunction2Double, Function2double>('Function2Double');
 
 typedef NativeFunction4Double = Double Function(Double, Double, Double, Double);
 final function4Double = ffiTestFunctions
-    .lookupFunction<NativeFunction4Double, Function4double>('Function1Double');
+    .lookupFunction<NativeFunction4Double, Function4double>('Function4Double');
 
 typedef NativeFunction10Double = Double Function(Double, Double, Double, Double,
     Double, Double, Double, Double, Double, Double);
@@ -941,9 +941,9 @@
   @override
   void run() {
     final double x = doCall1Float(N);
-    final double expected = N * (N - 1) / 2 + N * 42;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (17.0 + 42);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -954,9 +954,9 @@
   @override
   void run() {
     final double x = doCall2Float(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (1.0 + 2.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -967,9 +967,9 @@
   @override
   void run() {
     final double x = doCall4Float(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (1.0 + 2.0 + 3.0 + 4.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -980,9 +980,10 @@
   @override
   void run() {
     final double x = doCall10Float(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected =
+        N * (1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + 10.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -993,9 +994,29 @@
   @override
   void run() {
     final double x = doCall20Float(N);
-    final double expected = N * 220.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N *
+        (1.0 +
+            2.0 +
+            3.0 +
+            4.0 +
+            5.0 +
+            6.0 +
+            7.0 +
+            8.0 +
+            9.0 +
+            10.0 +
+            11.0 +
+            12.0 +
+            13.0 +
+            14.0 +
+            15.0 +
+            16.0 +
+            17.0 +
+            18.0 +
+            19.0 +
+            20.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -1006,9 +1027,9 @@
   @override
   void run() {
     final double x = doCall1Double(N);
-    final double expected = N * (N - 1) / 2 + N * 42;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (17.0 + 42.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -1019,9 +1040,9 @@
   @override
   void run() {
     final double x = doCall2Double(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (1.0 + 2.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -1032,9 +1053,9 @@
   @override
   void run() {
     final double x = doCall4Double(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (1.0 + 2.0 + 3.0 + 4.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -1045,9 +1066,10 @@
   @override
   void run() {
     final double x = doCall10Double(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected =
+        N * (1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + 10.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -1058,9 +1080,29 @@
   @override
   void run() {
     final double x = doCall20Double(N);
-    final double expected = N * 220.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N *
+        (1.0 +
+            2.0 +
+            3.0 +
+            4.0 +
+            5.0 +
+            6.0 +
+            7.0 +
+            8.0 +
+            9.0 +
+            10.0 +
+            11.0 +
+            12.0 +
+            13.0 +
+            14.0 +
+            15.0 +
+            16.0 +
+            17.0 +
+            18.0 +
+            19.0 +
+            20.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
diff --git a/benchmarks/FfiCall/dart2/FfiCall.dart b/benchmarks/FfiCall/dart2/FfiCall.dart
index 3e6f297..34b9fc0 100644
--- a/benchmarks/FfiCall/dart2/FfiCall.dart
+++ b/benchmarks/FfiCall/dart2/FfiCall.dart
@@ -210,11 +210,11 @@
 
 typedef NativeFunction2Double = Double Function(Double, Double);
 final function2Double = ffiTestFunctions
-    .lookupFunction<NativeFunction2Double, Function2double>('Function1Double');
+    .lookupFunction<NativeFunction2Double, Function2double>('Function2Double');
 
 typedef NativeFunction4Double = Double Function(Double, Double, Double, Double);
 final function4Double = ffiTestFunctions
-    .lookupFunction<NativeFunction4Double, Function4double>('Function1Double');
+    .lookupFunction<NativeFunction4Double, Function4double>('Function4Double');
 
 typedef NativeFunction10Double = Double Function(Double, Double, Double, Double,
     Double, Double, Double, Double, Double, Double);
@@ -943,9 +943,9 @@
   @override
   void run() {
     final double x = doCall1Float(N);
-    final double expected = N * (N - 1) / 2 + N * 42;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (17.0 + 42);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -956,9 +956,9 @@
   @override
   void run() {
     final double x = doCall2Float(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (1.0 + 2.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -969,9 +969,9 @@
   @override
   void run() {
     final double x = doCall4Float(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (1.0 + 2.0 + 3.0 + 4.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -982,9 +982,10 @@
   @override
   void run() {
     final double x = doCall10Float(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected =
+        N * (1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + 10.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -995,9 +996,29 @@
   @override
   void run() {
     final double x = doCall20Float(N);
-    final double expected = N * 220.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N *
+        (1.0 +
+            2.0 +
+            3.0 +
+            4.0 +
+            5.0 +
+            6.0 +
+            7.0 +
+            8.0 +
+            9.0 +
+            10.0 +
+            11.0 +
+            12.0 +
+            13.0 +
+            14.0 +
+            15.0 +
+            16.0 +
+            17.0 +
+            18.0 +
+            19.0 +
+            20.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -1008,9 +1029,9 @@
   @override
   void run() {
     final double x = doCall1Double(N);
-    final double expected = N * (N - 1) / 2 + N * 42;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (17.0 + 42.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -1021,9 +1042,9 @@
   @override
   void run() {
     final double x = doCall2Double(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (1.0 + 2.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -1034,9 +1055,9 @@
   @override
   void run() {
     final double x = doCall4Double(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N * (1.0 + 2.0 + 3.0 + 4.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -1047,9 +1068,10 @@
   @override
   void run() {
     final double x = doCall10Double(N);
-    final double expected = N * 55.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected =
+        N * (1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + 10.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
@@ -1060,9 +1082,29 @@
   @override
   void run() {
     final double x = doCall20Double(N);
-    final double expected = N * 220.0;
-    if (0.999 * expected > x && x > 1.001 * expected) {
-      throw Exception('$name: Unexpected result: $x');
+    final double expected = N *
+        (1.0 +
+            2.0 +
+            3.0 +
+            4.0 +
+            5.0 +
+            6.0 +
+            7.0 +
+            8.0 +
+            9.0 +
+            10.0 +
+            11.0 +
+            12.0 +
+            13.0 +
+            14.0 +
+            15.0 +
+            16.0 +
+            17.0 +
+            18.0 +
+            19.0 +
+            20.0);
+    if (0.999 * expected > x || x > 1.001 * expected) {
+      throw Exception('$name: Unexpected result: $x, expected $expected');
     }
   }
 }
diff --git a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
index 30d1728..03e4627 100644
--- a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/context_builder.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:cli_util/cli_util.dart';
 
@@ -50,6 +51,7 @@
       includedPaths: includedPaths,
       excludedPaths: excludedPaths,
     );
+    var fileContentOverlay = FileContentOverlay();
     for (var root in roots) {
       var contextBuilder = ContextBuilderImpl(
         resourceProvider: this.resourceProvider,
@@ -60,6 +62,7 @@
         declaredVariables: DeclaredVariables.fromMap(declaredVariables ?? {}),
         drainStreams: drainStreams,
         enableIndex: enableIndex,
+        fileContentOverlay: fileContentOverlay,
         performanceLog: performanceLog,
         retainDataForTesting: retainDataForTesting,
         sdkPath: sdkPath,
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
index e98ab16..7353694 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
@@ -43,6 +43,7 @@
       DeclaredVariables? declaredVariables,
       bool drainStreams = true,
       bool enableIndex = false,
+      FileContentOverlay? fileContentOverlay,
       List<String>? librarySummaryPaths,
       PerformanceLog? performanceLog,
       bool retainDataForTesting = false,
@@ -54,7 +55,7 @@
     ArgumentError.checkNotNull(sdkPath, 'sdkPath');
 
     byteStore ??= MemoryByteStore();
-    var fileContentOverlay = FileContentOverlay();
+    fileContentOverlay ??= FileContentOverlay();
     performanceLog ??= PerformanceLog(StringBuffer());
 
     DartSdkManager sdkManager = DartSdkManager(sdkPath);
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 16cc361..b8e8b06 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -270,7 +270,7 @@
   return FLAG_warn_on_pause_with_no_debugger || Service::debug_stream.enabled();
 }
 
-void Debugger::InvokeEventHandler(ServiceEvent* event) {
+static void InvokeEventHandler(ServiceEvent* event) {
   ASSERT(!event->IsPause());  // For pause events, call Pause instead.
   Service::HandleEvent(event);
 }
@@ -290,12 +290,12 @@
     return Thread::Current()->StealStickyError();
   }
   ServiceEvent event(isolate_, kind);
-  DebuggerStackTrace* trace = CollectStackTrace();
+  DebuggerStackTrace* trace = DebuggerStackTrace::Collect();
   if (trace->Length() > 0) {
     event.set_top_frame(trace->FrameAt(0));
   }
-  CacheStackTraces(trace, CollectAsyncCausalStackTrace(),
-                   CollectAwaiterReturnStackTrace());
+  CacheStackTraces(trace, DebuggerStackTrace::CollectAsyncCausal(),
+                   DebuggerStackTrace::CollectAwaiterReturn());
   resume_action_ = kContinue;
   Pause(&event);
   HandleSteppingRequest(trace);
@@ -378,7 +378,7 @@
   return bpt;
 }
 
-const char* Debugger::QualifiedFunctionName(const Function& func) {
+static const char* QualifiedFunctionName(const Function& func) {
   const String& func_name = String::Handle(func.name());
   Class& func_class = Class::Handle(func.Owner());
   String& class_name = String::Handle(func_class.Name());
@@ -504,7 +504,7 @@
 }
 
 StringPtr ActivationFrame::QualifiedFunctionName() {
-  return String::New(Debugger::QualifiedFunctionName(function()));
+  return String::New(::dart::QualifiedFunctionName(function()));
 }
 
 StringPtr ActivationFrame::SourceUrl() {
@@ -1568,6 +1568,9 @@
   }
 }
 
+static ActivationFrame* TopDartFrame();
+static bool IsAtAsyncJump(ActivationFrame* top_frame);
+
 bool Debugger::SetupStepOverAsyncSuspension(const char** error) {
   ActivationFrame* top_frame = TopDartFrame();
   if (!IsAtAsyncJump(top_frame)) {
@@ -1592,6 +1595,8 @@
   return true;
 }
 
+static bool CanRewindFrame(intptr_t frame_index, const char** error);
+
 bool Debugger::SetResumeAction(ResumeAction action,
                                intptr_t frame_index,
                                const char** error) {
@@ -1714,13 +1719,14 @@
   isolate_->set_single_step(value);
 }
 
-ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
-                                            uword pc,
-                                            StackFrame* frame,
-                                            const Code& code,
-                                            const Array& deopt_frame,
-                                            intptr_t deopt_frame_offset,
-                                            ActivationFrame::Kind kind) {
+static ActivationFrame* CollectDartFrame(
+    Isolate* isolate,
+    uword pc,
+    StackFrame* frame,
+    const Code& code,
+    const Array& deopt_frame,
+    intptr_t deopt_frame_offset,
+    ActivationFrame::Kind kind = ActivationFrame::kRegular) {
   ASSERT(code.ContainsInstructionAt(pc));
   ActivationFrame* activation =
       new ActivationFrame(pc, frame->fp(), frame->sp(), code, deopt_frame,
@@ -1734,9 +1740,9 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-ArrayPtr Debugger::DeoptimizeToArray(Thread* thread,
-                                     StackFrame* frame,
-                                     const Code& code) {
+static ArrayPtr DeoptimizeToArray(Thread* thread,
+                                  StackFrame* frame,
+                                  const Code& code) {
   ASSERT(code.is_optimized() && !code.is_force_optimized());
   Isolate* isolate = thread->isolate();
   // Create the DeoptContext for this deoptimization.
@@ -1757,7 +1763,7 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-DebuggerStackTrace* Debugger::CollectStackTrace() {
+DebuggerStackTrace* DebuggerStackTrace::Collect() {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
@@ -1778,21 +1784,22 @@
     }
     if (frame->IsDartFrame()) {
       code = frame->LookupDartCode();
-      AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code,
-                       &inlined_code, &deopt_frame);
+      stack_trace->AppendCodeFrames(thread, isolate, zone, frame, &code,
+                                    &inlined_code, &deopt_frame);
     }
   }
   return stack_trace;
 }
 
-void Debugger::AppendCodeFrames(Thread* thread,
-                                Isolate* isolate,
-                                Zone* zone,
-                                DebuggerStackTrace* stack_trace,
-                                StackFrame* frame,
-                                Code* code,
-                                Code* inlined_code,
-                                Array* deopt_frame) {
+// Appends at least one stack frame. Multiple frames will be appended
+// if |code| at the frame's pc contains inlined functions.
+void DebuggerStackTrace::AppendCodeFrames(Thread* thread,
+                                          Isolate* isolate,
+                                          Zone* zone,
+                                          StackFrame* frame,
+                                          Code* code,
+                                          Code* inlined_code,
+                                          Array* deopt_frame) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
   if (code->is_optimized()) {
     if (code->is_force_optimized()) {
@@ -1817,20 +1824,19 @@
                      function.ToFullyQualifiedCString());
       }
       intptr_t deopt_frame_offset = it.GetDeoptFpOffset();
-      stack_trace->AddActivation(CollectDartFrame(isolate, it.pc(), frame,
-                                                  *inlined_code, *deopt_frame,
-                                                  deopt_frame_offset));
+      AddActivation(CollectDartFrame(isolate, it.pc(), frame, *inlined_code,
+                                     *deopt_frame, deopt_frame_offset));
     }
     return;
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
-  stack_trace->AddActivation(CollectDartFrame(isolate, frame->pc(), frame,
-                                              *code, Object::null_array(), 0));
+  AddActivation(CollectDartFrame(isolate, frame->pc(), frame, *code,
+                                 Object::null_array(), 0));
 }
 
-DebuggerStackTrace* Debugger::CollectAsyncCausalStackTrace() {
+DebuggerStackTrace* DebuggerStackTrace::CollectAsyncCausal() {
   if (FLAG_lazy_async_stacks) {
-    return CollectAsyncLazyStackTrace();
+    return CollectAsyncLazy();
   }
   if (!FLAG_causal_async_stacks) {
     return nullptr;
@@ -1838,7 +1844,7 @@
   UNREACHABLE();  //  FLAG_causal_async_stacks is deprecated.
 }
 
-DebuggerStackTrace* Debugger::CollectAsyncLazyStackTrace() {
+DebuggerStackTrace* DebuggerStackTrace::CollectAsyncLazy() {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
@@ -1858,8 +1864,8 @@
 
   std::function<void(StackFrame*)> on_sync_frame = [&](StackFrame* frame) {
     code = frame->LookupDartCode();
-    AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code,
-                     &inlined_code, &deopt_frame);
+    stack_trace->AppendCodeFrames(thread, isolate, zone, frame, &code,
+                                  &inlined_code, &deopt_frame);
   };
 
   StackTraceUtils::CollectFramesLazy(thread, code_array, &pc_offset_array,
@@ -1906,7 +1912,7 @@
   return stack_trace;
 }
 
-DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() {
+DebuggerStackTrace* DebuggerStackTrace::CollectAwaiterReturn() {
 #if defined(DART_PRECOMPILED_RUNTIME)
   // Causal async stacks are not supported in the AOT runtime.
   ASSERT(!FLAG_async_debugger);
@@ -2066,7 +2072,7 @@
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
-ActivationFrame* Debugger::TopDartFrame() const {
+static ActivationFrame* TopDartFrame() {
   StackFrameIterator iterator(ValidationPolicy::kDontValidateFrames,
                               Thread::Current(),
                               StackFrameIterator::kNoCrossThreadIteration);
@@ -2085,32 +2091,22 @@
 }
 
 DebuggerStackTrace* Debugger::StackTrace() {
-  return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace();
-}
-
-DebuggerStackTrace* Debugger::CurrentStackTrace() {
-  return CollectStackTrace();
+  return (stack_trace_ != NULL) ? stack_trace_ : DebuggerStackTrace::Collect();
 }
 
 DebuggerStackTrace* Debugger::AsyncCausalStackTrace() {
-  return (async_causal_stack_trace_ != NULL) ? async_causal_stack_trace_
-                                             : CollectAsyncCausalStackTrace();
-}
-
-DebuggerStackTrace* Debugger::CurrentAsyncCausalStackTrace() {
-  return CollectAsyncCausalStackTrace();
+  return (async_causal_stack_trace_ != NULL)
+             ? async_causal_stack_trace_
+             : DebuggerStackTrace::CollectAsyncCausal();
 }
 
 DebuggerStackTrace* Debugger::AwaiterStackTrace() {
-  return (awaiter_stack_trace_ != NULL) ? awaiter_stack_trace_
-                                        : CollectAwaiterReturnStackTrace();
+  return (awaiter_stack_trace_ != NULL)
+             ? awaiter_stack_trace_
+             : DebuggerStackTrace::CollectAwaiterReturn();
 }
 
-DebuggerStackTrace* Debugger::CurrentAwaiterStackTrace() {
-  return CollectAwaiterReturnStackTrace();
-}
-
-DebuggerStackTrace* Debugger::StackTraceFrom(const class StackTrace& ex_trace) {
+DebuggerStackTrace* DebuggerStackTrace::From(const class StackTrace& ex_trace) {
   DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
   Function& function = Function::Handle();
   Object& code_object = Object::Handle();
@@ -2209,7 +2205,7 @@
 
 void Debugger::PauseException(const Instance& exc) {
   if (FLAG_stress_async_stacks) {
-    CollectAwaiterReturnStackTrace();
+    DebuggerStackTrace::CollectAwaiterReturn();
   }
   // We ignore this exception event when the VM is executing code invoked
   // by the debugger to evaluate variables values, when we see a nested
@@ -2219,8 +2215,9 @@
       (exc_pause_info_ == kNoPauseOnExceptions)) {
     return;
   }
-  DebuggerStackTrace* awaiter_stack_trace = CollectAwaiterReturnStackTrace();
-  DebuggerStackTrace* stack_trace = CollectStackTrace();
+  DebuggerStackTrace* awaiter_stack_trace =
+      DebuggerStackTrace::CollectAwaiterReturn();
+  DebuggerStackTrace* stack_trace = DebuggerStackTrace::Collect();
   if (awaiter_stack_trace != NULL) {
     if (!ShouldPauseOnException(awaiter_stack_trace, exc)) {
       return;
@@ -2235,8 +2232,8 @@
   if (stack_trace->Length() > 0) {
     event.set_top_frame(stack_trace->FrameAt(0));
   }
-  CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(),
-                   CollectAwaiterReturnStackTrace());
+  CacheStackTraces(stack_trace, DebuggerStackTrace::CollectAsyncCausal(),
+                   DebuggerStackTrace::CollectAwaiterReturn());
   Pause(&event);
   HandleSteppingRequest(stack_trace_);  // we may get a rewind request
   ClearCachedStackTraces();
@@ -2342,11 +2339,11 @@
 // algorithm, which would be simpler.  I believe that it only needs
 // two passes to support the recursive try-the-whole-function case.
 // Rewrite this later, once there are more tests in place.
-TokenPosition Debugger::ResolveBreakpointPos(const Function& func,
-                                             TokenPosition requested_token_pos,
-                                             TokenPosition last_token_pos,
-                                             intptr_t requested_column,
-                                             TokenPosition exact_token_pos) {
+static TokenPosition ResolveBreakpointPos(const Function& func,
+                                          TokenPosition requested_token_pos,
+                                          TokenPosition last_token_pos,
+                                          intptr_t requested_column,
+                                          TokenPosition exact_token_pos) {
   ASSERT(!func.HasOptimizedCode());
 
   requested_token_pos =
@@ -2777,6 +2774,12 @@
   return loc;
 }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+static TokenPosition FindExactTokenPosition(const Script& script,
+                                            TokenPosition start_of_line,
+                                            intptr_t column_number);
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 BreakpointLocation* Debugger::SetBreakpoint(const Script& script,
                                             TokenPosition token_pos,
                                             TokenPosition last_token_pos,
@@ -3281,8 +3284,8 @@
   return -1;
 }
 
-// Can the top frame be rewound?
-bool Debugger::CanRewindFrame(intptr_t frame_index, const char** error) const {
+// Can we rewind to the indicated frame?
+static bool CanRewindFrame(intptr_t frame_index, const char** error) {
   // check rewind pc is found
   DebuggerStackTrace* stack = Isolate::Current()->debugger()->StackTrace();
   intptr_t num_frames = stack->Length();
@@ -3539,7 +3542,7 @@
   Pause(&event);
 }
 
-bool Debugger::IsAtAsyncJump(ActivationFrame* top_frame) {
+static bool IsAtAsyncJump(ActivationFrame* top_frame) {
   Zone* zone = Thread::Current()->zone();
   Object& closure_or_null =
       Object::Handle(zone, top_frame->GetAsyncOperation());
@@ -3683,8 +3686,9 @@
                  frame->pc() - frame->code().PayloadStart());
   }
 
-  CacheStackTraces(CollectStackTrace(), CollectAsyncCausalStackTrace(),
-                   CollectAwaiterReturnStackTrace());
+  CacheStackTraces(DebuggerStackTrace::Collect(),
+                   DebuggerStackTrace::CollectAsyncCausal(),
+                   DebuggerStackTrace::CollectAwaiterReturn());
   if (SteppedForSyntheticAsyncBreakpoint()) {
     CleanupSyntheticAsyncBreakpoint();
   }
@@ -3703,27 +3707,31 @@
   if (ignore_breakpoints_ || IsPaused()) {
     return Error::null();
   }
-  DebuggerStackTrace* stack_trace = CollectStackTrace();
+  DebuggerStackTrace* stack_trace = DebuggerStackTrace::Collect();
   ASSERT(stack_trace->Length() > 0);
   ActivationFrame* top_frame = stack_trace->FrameAt(0);
-  ASSERT(top_frame != NULL);
+  ASSERT(top_frame != nullptr);
   CodeBreakpoint* cbpt = GetCodeBreakpoint(top_frame->pc());
-  ASSERT(cbpt != NULL);
+  ASSERT(cbpt != nullptr);
 
   if (!Library::Handle(top_frame->Library()).IsDebuggable()) {
     return Error::null();
   }
 
-  Breakpoint* bpt_hit = FindHitBreakpoint(cbpt->bpt_location_, top_frame);
-  if (bpt_hit == NULL) {
+  BreakpointLocation* bpt_location = cbpt->bpt_location_;
+  if (bpt_location == nullptr) {
+    return Error::null();
+  }
+  Breakpoint* bpt_hit = bpt_location->FindHitBreakpoint(top_frame);
+  if (bpt_hit == nullptr) {
     return Error::null();
   }
 
   if (bpt_hit->is_synthetic_async()) {
-    DebuggerStackTrace* stack_trace = CollectStackTrace();
+    DebuggerStackTrace* stack_trace = DebuggerStackTrace::Collect();
     ASSERT(stack_trace->Length() > 0);
-    CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(),
-                     CollectAwaiterReturnStackTrace());
+    CacheStackTraces(stack_trace, DebuggerStackTrace::CollectAsyncCausal(),
+                     DebuggerStackTrace::CollectAwaiterReturn());
 
     // Hit a synthetic async breakpoint.
     if (FLAG_verbose_debug) {
@@ -3736,9 +3744,9 @@
           top_frame->pc() - top_frame->code().PayloadStart());
     }
 
-    ASSERT(synthetic_async_breakpoint_ == NULL);
+    ASSERT(synthetic_async_breakpoint_ == nullptr);
     synthetic_async_breakpoint_ = bpt_hit;
-    bpt_hit = NULL;
+    bpt_hit = nullptr;
 
     // We are at the entry of an async function.
     // We issue a step over to resume at the point after the await statement.
@@ -3760,8 +3768,8 @@
                  top_frame->pc() - top_frame->code().PayloadStart());
   }
 
-  CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(),
-                   CollectAwaiterReturnStackTrace());
+  CacheStackTraces(stack_trace, DebuggerStackTrace::CollectAsyncCausal(),
+                   DebuggerStackTrace::CollectAwaiterReturn());
   SignalPausedEvent(top_frame, bpt_hit);
   // When we single step from a user breakpoint, our next stepping
   // point will be at the exact same pc.  Skip it.
@@ -3772,17 +3780,13 @@
   return Thread::Current()->StealStickyError();
 }
 
-Breakpoint* Debugger::FindHitBreakpoint(BreakpointLocation* location,
-                                        ActivationFrame* top_frame) {
-  if (location == NULL) {
-    return NULL;
-  }
+Breakpoint* BreakpointLocation::FindHitBreakpoint(ActivationFrame* top_frame) {
   // There may be more than one applicable breakpoint at this location, but we
   // will report only one as reached. If there is a single-shot breakpoint, we
   // favor it; then a closure-specific breakpoint ; then an general breakpoint.
 
   // First check for a single-shot breakpoint.
-  Breakpoint* bpt = location->breakpoints();
+  Breakpoint* bpt = breakpoints();
   while (bpt != NULL) {
     if (bpt->IsSingleShot()) {
       return bpt;
@@ -3791,7 +3795,7 @@
   }
 
   // Now check for a closure-specific breakpoint.
-  bpt = location->breakpoints();
+  bpt = breakpoints();
   while (bpt != NULL) {
     if (bpt->IsPerClosure()) {
       Closure& closure = Closure::Handle(top_frame->GetClosure());
@@ -3803,7 +3807,7 @@
   }
 
   // Finally, check for a general breakpoint.
-  bpt = location->breakpoints();
+  bpt = breakpoints();
   while (bpt != NULL) {
     if (bpt->IsRepeated()) {
       return bpt;
@@ -3822,10 +3826,10 @@
     return;
   }
 
-  DebuggerStackTrace* stack_trace = CollectStackTrace();
+  DebuggerStackTrace* stack_trace = DebuggerStackTrace::Collect();
   ASSERT(stack_trace->Length() > 0);
-  CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(),
-                   CollectAwaiterReturnStackTrace());
+  CacheStackTraces(stack_trace, DebuggerStackTrace::CollectAsyncCausal(),
+                   DebuggerStackTrace::CollectAwaiterReturn());
   // TODO(johnmccutchan): Send |msg| to Observatory.
 
   // We are in the native call to Developer_debugger.  the developer
@@ -3845,8 +3849,8 @@
 
 // Return innermost closure contained in 'function' that contains
 // the given token position.
-FunctionPtr Debugger::FindInnermostClosure(const Function& function,
-                                           TokenPosition token_pos) {
+static FunctionPtr FindInnermostClosure(const Function& function,
+                                        TokenPosition token_pos) {
   ASSERT(function.end_token_pos().IsReal());
   const TokenPosition& func_start = function.token_pos();
   auto thread = Thread::Current();
@@ -3874,9 +3878,9 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 // On single line of code with given column number,
 // Calculate exact tokenPosition
-TokenPosition Debugger::FindExactTokenPosition(const Script& script,
-                                               TokenPosition start_of_line,
-                                               intptr_t column_number) {
+static TokenPosition FindExactTokenPosition(const Script& script,
+                                            TokenPosition start_of_line,
+                                            intptr_t column_number) {
   intptr_t line;
   intptr_t col;
   if (script.GetTokenLocation(start_of_line, &line, &col)) {
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 382eff6..6378fb1 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -167,6 +167,9 @@
   Breakpoint* breakpoints() const { return this->conditions_; }
   void set_breakpoints(Breakpoint* head) { this->conditions_ = head; }
 
+  // Finds the breakpoint we hit at |location|.
+  Breakpoint* FindHitBreakpoint(ActivationFrame* top_frame);
+
   ScriptPtr script_;
   StringPtr url_;
   TokenPosition token_pos_;
@@ -432,14 +435,33 @@
 
   ActivationFrame* GetHandlerFrame(const Instance& exc_obj) const;
 
+  static DebuggerStackTrace* CollectAwaiterReturn();
+  static DebuggerStackTrace* Collect();
+  // Returns a debugger stack trace corresponding to a dart.core.StackTrace.
+  // Frames corresponding to invisible functions are omitted. It is not valid
+  // to query local variables in the returned stack.
+  static DebuggerStackTrace* From(const class StackTrace& ex_trace);
+
  private:
   void AddActivation(ActivationFrame* frame);
   void AddMarker(ActivationFrame::Kind marker);
   void AddAsyncCausalFrame(uword pc, const Code& code);
 
+  void AppendCodeFrames(Thread* thread,
+                        Isolate* isolate,
+                        Zone* zone,
+                        StackFrame* frame,
+                        Code* code,
+                        Code* inlined_code,
+                        Array* deopt_frame);
+
+  static DebuggerStackTrace* CollectAsyncCausal();
+  static DebuggerStackTrace* CollectAsyncLazy();
+
   ZoneGrowableArray<ActivationFrame*> trace_;
 
   friend class Debugger;
+
   DISALLOW_COPY_AND_ASSIGN(DebuggerStackTrace);
 };
 
@@ -549,21 +571,10 @@
   // The trace returned by StackTrace may have been cached; it is suitable for
   // use when stepping, but otherwise may be out of sync with the current stack.
   DebuggerStackTrace* StackTrace();
-  DebuggerStackTrace* CurrentStackTrace();
 
   DebuggerStackTrace* AsyncCausalStackTrace();
-  DebuggerStackTrace* CurrentAsyncCausalStackTrace();
 
   DebuggerStackTrace* AwaiterStackTrace();
-  DebuggerStackTrace* CurrentAwaiterStackTrace();
-
-  // Returns a debugger stack trace corresponding to a dart.core.StackTrace.
-  // Frames corresponding to invisible functions are omitted. It is not valid
-  // to query local variables in the returned stack.
-  DebuggerStackTrace* StackTraceFrom(const class StackTrace& dart_stacktrace);
-
-  // Utility functions.
-  static const char* QualifiedFunctionName(const Function& func);
 
   // Pause execution for a breakpoint.  Called from generated code.
   ErrorPtr PauseBreakpoint();
@@ -590,6 +601,8 @@
   void PrintSettingsToJSONObject(JSONObject* jsobj) const;
 
   static bool IsDebuggable(const Function& func);
+
+  // IsolateGroupDebugger::
   static bool IsDebugging(Thread* thread, const Function& func);
 
   intptr_t limitBreakpointId() { return next_id_; }
@@ -597,40 +610,28 @@
   // Callback to the debugger to continue frame rewind, post-deoptimization.
   void RewindPostDeopt();
 
-  DebuggerStackTrace* CollectAwaiterReturnStackTrace();
-
  private:
   ErrorPtr PauseRequest(ServiceEvent::EventKind kind);
 
-  // Finds the breakpoint we hit at |location|.
-  Breakpoint* FindHitBreakpoint(BreakpointLocation* location,
-                                ActivationFrame* top_frame);
-
   // Will return false if we are not at an await.
   bool SetupStepOverAsyncSuspension(const char** error);
 
   bool NeedsIsolateEvents();
   bool NeedsDebugEvents();
-  void InvokeEventHandler(ServiceEvent* event);
 
   void SendBreakpointEvent(ServiceEvent::EventKind kind, Breakpoint* bpt);
 
-  bool IsAtAsyncJump(ActivationFrame* top_frame);
+  // IsolateGroupDebugger::
   void FindCompiledFunctions(const Script& script,
                              TokenPosition start_pos,
                              TokenPosition end_pos,
                              GrowableObjectArray* code_function_list);
+  // IsolateGroupDebugger::
   bool FindBestFit(const Script& script,
                    TokenPosition token_pos,
                    TokenPosition last_token_pos,
                    Function* best_fit);
-  FunctionPtr FindInnermostClosure(const Function& function,
-                                   TokenPosition token_pos);
-  TokenPosition ResolveBreakpointPos(const Function& func,
-                                     TokenPosition requested_token_pos,
-                                     TokenPosition last_token_pos,
-                                     intptr_t requested_column,
-                                     TokenPosition exact_token_pos);
+  // IsolateGroupDebugger::
   void DeoptimizeWorld();
   void NotifySingleStepping(bool value) const;
   BreakpointLocation* SetCodeBreakpoints(const Script& script,
@@ -669,36 +670,6 @@
   void PrintBreakpointsListToJSONArray(BreakpointLocation* sbpt,
                                        JSONArray* jsarr) const;
 
-  ActivationFrame* TopDartFrame() const;
-  static ActivationFrame* CollectDartFrame(
-      Isolate* isolate,
-      uword pc,
-      StackFrame* frame,
-      const Code& code,
-      const Array& deopt_frame,
-      intptr_t deopt_frame_offset,
-      ActivationFrame::Kind kind = ActivationFrame::kRegular);
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  static ArrayPtr DeoptimizeToArray(Thread* thread,
-                                    StackFrame* frame,
-                                    const Code& code);
-  TokenPosition FindExactTokenPosition(const Script& script,
-                                       TokenPosition start_of_line,
-                                       intptr_t column_number);
-#endif
-  // Appends at least one stack frame. Multiple frames will be appended
-  // if |code| at the frame's pc contains inlined functions.
-  static void AppendCodeFrames(Thread* thread,
-                               Isolate* isolate,
-                               Zone* zone,
-                               DebuggerStackTrace* stack_trace,
-                               StackFrame* frame,
-                               Code* code,
-                               Code* inlined_code,
-                               Array* deopt_frame);
-  static DebuggerStackTrace* CollectStackTrace();
-  static DebuggerStackTrace* CollectAsyncCausalStackTrace();
-  static DebuggerStackTrace* CollectAsyncLazyStackTrace();
   void SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt);
 
   intptr_t nextId() { return next_id_++; }
@@ -718,9 +689,6 @@
                         DebuggerStackTrace* awaiter_stack_trace);
   void ClearCachedStackTraces();
 
-  // Can we rewind to the indicated frame?
-  bool CanRewindFrame(intptr_t frame_index, const char** error) const;
-
   void RewindToFrame(intptr_t frame_index);
   void RewindToUnoptimizedFrame(StackFrame* frame, const Code& code);
   void RewindToOptimizedFrame(StackFrame* frame,
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index 7d9d0ab..965764b 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -88,8 +88,7 @@
   Isolate* I = T->isolate();
   CHECK_DEBUGGER(I);
   CHECK_NOT_NULL(trace);
-  *trace =
-      reinterpret_cast<Dart_StackTrace>(I->debugger()->CurrentStackTrace());
+  *trace = reinterpret_cast<Dart_StackTrace>(DebuggerStackTrace::Collect());
   return Api::Success();
 }
 
@@ -106,9 +105,8 @@
     if (dart_stacktrace.IsNull()) {
       *trace = NULL;
     } else {
-      Isolate* I = T->isolate();
       *trace = reinterpret_cast<Dart_StackTrace>(
-          I->debugger()->StackTraceFrom(dart_stacktrace));
+          DebuggerStackTrace::From(dart_stacktrace));
     }
     return Api::Success();
   } else {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 33d8942..8b81dc7 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -10800,6 +10800,8 @@
   friend class Class;
 };
 
+class DebuggerStackTrace;
+
 // Internal stacktrace object used in exceptions for printing stack traces.
 class StackTrace : public Instance {
  public:
@@ -10856,7 +10858,7 @@
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(StackTrace, Instance);
   friend class Class;
-  friend class Debugger;
+  friend class DebuggerStackTrace;
 };
 
 class RegExpFlags {
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 849bf2f..c54e46f 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -2607,7 +2607,7 @@
       }
     }
     if (FLAG_stress_async_stacks) {
-      isolate->debugger()->CollectAwaiterReturnStackTrace();
+      DebuggerStackTrace::CollectAwaiterReturn();
     }
   }
   if (do_gc) {
diff --git a/tools/VERSION b/tools/VERSION
index 9546ef0..fa1d5b6 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 65
+PRERELEASE 66
 PRERELEASE_PATCH 0
\ No newline at end of file