Version 2.8.4

* Cherry-pick 857fca710fd7b75e5595e198d5fb723f077b4563 to stable
* Cherry-pick 4246b82425e402ad70b5ff48ccd2de00654926a3 to stable
* Cherry-pick 099415b8b87432bfb5559b193f8062c8e790e839 to stable
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 15d525e..dc5035a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 2.8.4 - 2020-06-04
+
+This is a patch release that fixes potential memory leaks in the Dart front-end
+(issues [#42111][] and [#42112][]).
+
+[#42111]: https://github.com/dart-lang/sdk/issues/42111
+[#42112]: https://github.com/dart-lang/sdk/issues/42112
+
 ## 2.8.3 - 2020-05-28
 
 This is a patch release that fixes the following issues:
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 17ea976..347474f 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -328,7 +328,6 @@
 
   IncrementalCompiler _generator;
   JavaScriptBundler _bundler;
-  Component _component;
 
   String _kernelBinaryFilename;
   String _kernelBinaryFilenameIncremental;
@@ -341,6 +340,30 @@
 
   final List<String> errors = List<String>();
 
+  _onDiagnostic(DiagnosticMessage message) {
+    bool printMessage;
+    switch (message.severity) {
+      case Severity.error:
+      case Severity.internalProblem:
+        printMessage = true;
+        errors.addAll(message.plainTextFormatted);
+        break;
+      case Severity.warning:
+        printMessage = true;
+        break;
+      case Severity.context:
+      case Severity.ignored:
+        throw 'Unexpected severity: ${message.severity}';
+    }
+    if (printMessage) {
+      printDiagnosticMessage(message, _outputStream.writeln);
+    }
+  }
+
+  void _installDartdevcTarget() {
+    targets['dartdevc'] = (TargetFlags flags) => DevCompilerTarget(flags);
+  }
+
   @override
   Future<bool> compile(
     String entryPoint,
@@ -378,25 +401,7 @@
           parseExperimentalArguments(options['enable-experiment']),
           onError: (msg) => errors.add(msg))
       ..nnbdMode = options['null-safety'] ? NnbdMode.Strong : NnbdMode.Weak
-      ..onDiagnostic = (DiagnosticMessage message) {
-        bool printMessage;
-        switch (message.severity) {
-          case Severity.error:
-          case Severity.internalProblem:
-            printMessage = true;
-            errors.addAll(message.plainTextFormatted);
-            break;
-          case Severity.warning:
-            printMessage = true;
-            break;
-          case Severity.context:
-          case Severity.ignored:
-            throw 'Unexpected severity: ${message.severity}';
-        }
-        if (printMessage) {
-          printDiagnosticMessage(message, _outputStream.writeln);
-        }
-      };
+      ..onDiagnostic = _onDiagnostic;
 
     if (options.wasParsed('libraries-spec')) {
       compilerOptions.librariesSpecificationUri =
@@ -447,7 +452,7 @@
     )..parseCommandLineFlags(options['bytecode-options']);
 
     // Initialize additional supported kernel targets.
-    targets['dartdevc'] = (TargetFlags flags) => DevCompilerTarget(flags);
+    _installDartdevcTarget();
     compilerOptions.target = createFrontEndTarget(
       options['target'],
       trackWidgetCreation: options['track-widget-creation'],
@@ -496,8 +501,6 @@
           component.uriToSource.keys);
 
       incrementalSerializer = _generator.incrementalSerializer;
-      _component = component;
-      _component.computeCanonicalNames();
     } else {
       if (options['link-platform']) {
         // TODO(aam): Remove linkedDependencies once platform is directly embedded
@@ -538,8 +541,10 @@
       }
 
       _kernelBinaryFilename = _kernelBinaryFilenameIncremental;
-    } else
+    } else {
       _outputStream.writeln(boundaryKey);
+    }
+    results = null; // Fix leak: Probably variation of http://dartbug.com/36983.
     return errors.isEmpty;
   }
 
@@ -917,8 +922,11 @@
       }
       assert(kernel2jsCompiler != null);
 
+      Component component = _generator.lastKnownGoodComponent;
+      component.computeCanonicalNames();
+
       var evaluator = new ExpressionCompiler(
-          _generator.generator, kernel2jsCompiler, _component,
+          _generator.generator, kernel2jsCompiler, component,
           verbose: _compilerOptions.verbose,
           onDiagnostic: _compilerOptions.onDiagnostic);
 
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index aabfcf0..415a3be 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -419,6 +419,9 @@
     List<int> index = <int>[];
     while (_byteOffset > 0) {
       int size = readUint32();
+      if (size <= 0) {
+        throw fail("invalid size '$size' reported at offset $byteOffset");
+      }
       int start = _byteOffset - size;
       if (start < 0) {
         throw fail("indicated size does not match file size");
diff --git a/pkg/kernel/test/binary/invalid_index_size.dart b/pkg/kernel/test/binary/invalid_index_size.dart
new file mode 100644
index 0000000..46f9bc4
--- /dev/null
+++ b/pkg/kernel/test/binary/invalid_index_size.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/binary/ast_from_binary.dart' show ParseError;
+
+import 'utils.dart';
+
+main() {
+  Library lib1 = new Library(Uri.parse("foo://bar.dart"));
+  Component c1 = new Component(libraries: [lib1]);
+  List<int> serialized = serializeComponent(c1);
+  // The last 4 bytes is the size entry in the index. Overwrite that with 0's.
+  for (int i = serialized.length - 4; i < serialized.length; i++) {
+    serialized[i] = 0;
+  }
+  bool gotExpectedException = false;
+  try {
+    loadComponentFromBytes(serialized);
+    throw "The above line should have thrown.";
+  } on ParseError catch (e) {
+    if (e.toString().contains("invalid size")) {
+      gotExpectedException = true;
+    }
+  }
+  if (!gotExpectedException) {
+    throw "Didn't get the right exception!";
+  }
+}
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index 10eeeaa..bf5874e 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -34,6 +34,7 @@
 
   Uri get entryPoint => _entryPoint;
   IncrementalKernelGenerator get generator => _generator;
+  Component get lastKnownGoodComponent => _lastKnownGood;
 
   IncrementalCompiler(this._compilerOptions, this._entryPoint,
       {this.initializeFromDillUri, bool incrementalSerialization: true})
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index fe02d0b..2bf0486 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -135,7 +135,7 @@
   while (reader->offset() > 0) {
     intptr_t size = reader->ReadUInt32();
     intptr_t start = reader->offset() - size;
-    if (start < 0) {
+    if (start < 0 || size <= 0) {
       if (error != nullptr) {
         *error = kKernelInvalidSizeIndicated;
       }
diff --git a/tools/VERSION b/tools/VERSION
index b4b0afc..eb95ae4 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -32,7 +32,7 @@
 CHANNEL stable
 MAJOR 2
 MINOR 8
-PATCH 3
+PATCH 4
 PRERELEASE 0
 PRERELEASE_PATCH 0
 ABI_VERSION 32