Version 2.0.0-dev.47.0

Merge commit 'a86b864fa9b113f5cc4669dc3959d3b7c9761922' into dev
diff --git a/.gitattributes b/.gitattributes
index 631de6a..8f4b8ba 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -14,6 +14,7 @@
 *.yaml text
 
 # Files that should not be converted.
+tests/compiler/dart2js_extra/eof_line_ending_test.dart -text
 tests/compiler/dart2js_extra/string_interpolation_test.dart -text
 tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart -text
 tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart -text
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..d8c2687
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,21 @@
+Thank you for taking the time to file an issue!
+
+In order to route, prioritize, and act on this, please include:
+
+* Dart SDK Version (`dart --version`)
+* Whether you are using Windows, MacOSX, or Linux (if applicable)
+* Whether you are using Chrome, Safari, Firefox, Edge (if applicable)
+
+Missing some or all of the above might make the issue take longer or be
+impossible to act on.
+
+----
+
+Is it really an issue? For general questions consider starting with Stack
+Overflow:
+https://stackoverflow.com/questions/tagged/dart
+
+Also consider our Gitter channel for light-weight/quick discussions:
+https://gitter.im/dart-lang/sdk
+
+-----
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 46c72ce..4d96f13 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,37 @@
+## 2.0.0-dev.47.0
+
+### Tool Changes
+
+#### Analyzer
+
+* The command line analyzer (dartanalyzer) and the analysis server no longer
+  treat directories named `packages` specially. Previously they had ignored
+  these directories - and their contents - from the point of view of analysis. Now
+  they'll be treated just as regular directories. This special-casing of
+  `packages` directories was to support using symlinks for package: resolution;
+  that functionality is now handled by `.packages` files.
+
 ## 2.0.0-dev.46.0
 
 ## 2.0.0-dev.45.0
 
+### Core library changes
+
+* `dart:async`
+  * Removed the deprecated `defaultValue` parameter on `Stream.firstWhere` and
+    `Stream.lastWhere`.
+
+### Tool Changes
+
+#### Pub
+
+* Fix a bug where the version solver could loop infinitely when resolving a
+  conflict involving pre-release constraints ([issue 1863][pub#1863]).
+
+[pub#1863]: https://github.com/dart-lang/pub/issues/1863
+
+## 2.0.0-dev.45.0
+
 ### Tool Changes
 
 #### Pub
@@ -11,6 +41,7 @@
 
 [pub#1856]: https://github.com/dart-lang/pub/issues/1856
 
+
 ## 2.0.0-dev.44.0
 
 ### Tool Changes
diff --git a/DEPS b/DEPS
index fcef030..ebe2a9d 100644
--- a/DEPS
+++ b/DEPS
@@ -67,7 +67,7 @@
   "convert_tag": "@2.0.1",
   "crypto_tag" : "@2.0.2+1",
   "csslib_tag" : "@0.14.1",
-  "dart2js_info_tag" : "@0.5.5+1",
+  "dart2js_info_tag" : "@0.5.6",
 
   # Note: updates to dart_style have to be coordinated carefully with
   # the infrastructure-team so that the internal formatter in
@@ -99,7 +99,7 @@
   "isolate_tag": "@1.1.0",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@2.0.6",
-  "linter_tag": "@0.1.46",
+  "linter_tag": "@0.1.47",
   "logging_tag": "@0.11.3+1",
   "markdown_tag": "@1.1.1",
   "matcher_tag": "@0.12.1+4",
@@ -116,7 +116,7 @@
   "pool_tag": "@1.3.4",
   "protobuf_tag": "@0.7.1",
   "pub_rev": "@4947e0b3cb3ec77e4e8fe0d3141ce4dc60f43256",
-  "pub_semver_tag": "@1.3.4",
+  "pub_semver_tag": "@1.3.6",
   "quiver_tag": "@5aaa3f58c48608af5b027444d561270b53f15dbf",
   "resource_rev":"@af5a5bf65511943398146cf146e466e5f0b95cb9",
   "root_certificates_rev": "@16ef64be64c7dfdff2b9f4b910726e635ccc519e",
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index d7651ac..148fc49 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -211,8 +211,17 @@
 const String FLUTTER_NOTIFICATION_OUTLINE_INSTRUMENTED_CODE =
     'instrumentedCode';
 const String FLUTTER_NOTIFICATION_OUTLINE_OUTLINE = 'outline';
+const String FLUTTER_REQUEST_GET_CHANGE_ADD_FOR_DESIGN_TIME_CONSTRUCTOR =
+    'flutter.getChangeAddForDesignTimeConstructor';
+const String FLUTTER_REQUEST_GET_CHANGE_ADD_FOR_DESIGN_TIME_CONSTRUCTOR_FILE =
+    'file';
+const String FLUTTER_REQUEST_GET_CHANGE_ADD_FOR_DESIGN_TIME_CONSTRUCTOR_OFFSET =
+    'offset';
 const String FLUTTER_REQUEST_SET_SUBSCRIPTIONS = 'flutter.setSubscriptions';
 const String FLUTTER_REQUEST_SET_SUBSCRIPTIONS_SUBSCRIPTIONS = 'subscriptions';
+const String
+    FLUTTER_RESPONSE_GET_CHANGE_ADD_FOR_DESIGN_TIME_CONSTRUCTOR_CHANGE =
+    'change';
 const String KYTHE_REQUEST_GET_KYTHE_ENTRIES = 'kythe.getKytheEntries';
 const String KYTHE_REQUEST_GET_KYTHE_ENTRIES_FILE = 'file';
 const String KYTHE_RESPONSE_GET_KYTHE_ENTRIES_ENTRIES = 'entries';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 4fffb99..cd60f28 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -11072,6 +11072,210 @@
 }
 
 /**
+ * flutter.getChangeAddForDesignTimeConstructor params
+ *
+ * {
+ *   "file": FilePath
+ *   "offset": int
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class FlutterGetChangeAddForDesignTimeConstructorParams
+    implements RequestParams {
+  String _file;
+
+  int _offset;
+
+  /**
+   * The file containing the code of the class.
+   */
+  String get file => _file;
+
+  /**
+   * The file containing the code of the class.
+   */
+  void set file(String value) {
+    assert(value != null);
+    this._file = value;
+  }
+
+  /**
+   * The offset of the class in the code.
+   */
+  int get offset => _offset;
+
+  /**
+   * The offset of the class in the code.
+   */
+  void set offset(int value) {
+    assert(value != null);
+    this._offset = value;
+  }
+
+  FlutterGetChangeAddForDesignTimeConstructorParams(String file, int offset) {
+    this.file = file;
+    this.offset = offset;
+  }
+
+  factory FlutterGetChangeAddForDesignTimeConstructorParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String file;
+      if (json.containsKey("file")) {
+        file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "file");
+      }
+      int offset;
+      if (json.containsKey("offset")) {
+        offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "offset");
+      }
+      return new FlutterGetChangeAddForDesignTimeConstructorParams(
+          file, offset);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath,
+          "flutter.getChangeAddForDesignTimeConstructor params", json);
+    }
+  }
+
+  factory FlutterGetChangeAddForDesignTimeConstructorParams.fromRequest(
+      Request request) {
+    return new FlutterGetChangeAddForDesignTimeConstructorParams.fromJson(
+        new RequestDecoder(request), "params", request.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["file"] = file;
+    result["offset"] = offset;
+    return result;
+  }
+
+  @override
+  Request toRequest(String id) {
+    return new Request(
+        id, "flutter.getChangeAddForDesignTimeConstructor", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is FlutterGetChangeAddForDesignTimeConstructorParams) {
+      return file == other.file && offset == other.offset;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, file.hashCode);
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * flutter.getChangeAddForDesignTimeConstructor result
+ *
+ * {
+ *   "change": SourceChange
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class FlutterGetChangeAddForDesignTimeConstructorResult
+    implements ResponseResult {
+  SourceChange _change;
+
+  /**
+   * The change that adds the forDesignTime() constructor. If the change cannot
+   * be produced, an error is returned.
+   */
+  SourceChange get change => _change;
+
+  /**
+   * The change that adds the forDesignTime() constructor. If the change cannot
+   * be produced, an error is returned.
+   */
+  void set change(SourceChange value) {
+    assert(value != null);
+    this._change = value;
+  }
+
+  FlutterGetChangeAddForDesignTimeConstructorResult(SourceChange change) {
+    this.change = change;
+  }
+
+  factory FlutterGetChangeAddForDesignTimeConstructorResult.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      SourceChange change;
+      if (json.containsKey("change")) {
+        change = new SourceChange.fromJson(
+            jsonDecoder, jsonPath + ".change", json["change"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "change");
+      }
+      return new FlutterGetChangeAddForDesignTimeConstructorResult(change);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath,
+          "flutter.getChangeAddForDesignTimeConstructor result", json);
+    }
+  }
+
+  factory FlutterGetChangeAddForDesignTimeConstructorResult.fromResponse(
+      Response response) {
+    return new FlutterGetChangeAddForDesignTimeConstructorResult.fromJson(
+        new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
+        "result",
+        response.result);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["change"] = change.toJson();
+    return result;
+  }
+
+  @override
+  Response toResponse(String id) {
+    return new Response(id, result: toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is FlutterGetChangeAddForDesignTimeConstructorResult) {
+      return change == other.change;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, change.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * FlutterOutline
  *
  * {
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index c827e0f..84d9d18 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -408,11 +408,6 @@
   static const String LIB_DIR_NAME = 'lib';
 
   /**
-   * The name of `packages` folders.
-   */
-  static const String PACKAGES_NAME = 'packages';
-
-  /**
    * File name of pubspec files.
    */
   static const String PUBSPEC_NAME = 'pubspec.yaml';
@@ -836,9 +831,6 @@
         changeSet.addedSource(source);
         info.sources[path] = source;
       } else if (child is Folder) {
-        if (child.shortName == PACKAGES_NAME) {
-          continue;
-        }
         _addPreviouslyExcludedSources(info, changeSet, child, oldExcludedPaths);
       }
     }
@@ -875,10 +867,6 @@
           info.sources[path] = source;
         }
       } else if (child is Folder) {
-        String shortName = child.shortName;
-        if (shortName == PACKAGES_NAME) {
-          continue;
-        }
         _addSourceFiles(changeSet, child, info);
       }
     }
@@ -1181,9 +1169,7 @@
    */
   void _createContexts(ContextInfo parent, Folder folder,
       List<String> excludedPaths, bool withPackageSpecOnly) {
-    if (_isExcluded(folder.path) ||
-        folder.shortName.startsWith('.') ||
-        folder.shortName == 'packages') {
+    if (_isExcluded(folder.path) || folder.shortName.startsWith('.')) {
       return;
     }
     // Decide whether a context needs to be created for [folder] here, and if
@@ -1383,7 +1369,6 @@
     // maybe excluded globally
     if (_isExcluded(path) ||
         _isContainedInDotFolder(info.folder.path, path) ||
-        _isInPackagesDir(info.folder.path, path) ||
         _isInTopLevelDocDir(info.folder.path, path)) {
       return;
     }
@@ -1527,19 +1512,6 @@
   }
 
   /**
-   * Determine whether the given [path], when interpreted relative to the
-   * context root [root], contains a 'packages' folder.
-   */
-  bool _isInPackagesDir(String root, String path) {
-    String suffixPath = absolutePathContext.suffix(root, path);
-    if (suffixPath == null) {
-      return false;
-    }
-    List<String> pathParts = absolutePathContext.split(suffixPath);
-    return pathParts.contains(PACKAGES_NAME);
-  }
-
-  /**
    * Determine whether the given [path] is in the direct 'doc' folder of the
    * context root [root].
    */
diff --git a/pkg/analysis_server/lib/src/flutter/flutter_correction.dart b/pkg/analysis_server/lib/src/flutter/flutter_correction.dart
index 7e16232..3791140 100644
--- a/pkg/analysis_server/lib/src/flutter/flutter_correction.dart
+++ b/pkg/analysis_server/lib/src/flutter/flutter_correction.dart
@@ -71,7 +71,7 @@
             builder.write('  ');
           }
 
-          builder.writeln('$className.forDesignTime() {');
+          builder.writeln('factory $className.forDesignTime() {');
           builder.writeln('    // TODO: add arguments');
           builder.writeln('    return new $className();');
           builder.write('  }');
diff --git a/pkg/analysis_server/lib/src/flutter/flutter_domain.dart b/pkg/analysis_server/lib/src/flutter/flutter_domain.dart
index aa486b8..5c5470a3 100644
--- a/pkg/analysis_server/lib/src/flutter/flutter_domain.dart
+++ b/pkg/analysis_server/lib/src/flutter/flutter_domain.dart
@@ -2,13 +2,15 @@
 // 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 'dart:core';
+import 'dart:async';
 
 import 'package:analysis_server/protocol/protocol_constants.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_abstract.dart';
+import 'package:analysis_server/src/flutter/flutter_correction.dart';
 import 'package:analysis_server/src/protocol/protocol_internal.dart';
 import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer/dart/analysis/results.dart';
 
 /**
  * A [RequestHandler] that handles requests in the `flutter` domain.
@@ -23,6 +25,11 @@
   Response handleRequest(Request request) {
     try {
       String requestName = request.method;
+      if (requestName ==
+          FLUTTER_REQUEST_GET_CHANGE_ADD_FOR_DESIGN_TIME_CONSTRUCTOR) {
+        getChangeAddForDesignTimeConstructor(request);
+        return Response.DELAYED_RESPONSE;
+      }
       if (requestName == FLUTTER_REQUEST_SET_SUBSCRIPTIONS) {
         return setSubscriptions(request);
       }
@@ -42,4 +49,35 @@
     server.setFlutterSubscriptions(subMap);
     return new FlutterSetSubscriptionsResult().toResponse(request.id);
   }
+
+  /**
+   * Implement the 'flutter.getChangeAddForDesignTimeConstructor' request.
+   */
+  Future getChangeAddForDesignTimeConstructor(Request request) async {
+    var params =
+        new FlutterGetChangeAddForDesignTimeConstructorParams.fromRequest(
+            request);
+    String file = params.file;
+    int offset = params.offset;
+
+    ResolveResult result = await server.getAnalysisResult(file);
+    if (result != null) {
+      var corrections = new FlutterCorrections(
+          file: file,
+          fileContent: result.content,
+          selectionOffset: offset,
+          selectionLength: 0,
+          session: result.session,
+          unit: result.unit);
+      SourceChange change = await corrections.addForDesignTimeConstructor();
+      if (change != null) {
+        server.sendResponse(
+            new FlutterGetChangeAddForDesignTimeConstructorResult(change)
+                .toResponse(request.id));
+        return;
+      }
+    }
+    server.sendResponse(
+        new Response.invalidParameter(request, 'file', 'No change'));
+  }
 }
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index 35cc310..e2e60a6 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -556,7 +556,7 @@
   const A(int i);
 }
 main() {
-  var a = A(0);
+  const a = A(0);
 }
 ''');
     HoverInformation hover = await prepareHover('A(0)');
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index f97f086..db983e5 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -180,24 +180,6 @@
     expect(sourceFactory.forUri('dart:typed_data'), isNotNull);
   }
 
-  test_ignoreFilesInPackagesFolder() {
-    // create a context with a pubspec.yaml file
-    String pubspecPath = path.posix.join(projPath, 'pubspec.yaml');
-    resourceProvider.newFile(pubspecPath, 'pubspec');
-    // create a file in the "packages" folder
-    String filePath1 = path.posix.join(projPath, 'packages', 'file1.dart');
-    resourceProvider.newFile(filePath1, 'contents');
-    // "packages" files are ignored initially
-    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    expect(callbacks.currentFilePaths, isEmpty);
-    // "packages" files are ignored during watch
-    String filePath2 = path.posix.join(projPath, 'packages', 'file2.dart');
-    resourceProvider.newFile(filePath2, 'contents');
-    return pumpEventQueue().then((_) {
-      expect(callbacks.currentFilePaths, isEmpty);
-    });
-  }
-
   void test_isInAnalysisRoot_excluded() {
     // prepare paths
     String project = convertPath('/project');
@@ -238,6 +220,23 @@
     expect(manager.isInAnalysisRoot('/test.dart'), isFalse);
   }
 
+  test_packagesFolder_areAnalyzed() {
+    // create a context with a pubspec.yaml file
+    String pubspecPath = path.posix.join(projPath, 'pubspec.yaml');
+    resourceProvider.newFile(pubspecPath, 'pubspec');
+    // create a file in the "packages" folder
+    String filePath1 = path.posix.join(projPath, 'packages', 'file1.dart');
+    File file1 = resourceProvider.newFile(filePath1, 'contents');
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    expect(callbacks.currentFilePaths, unorderedEquals([file1.path]));
+    String filePath2 = path.posix.join(projPath, 'packages', 'file2.dart');
+    File file2 = resourceProvider.newFile(filePath2, 'contents');
+    return pumpEventQueue().then((_) {
+      expect(callbacks.currentFilePaths,
+          unorderedEquals([file1.path, file2.path]));
+    });
+  }
+
   test_path_filter() async {
     // Setup context.
     Folder root = resourceProvider.newFolder(projPath);
@@ -943,16 +942,6 @@
     expect(callbacks.currentFilePaths, hasLength(0));
   }
 
-  void test_setRoots_noContext_inPackagesFolder() {
-    String pubspecPath = path.posix.join(projPath, 'packages', 'pubspec.yaml');
-    resourceProvider.newFile(pubspecPath, 'name: test');
-    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    // verify
-    expect(callbacks.currentContextRoots, hasLength(1));
-    expect(callbacks.currentContextRoots, contains(projPath));
-    expect(callbacks.currentFilePaths, hasLength(0));
-  }
-
   void test_setRoots_packageResolver() {
     String filePath = join(projPath, 'lib', 'foo.dart');
     newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
@@ -968,6 +957,16 @@
     expect(result.fullName, filePath);
   }
 
+  void test_setRoots_packagesFolder_hasContext() {
+    String pubspecPath = path.posix.join(projPath, 'packages', 'pubspec.yaml');
+    resourceProvider.newFile(pubspecPath, 'name: test');
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    // verify
+    expect(callbacks.currentContextRoots, hasLength(2));
+    expect(callbacks.currentContextRoots, contains(projPath));
+    expect(callbacks.currentFilePaths, hasLength(0));
+  }
+
   void test_setRoots_pathContainsDotFile() {
     // If the path to a file (relative to the context root) contains a folder
     // whose name begins with '.', then the file is ignored.
diff --git a/pkg/analysis_server/test/integration/coverage.md b/pkg/analysis_server/test/integration/coverage.md
index 8ab1806..4dbeae6 100644
--- a/pkg/analysis_server/test/integration/coverage.md
+++ b/pkg/analysis_server/test/integration/coverage.md
@@ -84,5 +84,6 @@
 - [x] kythe.getKytheEntries
 
 ## flutter domain
+- [ ] flutter.getChangeAddForDesignTimeConstructor
 - [ ] flutter.setSubscriptions
 - [ ] flutter.outline
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index cf284ec..9b77a47 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -2118,6 +2118,40 @@
   }
 
   /**
+   * Return the change that adds the forDesignTime() constructor for the widget
+   * class at the given offset.
+   *
+   * Parameters
+   *
+   * file: FilePath
+   *
+   *   The file containing the code of the class.
+   *
+   * offset: int
+   *
+   *   The offset of the class in the code.
+   *
+   * Returns
+   *
+   * change: SourceChange
+   *
+   *   The change that adds the forDesignTime() constructor. If the change
+   *   cannot be produced, an error is returned.
+   */
+  Future<FlutterGetChangeAddForDesignTimeConstructorResult>
+      sendFlutterGetChangeAddForDesignTimeConstructor(
+          String file, int offset) async {
+    var params =
+        new FlutterGetChangeAddForDesignTimeConstructorParams(file, offset)
+            .toJson();
+    var result = await server.send(
+        "flutter.getChangeAddForDesignTimeConstructor", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new FlutterGetChangeAddForDesignTimeConstructorResult.fromJson(
+        decoder, 'result', result);
+  }
+
+  /**
    * Subscribe for services that are specific to individual files. All previous
    * subscriptions are replaced by the current set of subscriptions. If a given
    * service is not included as a key in the map then no files will be
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 464d280..dd07221 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -2486,6 +2486,31 @@
     () => new MatchesJsonObject("extractWidget options", {"name": isString}));
 
 /**
+ * flutter.getChangeAddForDesignTimeConstructor params
+ *
+ * {
+ *   "file": FilePath
+ *   "offset": int
+ * }
+ */
+final Matcher isFlutterGetChangeAddForDesignTimeConstructorParams =
+    new LazyMatcher(() => new MatchesJsonObject(
+        "flutter.getChangeAddForDesignTimeConstructor params",
+        {"file": isFilePath, "offset": isInt}));
+
+/**
+ * flutter.getChangeAddForDesignTimeConstructor result
+ *
+ * {
+ *   "change": SourceChange
+ * }
+ */
+final Matcher isFlutterGetChangeAddForDesignTimeConstructorResult =
+    new LazyMatcher(() => new MatchesJsonObject(
+        "flutter.getChangeAddForDesignTimeConstructor result",
+        {"change": isSourceChange}));
+
+/**
  * flutter.outline params
  *
  * {
diff --git a/pkg/analysis_server/test/src/flutter/flutter_correction_test.dart b/pkg/analysis_server/test/src/flutter/flutter_correction_test.dart
index b285c2b..2e79d3f 100644
--- a/pkg/analysis_server/test/src/flutter/flutter_correction_test.dart
+++ b/pkg/analysis_server/test/src/flutter/flutter_correction_test.dart
@@ -65,7 +65,7 @@
 class MyWidget extends StatelessWidget {
   MyWidget(String text);
 
-  MyWidget.forDesignTime() {
+  factory MyWidget.forDesignTime() {
     // TODO: add arguments
     return new MyWidget();
   }
@@ -97,7 +97,7 @@
 class MyWidget extends StatelessWidget {
   MyWidget();
 
-  MyWidget.forDesignTime() {
+  factory MyWidget.forDesignTime() {
     // TODO: add arguments
     return new MyWidget();
   }
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index e551044..6272649 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -619,6 +619,17 @@
   public void execution_setSubscriptions(List<String> subscriptions);
 
   /**
+   * {@code flutter.getChangeAddForDesignTimeConstructor}
+   *
+   * Return the change that adds the forDesignTime() constructor for the widget class at the given
+   * offset.
+   *
+   * @param file The file containing the code of the class.
+   * @param offset The offset of the class in the code.
+   */
+  public void flutter_getChangeAddForDesignTimeConstructor(String file, int offset, GetChangeAddForDesignTimeConstructorConsumer consumer);
+
+  /**
    * {@code flutter.setSubscriptions}
    *
    * Subscribe for services that are specific to individual files. All previous subscriptions are
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 49e3cb8..50954cd 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -2630,6 +2630,35 @@
   <p>
     The analysis domain contains API’s related to Flutter support.
   </p>
+  <request method="getChangeAddForDesignTimeConstructor">
+    <p>
+      Return the change that adds the forDesignTime() constructor for the
+      widget class at the given offset.
+    </p>
+    <params>
+      <field name="file">
+        <ref>FilePath</ref>
+        <p>
+          The file containing the code of the class.
+        </p>
+      </field>
+      <field name="offset">
+        <ref>int</ref>
+        <p>
+          The offset of the class in the code.
+        </p>
+      </field>
+    </params>
+    <result>
+      <field name="change">
+        <ref>SourceChange</ref>
+        <p>
+          The change that adds the forDesignTime() constructor.
+          If the change cannot be produced, an error is returned.
+        </p>
+      </field>
+    </result>
+  </request>
   <request method="setSubscriptions">
     <p>
       Subscribe for services that are specific to individual files.
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 2f3fc05..83147d0 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -41,11 +41,6 @@
   static const String OLD_ANALYSIS_OPTIONS_NAME = '.analysis_options';
 
   /**
-   * The name of the packages folder.
-   */
-  static const String PACKAGES_DIR_NAME = 'packages';
-
-  /**
    * The name of the packages file.
    */
   static const String PACKAGES_FILE_NAME = '.packages';
@@ -277,8 +272,7 @@
       for (Resource child in folder.getChildren()) {
         if (child is Folder) {
           if (excludedFolders.contains(folder) ||
-              folder.shortName.startsWith('.') ||
-              folder.shortName == PACKAGES_DIR_NAME) {
+              folder.shortName.startsWith('.')) {
             containingRoot.excluded.add(folder);
           } else {
             _createContextRoots(roots, child, excludedFolders, containingRoot,
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_root.dart b/pkg/analyzer/lib/src/dart/analysis/context_root.dart
index 0d3a082..463b9f6 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_root.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_root.dart
@@ -98,8 +98,7 @@
   bool _isExcluded(String path) {
     Context context = resourceProvider.pathContext;
     String name = context.basename(path);
-    if (name.startsWith('.') ||
-        (name == 'packages' && resourceProvider.getResource(path) is Folder)) {
+    if (name.startsWith('.')) {
       return true;
     }
     for (String excludedPath in excludedPaths) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index b596dca..88f8525 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -95,7 +95,7 @@
   /**
    * The version of data format, should be incremented on every format change.
    */
-  static const int DATA_VERSION = 55;
+  static const int DATA_VERSION = 56;
 
   /**
    * The number of exception contexts allowed to write. Once this field is
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 9774ad0..265a55c 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -2766,20 +2766,23 @@
 
   @override
   void onError(AnalysisError error) {
-    switch (error.errorCode) {
-      case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL:
-      case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING:
-      case CompileTimeErrorCode.CONST_EVAL_TYPE_INT:
-      case CompileTimeErrorCode.CONST_EVAL_TYPE_NUM:
-      case CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION:
-      case CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE:
-      case CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT:
-      case CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER:
-      case CompileTimeErrorCode
-          .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST:
-      case CompileTimeErrorCode.INVALID_CONSTANT:
-      case CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL:
-        hasConstError = true;
+    ErrorCode errorCode = error.errorCode;
+    if (errorCode is CompileTimeErrorCode) {
+      switch (errorCode) {
+        case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL:
+        case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING:
+        case CompileTimeErrorCode.CONST_EVAL_TYPE_INT:
+        case CompileTimeErrorCode.CONST_EVAL_TYPE_NUM:
+        case CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION:
+        case CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE:
+        case CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT:
+        case CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER:
+        case CompileTimeErrorCode
+            .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST:
+        case CompileTimeErrorCode.INVALID_CONSTANT:
+        case CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL:
+          hasConstError = true;
+      }
     }
   }
 }
@@ -6555,7 +6558,7 @@
     if (!isImplicit) {
       return keyword.keyword == Keyword.CONST;
     } else {
-      return inConstantContext || canBeConst();
+      return inConstantContext;
     }
   }
 
@@ -6622,6 +6625,13 @@
             }
           }
         }
+      } else if (argument is Identifier) {
+        Element element = argument.bestElement;
+        if (element is PropertyAccessorElement && !element.variable.isConst) {
+          return false;
+        } else if (element is VariableElement && !element.isConst) {
+          return false;
+        }
       } else {
         return false;
       }
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 2dc985f..2951395 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -1633,6 +1633,7 @@
         element is PropertyAccessorElement ? element.variable : element;
     if (variableElement is VariableElementImpl) {
       evaluationEngine.validator.beforeGetEvaluationResult(variableElement);
+      variableElement.computeConstantValue();
       EvaluationResultImpl value = variableElement.evaluationResult;
       if (variableElement.isConst && value != null) {
         return value.value;
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index b07ff69..7e47780 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -69,8 +69,12 @@
       InstanceCreationExpression node) {
     InstanceCreationExpression expression =
         super.visitInstanceCreationExpression(node);
-    if (previewDart2 && node.keyword == null && node.isConst) {
-      expression.keyword = new KeywordToken(Keyword.CONST, node.offset);
+    if (previewDart2 && node.keyword == null) {
+      if (node.isConst) {
+        expression.keyword = new KeywordToken(Keyword.CONST, node.offset);
+      } else {
+        expression.keyword = new KeywordToken(Keyword.NEW, node.offset);
+      }
     }
     expression.staticElement = node.staticElement;
     return expression;
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 836f94c..2b1db80 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -384,6 +384,10 @@
         errorReporter?.reportErrorForOffset(
             ScannerErrorCode.MISSING_DIGIT, offset, length);
         return;
+      case "MISSING_EXPRESSION_IN_THROW":
+        errorReporter?.reportErrorForOffset(
+            ParserErrorCode.MISSING_EXPRESSION_IN_THROW, offset, length);
+        return;
       case "MISSING_ENUM_BODY":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.MISSING_ENUM_BODY, offset, length);
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 529103f..69583e8 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -18,6 +18,7 @@
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
@@ -44,12 +45,14 @@
  * feature.
  */
 class AstRewriteVisitor extends ScopedVisitor {
+  final bool addConstKeyword;
+
   /**
    * Initialize a newly created visitor.
    */
   AstRewriteVisitor(LibraryElement definingLibrary, Source source,
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
-      {Scope nameScope})
+      {Scope nameScope, this.addConstKeyword: false})
       : super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope);
 
@@ -77,7 +80,7 @@
         TypeName typeName = astFactory.typeName(methodName, node.typeArguments);
         InstanceCreationExpression instanceCreationExpression =
             astFactory.instanceCreationExpression(
-                null,
+                _getKeyword(node),
                 astFactory.constructorName(typeName, null, null),
                 node.argumentList);
         DartType type = _getType(element, node.typeArguments);
@@ -100,7 +103,7 @@
           TypeName typeName = astFactory.typeName(target, node.typeArguments);
           InstanceCreationExpression instanceCreationExpression =
               astFactory.instanceCreationExpression(
-                  null,
+                  _getKeyword(node),
                   astFactory.constructorName(
                       typeName, node.operator, methodName),
                   node.argumentList);
@@ -124,7 +127,7 @@
               node.typeArguments);
           InstanceCreationExpression instanceCreationExpression =
               astFactory.instanceCreationExpression(
-                  null,
+                  _getKeyword(node),
                   astFactory.constructorName(typeName, null, null),
                   node.argumentList);
           DartType type = _getType(prefixedElement, node.typeArguments);
@@ -145,7 +148,7 @@
             TypeName typeName = astFactory.typeName(target, node.typeArguments);
             InstanceCreationExpression instanceCreationExpression =
                 astFactory.instanceCreationExpression(
-                    null,
+                    _getKeyword(node),
                     astFactory.constructorName(
                         typeName, node.operator, methodName),
                     node.argumentList);
@@ -162,6 +165,16 @@
   }
 
   /**
+   * Return the token that should be used in the [InstanceCreationExpression]
+   * that corresponds to the given invocation [node].
+   */
+  Token _getKeyword(MethodInvocation node) {
+    return addConstKeyword
+        ? new KeywordToken(Keyword.CONST, node.offset)
+        : null;
+  }
+
+  /**
    * Return the type of the given class [element] after substituting any type
    * arguments from the list of [typeArguments] for the class' type parameters.
    */
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
index ea14ea6..bb05401 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
@@ -182,17 +182,20 @@
       } else if (assetsField != null) {
         _reportErrorForNode(
             reporter, assetsField, PubspecWarningCode.ASSET_FIELD_NOT_LIST);
-      } else {
-        // TODO(brianwilkerson) Should we report an error if `assets` is
-        // missing?
       }
+
       if (flutterField.length > 1) {
         // TODO(brianwilkerson) Should we report an error if `flutter` contains
         // keys other than `assets`?
       }
     } else if (flutterField != null) {
-      _reportErrorForNode(
-          reporter, flutterField, PubspecWarningCode.FLUTTER_FIELD_NOT_MAP);
+      if (flutterField.value == null) {
+        // allow an empty `flutter:` section; explicitly fail on a non-empty,
+        // non-map one
+      } else {
+        _reportErrorForNode(
+            reporter, flutterField, PubspecWarningCode.FLUTTER_FIELD_NOT_MAP);
+      }
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 5dec73d..e03b7aa 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -7,8 +7,10 @@
 import 'dart:collection';
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/handle.dart';
 import 'package:analyzer/src/dart/element/member.dart';
@@ -1119,6 +1121,11 @@
   CompilationUnitElementImpl unit;
 
   /**
+   * The visitor to rewrite implicit `new` and `const`.
+   */
+  AstRewriteVisitor astRewriteVisitor;
+
+  /**
    * Map from slot id to the corresponding [EntityRef] object for linked types
    * (i.e. propagated and inferred types).
    */
@@ -1561,7 +1568,18 @@
   }
 
   Expression _buildConstExpression(ElementImpl context, UnlinkedExpr uc) {
-    return new ExprBuilder(this, context, uc).build();
+    var expression = new ExprBuilder(this, context, uc).build();
+
+    if (expression != null && context.context.analysisOptions.previewDart2) {
+      astRewriteVisitor ??= new AstRewriteVisitor(libraryResynthesizer.library,
+          unit.source, typeProvider, AnalysisErrorListener.NULL_LISTENER,
+          addConstKeyword: true);
+      var container = astFactory.expressionStatement(expression, null);
+      expression.accept(astRewriteVisitor);
+      expression = container.expression;
+    }
+
+    return expression;
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index 2cf21ed..8ac5f4f 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -595,10 +595,6 @@
   }
 
   void _serializeMethodInvocation(MethodInvocation invocation) {
-    if (invocation.target != null ||
-        invocation.methodName.name != 'identical') {
-      isValidConst = false;
-    }
     Expression target = invocation.target;
     SimpleIdentifier methodName = invocation.methodName;
     ArgumentList argumentList = invocation.argumentList;
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 17f11d3..1ab766a 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -472,18 +472,6 @@
 
   @override
   @failingTest
-  void test_missingExpressionInThrow() {
-    // TODO(brianwilkerson) Does not recover.
-    //   type 'RethrowExpressionImpl' is not a subtype of type 'ThrowExpression' of 'expression' where
-    //   RethrowExpressionImpl is from package:analyzer/src/dart/ast/ast.dart
-    //   ThrowExpression is from package:analyzer/dart/ast/ast.dart
-    //
-    //   test/generated/parser_test.dart 3492:59                            FastaParserTestCase&ErrorParserTestMixin.test_missingExpressionInThrow_withCascade
-    super.test_missingExpressionInThrow();
-  }
-
-  @override
-  @failingTest
   void test_missingFunctionParameters_topLevel_void_block() {
     // TODO(brianwilkerson) Wrong errors:
     // Expected 1 errors of type ParserErrorCode.MISSING_FUNCTION_PARAMETERS, found 0
@@ -1202,7 +1190,9 @@
 
   @override
   void addCompileTimeError(Message message, int charOffset, int length, Uri uri,
-      {bool silent: false, bool wasHandled: false, LocatedMessage context}) {
+      {bool silent: false,
+      bool wasHandled: false,
+      List<LocatedMessage> context}) {
     fail('${message.message}');
   }
 
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index a18492f..9a06e00 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -5589,7 +5589,7 @@
 
   void test_varAndType_field() {
     parseCompilationUnit("class C { var int x; }",
-        errors: [expectedError(ParserErrorCode.VAR_AND_TYPE, 14, 3)]);
+        errors: [expectedError(ParserErrorCode.VAR_AND_TYPE, 10, 3)]);
   }
 
   void test_varAndType_local() {
@@ -5614,7 +5614,7 @@
 
   void test_varAndType_topLevelVariable() {
     parseCompilationUnit("var int x;",
-        errors: [expectedError(ParserErrorCode.VAR_AND_TYPE, 4, 3)]);
+        errors: [expectedError(ParserErrorCode.VAR_AND_TYPE, 0, 3)]);
   }
 
   void test_varAsTypeName_as() {
@@ -9685,7 +9685,6 @@
     parser.parseFunctionBodies = parseFunctionBodies;
     parser.enableNnbd = enableNnbd;
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
-    parser.enableUriInPartOf = enableUriInPartOf;
     parser.currentToken = tokenStream;
   }
 
@@ -15044,6 +15043,18 @@
     expect(variableList.type, new isInstanceOf<GenericFunctionType>());
   }
 
+  void test_invalid_typeParamAnnotation() {
+    parseCompilationUnit('main() { C<@Foo T> v; }',
+        errors: usingFastaParser
+            // TODO(danrubel): Improve this error to indicate that annotations
+            // are not valid in this context.
+            ? [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 11, 1)]
+            : [
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 1)
+              ]);
+  }
+
   void test_parseStatement_emptyTypeArgumentList() {
     var declaration = parseStatement('C<> c;') as VariableDeclarationStatement;
     assertErrorsWithCodes([ParserErrorCode.EXPECTED_TYPE_NAME]);
diff --git a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
index b3f133b..ea4762e 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
@@ -211,24 +211,6 @@
     expect(outerRoot.packagesFile, outerPackagesFile);
   }
 
-  void test_locateRoots_nested_excluded_packages() {
-    Folder outerRootFolder = newFolder('/test/outer');
-    File outerOptionsFile = newOptionsFile('/test/outer');
-    File outerPackagesFile = newPackagesFile('/test/outer');
-    Folder excludedFolder = newFolder('/test/outer/packages');
-    newOptionsFile('/test/outer/packages/inner');
-
-    List<ContextRoot> roots =
-        contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
-    expect(roots, hasLength(1));
-
-    ContextRoot outerRoot = findRoot(roots, outerRootFolder);
-    expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
-    expect(outerRoot.excludedPaths, unorderedEquals([excludedFolder.path]));
-    expect(outerRoot.optionsFile, outerOptionsFile);
-    expect(outerRoot.packagesFile, outerPackagesFile);
-  }
-
   void test_locateRoots_nested_multiple() {
     Folder outerRootFolder = newFolder('/test/outer');
     File outerOptionsFile = newOptionsFile('/test/outer');
@@ -450,6 +432,24 @@
     expect(outerRoot.packagesFile, overridePackagesFile);
   }
 
+  void test_locateRoots_nested_packagesDirectory_included() {
+    Folder outerRootFolder = newFolder('/test/outer');
+    File outerOptionsFile = newOptionsFile('/test/outer');
+    File outerPackagesFile = newPackagesFile('/test/outer');
+    File innerOptionsFile = newOptionsFile('/test/outer/packages/inner');
+
+    List<ContextRoot> roots =
+        contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
+    expect(roots, hasLength(2));
+
+    ContextRoot outerRoot = findRoot(roots, outerRootFolder);
+    expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
+    expect(outerRoot.excludedPaths,
+        unorderedEquals([innerOptionsFile.parent.path]));
+    expect(outerRoot.optionsFile, outerOptionsFile);
+    expect(outerRoot.packagesFile, outerPackagesFile);
+  }
+
   void test_locateRoots_single_dir_directOptions_directPackages() {
     Folder rootFolder = newFolder('/test/root');
     File optionsFile = newOptionsFile('/test/root');
diff --git a/pkg/analyzer/test/src/dart/analysis/context_root_test.dart b/pkg/analyzer/test/src/dart/analysis/context_root_test.dart
index 9f15523..573d210 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_root_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_root_test.dart
@@ -65,14 +65,14 @@
     expect(contextRoot.isAnalyzed(filePath), isFalse);
   }
 
-  test_isAnalyzed_implicitlyExcluded_packages() {
-    String folderPath = provider.convertPath('/test/root/lib/packages');
-    provider.newFolder(folderPath);
-    expect(contextRoot.isAnalyzed(folderPath), isFalse);
-  }
-
   test_isAnalyzed_included() {
     String filePath = provider.convertPath('/test/root/lib/root.dart');
     expect(contextRoot.isAnalyzed(filePath), isTrue);
   }
+
+  test_isAnalyzed_packagesDirectory_analyzed() {
+    String folderPath = provider.convertPath('/test/root/lib/packages');
+    provider.newFolder(folderPath);
+    expect(contextRoot.isAnalyzed(folderPath), isTrue);
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 50be7e7..907139e 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -344,6 +344,12 @@
 
 @reflectiveTest
 class AnalysisDriverTest extends BaseAnalysisDriverTest {
+  void configurePreviewDart2() {
+    driver.configure(
+        analysisOptions: new AnalysisOptionsImpl.from(driver.analysisOptions)
+          ..previewDart2 = true);
+  }
+
   test_addedFiles() async {
     var a = _p('/test/lib/a.dart');
     var b = _p('/test/lib/b.dart');
@@ -1002,6 +1008,63 @@
     expect(x.constantValue, isNotNull);
   }
 
+  test_const_implicitCreation() async {
+    configurePreviewDart2();
+
+    var a = _p('/test/bin/a.dart');
+    var b = _p('/test/bin/b.dart');
+    provider.newFile(a, r'''
+class C {
+  const C();
+  static const C WARNING = C();
+}
+''');
+    provider.newFile(b, r'''
+import 'a.dart';
+
+class D {
+  const D();
+  static const D WARNING = D();
+}
+
+const c = C.WARNING;
+const d = D.WARNING;
+''');
+    AnalysisResult result = await driver.getResult(b);
+    expect(result.errors, isEmpty);
+  }
+
+  test_const_implicitCreation_rewrite() async {
+    configurePreviewDart2();
+
+    var a = _p('/test/bin/a.dart');
+    var b = _p('/test/bin/b.dart');
+    provider.newFile(a, r'''
+class A {
+  const A();
+}
+
+class B {
+  final A a;
+  const B(this.a);
+}
+
+class C {
+  const b = B(A());
+  const C();
+}
+''');
+    provider.newFile(b, r'''
+import 'a.dart';
+
+main() {
+  const C();
+}
+''');
+    AnalysisResult result = await driver.getResult(b);
+    expect(result.errors, isEmpty);
+  }
+
   test_const_implicitSuperConstructorInvocation() async {
     addTestFile('''
 class Base {}
diff --git a/pkg/analyzer/test/src/dart/ast/ast_test.dart b/pkg/analyzer/test/src/dart/ast/ast_test.dart
index c037947..c76c2a4 100644
--- a/pkg/analyzer/test/src/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/ast_test.dart
@@ -49,6 +49,32 @@
     assertInContext("C(0", true);
   }
 
+  test_inConstantContext_instanceCreation_fieldWithConstConstructor() {
+    parse('''
+class C {
+  final d = D();
+  const C();
+}
+class D {
+  const D();
+}
+''');
+    assertInContext("D()", false);
+  }
+
+  test_inConstantContext_instanceCreation_fieldWithoutConstConstructor() {
+    parse('''
+class C {
+  final d = D();
+  C();
+}
+class D {
+  const D();
+}
+''');
+    assertInContext("D()", false);
+  }
+
   test_inConstantContext_instanceCreation_functionLiteral() {
     parse('''
 const V = () => C();
@@ -59,26 +85,6 @@
     assertInContext("C()", false);
   }
 
-  test_inConstantContext_instanceCreation_initializer_false() {
-    parse('''
-var c = C();
-class C {
-  const C();
-}
-''');
-    assertInContext("C()", false);
-  }
-
-  test_inConstantContext_instanceCreation_initializer_true() {
-    parse('''
-const c = C();
-class C {
-  const C();
-}
-''');
-    assertInContext("C()", true);
-  }
-
   test_inConstantContext_instanceCreation_instanceCreation_false() {
     parse('''
 f() {
@@ -216,6 +222,26 @@
     assertInContext("C()", true);
   }
 
+  test_inConstantContext_instanceCreation_topLevelVariable_false() {
+    parse('''
+var c = C();
+class C {
+  const C();
+}
+''');
+    assertInContext("C()", false);
+  }
+
+  test_inConstantContext_instanceCreation_topLevelVariable_true() {
+    parse('''
+const c = C();
+class C {
+  const C();
+}
+''');
+    assertInContext("C()", true);
+  }
+
   test_inConstantContext_listLiteral_annotation_true() {
     parse('''
 @C([])
@@ -442,6 +468,8 @@
   String testSource;
   CompilationUnitImpl testUnit;
 
+  bool get enableNewAnalysisDriver => true;
+
   void assertIsConst(String snippet, bool isConst) {
     int index = testSource.indexOf(snippet);
     expect(index >= 0, isTrue);
@@ -462,6 +490,20 @@
     testUnit = await resolveSource2('/test.dart', source);
   }
 
+  void
+      test_isConst_notInContext_constructor_const_constParam_identifier() async {
+    enablePreviewDart2();
+    await resolve('''
+var v = C(C.a);
+class C {
+  static const C a = C.c();
+  const C(c);
+  const C.c();
+}
+''');
+    assertIsConst("C(C", false);
+  }
+
   void test_isConst_notInContext_constructor_const_constParam_named() async {
     enablePreviewDart2();
     await resolve('''
@@ -470,7 +512,7 @@
   const C({c});
 }
 ''');
-    assertIsConst("C(c", true);
+    assertIsConst("C(c", false);
   }
 
   void
@@ -482,7 +524,7 @@
   const C({c});
 }
 ''');
-    assertIsConst("C(c", true);
+    assertIsConst("C(c", false);
   }
 
   void test_isConst_notInContext_constructor_const_constParam_parens() async {
@@ -494,7 +536,7 @@
   const C.c();
 }
 ''');
-    assertIsConst("C( (", true);
+    assertIsConst("C( (", false);
   }
 
   void test_isConst_notInContext_constructor_const_generic_named() async {
@@ -505,7 +547,7 @@
   const C.n();
 }
 ''');
-    assertIsConst("C<int>.n", true);
+    assertIsConst("C<int>.n", false);
   }
 
   void
@@ -520,7 +562,7 @@
 import 'c.dart' as p;
 f() => <Object>[p.C<int>.n()];
 ''');
-    assertIsConst("C<int>", true);
+    assertIsConst("C<int>", false);
   }
 
   void test_isConst_notInContext_constructor_const_generic_unnamed() async {
@@ -531,7 +573,7 @@
   const C();
 }
 ''');
-    assertIsConst("C<int>", true);
+    assertIsConst("C<int>", false);
   }
 
   void
@@ -546,7 +588,7 @@
 import 'c.dart' as p;
 f() => <Object>[p.C<int>()];
 ''');
-    assertIsConst("C<int>", true);
+    assertIsConst("C<int>", false);
   }
 
   void
@@ -589,7 +631,7 @@
   const C.n();
 }
 ''');
-    assertIsConst("C.n()", true);
+    assertIsConst("C.n()", false);
   }
 
   void
@@ -604,7 +646,7 @@
 import 'c.dart' as p;
 f() => <Object>[p.C.n()];
 ''');
-    assertIsConst("C.n()", true);
+    assertIsConst("C.n()", false);
   }
 
   void test_isConst_notInContext_constructor_const_nonGeneric_unnamed() async {
@@ -615,7 +657,7 @@
   const C();
 }
 ''');
-    assertIsConst("C()", true);
+    assertIsConst("C()", false);
   }
 
   void
@@ -630,7 +672,7 @@
 import 'c.dart' as p;
 f() => <Object>[p.C()];
 ''');
-    assertIsConst("C()", true);
+    assertIsConst("C()", false);
   }
 
   void test_isConst_notInContext_constructor_nonConst() async {
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
index 550eecb..9ba13da 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
@@ -36,7 +36,6 @@
               'class _s_ {}',
               failing: <String>[
                 'typedef',
-                'functionVoid',
                 'functionNonVoid',
                 'getter',
                 'setter'
@@ -53,8 +52,7 @@
               'class A extends _s_ {}',
               failing: allExceptEof),
           new TestDescriptor('extendsBody', 'class A extends {}',
-              [ParserErrorCode.EXPECTED_TYPE_NAME], 'class A extends _s_ {}',
-              allFailing: true),
+              [ParserErrorCode.EXPECTED_TYPE_NAME], 'class A extends _s_ {}'),
           new TestDescriptor(
               'extendsWithNameBody',
               'class A extends with B {}',
@@ -80,8 +78,7 @@
               'extendsNameWithBody',
               'class A extends B with {}',
               [ParserErrorCode.EXPECTED_TYPE_NAME],
-              'class A extends B with _s_ {}',
-              allFailing: true),
+              'class A extends B with _s_ {}'),
           new TestDescriptor(
               'extendsNameImplements',
               'class A extends B implements',
@@ -95,8 +92,7 @@
               'extendsNameImplementsBody',
               'class A extends B implements {}',
               [ParserErrorCode.EXPECTED_TYPE_NAME],
-              'class A extends B implements _s_ {}',
-              allFailing: true),
+              'class A extends B implements _s_ {}'),
           new TestDescriptor(
               'extendsNameWithNameImplements',
               'class A extends B with C implements',
@@ -110,8 +106,7 @@
               'extendsNameWithNameImplementsBody',
               'class A extends B with C implements {}',
               [ParserErrorCode.EXPECTED_TYPE_NAME],
-              'class A extends B with C implements _s_ {}',
-              allFailing: true),
+              'class A extends B with C implements _s_ {}'),
           new TestDescriptor(
               'implements',
               'class A implements',
@@ -121,9 +116,11 @@
               ],
               'class A implements _s_ {}',
               failing: allExceptEof),
-          new TestDescriptor('implementsBody', 'class A implements {}',
-              [ParserErrorCode.EXPECTED_TYPE_NAME], 'class A implements _s_ {}',
-              allFailing: true),
+          new TestDescriptor(
+              'implementsBody',
+              'class A implements {}',
+              [ParserErrorCode.EXPECTED_TYPE_NAME],
+              'class A implements _s_ {}'),
           new TestDescriptor(
               'implementsNameComma',
               'class A implements B,',
@@ -137,8 +134,7 @@
               'implementsNameCommaBody',
               'class A implements B, {}',
               [ParserErrorCode.EXPECTED_TYPE_NAME],
-              'class A implements B, _s_ {}',
-              allFailing: true),
+              'class A implements B, _s_ {}'),
         ],
         PartialCodeTest.declarationSuffixes);
   }
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/local_variable_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/local_variable_test.dart
index 7a54709..23eac88 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/local_variable_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/local_variable_test.dart
@@ -66,7 +66,6 @@
                 'for',
                 'labeled',
                 'localFunctionNonVoid',
-                'localFunctionVoid',
                 'return',
               ]),
           new TestDescriptor(
@@ -85,7 +84,6 @@
                 'for',
                 'labeled',
                 'localFunctionNonVoid',
-                'localFunctionVoid',
                 'return',
               ]),
           new TestDescriptor('constNameCommaName', 'const a, b',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
index cc08a8b..1d27bed 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
@@ -76,13 +76,7 @@
               CompileTimeErrorCode.CONST_NOT_INITIALIZED
             ],
             "const a, _s_;",
-            failing: [
-              'typedef',
-              'functionVoid',
-              'functionNonVoid',
-              'getter',
-              'setter'
-            ],
+            failing: ['typedef', 'functionNonVoid', 'getter', 'setter'],
             expectedErrorsInValidCode: [
               CompileTimeErrorCode.CONST_NOT_INITIALIZED,
               CompileTimeErrorCode.CONST_NOT_INITIALIZED
@@ -98,13 +92,7 @@
               CompileTimeErrorCode.CONST_NOT_INITIALIZED
             ],
             "const int a, _s_;",
-            failing: [
-              'typedef',
-              'functionVoid',
-              'functionNonVoid',
-              'getter',
-              'setter'
-            ],
+            failing: ['typedef', 'functionNonVoid', 'getter', 'setter'],
             expectedErrorsInValidCode: [
               CompileTimeErrorCode.CONST_NOT_INITIALIZED,
               CompileTimeErrorCode.CONST_NOT_INITIALIZED
diff --git a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
index 883fe5f..9386a8d 100644
--- a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
+++ b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
@@ -210,11 +210,17 @@
 ''', [PubspecWarningCode.FLUTTER_FIELD_NOT_MAP]);
   }
 
-  test_flutterFieldNotMap_error_empty() {
-    assertErrors('''
+  test_flutterField_empty_noError() {
+    assertNoErrors('''
 name: sample
 flutter:
-''', [PubspecWarningCode.FLUTTER_FIELD_NOT_MAP]);
+''');
+
+    assertNoErrors('''
+name: sample
+flutter:
+
+''');
   }
 
   test_flutterFieldNotMap_noError() {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 0b1369a..f707999 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -2526,7 +2526,7 @@
   }
 
   test_const_invalid_field_const() async {
-    variablesWithNotConstInitializers.add('f');
+    shouldCompareLibraryElements = false;
     var library = await checkLibrary(r'''
 class C {
   static const f = 1 + foo();
@@ -2545,14 +2545,16 @@
     } else if (isStrongMode) {
       checkElementText(library, r'''
 class C {
-  static const int f;
+  static const int f = 1 +
+        foo/*location: test.dart;foo*/();
 }
 int foo() {}
 ''');
     } else {
       checkElementText(library, r'''
 class C {
-  static const dynamic f;
+  static const dynamic f = 1 +
+        foo/*location: test.dart;foo*/();
 }
 int foo() {}
 ''');
@@ -2594,7 +2596,7 @@
   }
 
   test_const_invalid_topLevel() async {
-    variablesWithNotConstInitializers.add('v');
+    shouldCompareLibraryElements = false;
     var library = await checkLibrary(r'''
 const v = 1 + foo();
 int foo() => 42;
@@ -2608,12 +2610,14 @@
 ''');
     } else if (isStrongMode) {
       checkElementText(library, r'''
-const int v;
+const int v = 1 +
+        foo/*location: test.dart;foo*/();
 int foo() {}
 ''');
     } else {
       checkElementText(library, r'''
-const dynamic v;
+const dynamic v = 1 +
+        foo/*location: test.dart;foo*/();
 int foo() {}
 ''');
     }
@@ -4566,7 +4570,7 @@
   }
 
   test_constructor_initializers_field_notConst() async {
-    variablesWithNotConstInitializers.add('x');
+    shouldCompareLibraryElements = false;
     var library = await checkLibrary('''
 class C {
   final x;
@@ -4574,9 +4578,8 @@
 }
 int foo() => 42;
 ''', allowErrors: true);
-    if (isSharedFrontEnd) {
-      // It is OK to keep non-constant initializers.
-      checkElementText(library, r'''
+    // It is OK to keep non-constant initializers.
+    checkElementText(library, r'''
 class C {
   final dynamic x;
   const C() :
@@ -4585,16 +4588,6 @@
 }
 int foo() {}
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  final dynamic x;
-  const C() :
-        x/*location: test.dart;C;x*/ = <null>;
-}
-int foo() {}
-''');
-    }
   }
 
   test_constructor_initializers_field_withParameter() async {
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 0411275..37b5eca 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -6887,7 +6887,6 @@
     }
     UnlinkedVariable variable = serializeVariableText('var v = (x) => x.f();');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
-        isValidConst: false,
         operators: [
           UnlinkedExprOperation.pushParameter,
           UnlinkedExprOperation.invokeMethod
@@ -6910,7 +6909,6 @@
     UnlinkedVariable variable =
         serializeVariableText('var v = (x) => x.y.f();');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
-        isValidConst: false,
         operators: [
           UnlinkedExprOperation.pushParameter,
           UnlinkedExprOperation.extractProperty,
@@ -7135,31 +7133,26 @@
 A a = new A();
 final v = a.b.c.m(10, 20);
 ''');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.invokeMethodRef,
-        ],
-        ints: [
-          10,
-          20,
-          0,
-          2,
-          0
-        ],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'm',
-                  expectedKind: ReferenceKind.unresolved,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
-                    new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
-                    new _PrefixExpectation(
-                        ReferenceKind.topLevelPropertyAccessor, 'a')
-                  ])
-        ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+      UnlinkedExprOperation.pushInt,
+      UnlinkedExprOperation.pushInt,
+      UnlinkedExprOperation.invokeMethodRef,
+    ], ints: [
+      10,
+      20,
+      0,
+      2,
+      0
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, 'm',
+              expectedKind: ReferenceKind.unresolved,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
+                new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
+                new _PrefixExpectation(
+                    ReferenceKind.topLevelPropertyAccessor, 'a')
+              ])
+    ]);
   }
 
   test_expr_invokeMethodRef_static_importedWithPrefix() {
@@ -7175,26 +7168,21 @@
 import 'a.dart' as p;
 final v = p.C.m();
 ''');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.invokeMethodRef,
-        ],
-        ints: [
-          0,
-          0,
-          0
-        ],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'm',
-                  expectedKind: ReferenceKind.method,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                        absoluteUri: absUri('/a.dart')),
-                    new _PrefixExpectation(ReferenceKind.prefix, 'p')
-                  ])
-        ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+      UnlinkedExprOperation.invokeMethodRef,
+    ], ints: [
+      0,
+      0,
+      0
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, 'm',
+              expectedKind: ReferenceKind.method,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
+                    absoluteUri: absUri('/a.dart')),
+                new _PrefixExpectation(ReferenceKind.prefix, 'p')
+              ])
+    ]);
   }
 
   test_expr_invokeMethodRef_with_reference_arg() {
@@ -7206,23 +7194,19 @@
 final u = null;
 final v = f(u);
 ''');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.invokeMethodRef
-        ],
-        ints: [
-          0,
-          1,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'u',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'f',
-              expectedKind: ReferenceKind.topLevelFunction)
-        ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+      UnlinkedExprOperation.pushReference,
+      UnlinkedExprOperation.invokeMethodRef
+    ], ints: [
+      0,
+      1,
+      0
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, 'u',
+          expectedKind: ReferenceKind.topLevelPropertyAccessor),
+      (EntityRef r) => checkTypeRef(r, null, 'f',
+          expectedKind: ReferenceKind.topLevelFunction)
+    ]);
   }
 
   test_expr_invokeMethodRef_withTypeParameters() {
@@ -7233,23 +7217,18 @@
 f<T, U>() => null;
 final v = f<int, String>();
 ''');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.invokeMethodRef
-        ],
-        ints: [
-          0,
-          0,
-          2
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'f',
-              expectedKind: ReferenceKind.topLevelFunction,
-              numTypeParameters: 2),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int'),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'String')
-        ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+      UnlinkedExprOperation.invokeMethodRef
+    ], ints: [
+      0,
+      0,
+      2
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, 'f',
+          expectedKind: ReferenceKind.topLevelFunction, numTypeParameters: 2),
+      (EntityRef r) => checkTypeRef(r, 'dart:core', 'int'),
+      (EntityRef r) => checkTypeRef(r, 'dart:core', 'String')
+    ]);
   }
 
   test_expr_makeTypedList() {
@@ -7462,27 +7441,22 @@
   static int m() => 42;
 }''').fields[0];
     expect(variable.isFinal, isTrue);
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.invokeMethodRef,
-          UnlinkedExprOperation.add,
-        ],
-        ints: [
-          1,
-          0,
-          0,
-          0
-        ],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'm',
-                  expectedKind: ReferenceKind.method,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-                  ])
-        ]);
+    assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+      UnlinkedExprOperation.pushInt,
+      UnlinkedExprOperation.invokeMethodRef,
+      UnlinkedExprOperation.add,
+    ], ints: [
+      1,
+      0,
+      0,
+      0
+    ], strings: [], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, 'm',
+              expectedKind: ReferenceKind.method,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+              ])
+    ]);
   }
 
   test_field_final_typeParameter() {
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index a901ed4..5136abf 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -153,9 +153,6 @@
   /// Whether to treat lints as fatal
   final bool lintsAreFatal;
 
-  /// Whether to use memory byte store for analysis driver.
-  final bool useAnalysisDriverMemoryByteStore;
-
   /// Emit output in a verbose mode.
   final bool verbose;
 
@@ -207,8 +204,6 @@
         strongMode = args['strong'],
         implicitCasts = args[implicitCastsFlag],
         implicitDynamic = !args['no-implicit-dynamic'],
-        useAnalysisDriverMemoryByteStore =
-            args['use-analysis-driver-memory-byte-store'],
         verbose = args['verbose'],
         color = args['color'];
 
@@ -384,12 +379,12 @@
           negatable: false,
           hide: hide)
       ..addOption('build-analysis-output',
-          help:
-              'Specifies the path to the file where analysis results should be written.',
+          help: 'Specifies the path to the file where analysis results should '
+              'be written.',
           hide: hide)
       ..addFlag('build-mode',
-          // TODO(paulberry): add more documentation.
-          help: 'Enable build mode.',
+          help: 'Run in build mode; '
+              'this is used to generate analyzer summaries for build systems.',
           defaultsTo: false,
           negatable: false,
           hide: hide)
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 3b253de..693f8fd 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -16,6 +16,7 @@
 import 'constants/values.dart';
 import 'common_elements.dart' show CommonElements;
 import 'elements/elements.dart';
+import 'elements/types.dart' show DartTypes;
 import 'elements/modelx.dart' show ConstantVariableMixin;
 import 'elements/operators.dart';
 import 'elements/resolution_types.dart';
@@ -1460,13 +1461,16 @@
   CommonElements get commonElements => _compiler.resolution.commonElements;
 
   @override
+  DartTypes get types => _compiler.resolution.types;
+
+  @override
   String readFromEnvironment(String name) {
     return _compiler.fromEnvironment(name);
   }
 
   @override
   ResolutionInterfaceType substByContext(
-      ResolutionInterfaceType base, ResolutionInterfaceType target) {
+      ResolutionDartType base, ResolutionInterfaceType target) {
     return base.substByContext(target);
   }
 
diff --git a/pkg/compiler/lib/src/constants/evaluation.dart b/pkg/compiler/lib/src/constants/evaluation.dart
index cdb11cc..7a20827 100644
--- a/pkg/compiler/lib/src/constants/evaluation.dart
+++ b/pkg/compiler/lib/src/constants/evaluation.dart
@@ -18,6 +18,11 @@
 abstract class EvaluationEnvironment {
   CommonElements get commonElements;
 
+  DartTypes get types;
+
+  /// Type in the enclosing constructed
+  InterfaceType get enclosingConstructedType;
+
   /// Read environments string passed in using the '-Dname=value' option.
   String readFromEnvironment(String name);
 
@@ -35,7 +40,7 @@
   /// Performs the substitution of the type arguments of [target] for their
   /// corresponding type variables in [type].
   InterfaceType substByContext(
-      covariant InterfaceType base, covariant InterfaceType target);
+      covariant DartType base, covariant InterfaceType target);
 
   void reportWarning(
       ConstantExpression expression, MessageKind kind, Map arguments);
@@ -43,8 +48,8 @@
   void reportError(
       ConstantExpression expression, MessageKind kind, Map arguments);
 
-  ConstantValue evaluateConstructor(
-      ConstructorEntity constructor, ConstantValue evaluate());
+  ConstantValue evaluateConstructor(ConstructorEntity constructor,
+      InterfaceType type, ConstantValue evaluate());
 
   ConstantValue evaluateField(FieldEntity field, ConstantValue evaluate());
 
@@ -54,6 +59,7 @@
 
 abstract class EvaluationEnvironmentBase implements EvaluationEnvironment {
   Link<Spannable> _spannableStack = const Link<Spannable>();
+  InterfaceType enclosingConstructedType;
   final Set<FieldEntity> _currentlyEvaluatedFields = new Set<FieldEntity>();
   final bool constantRequired;
 
@@ -94,10 +100,13 @@
   }
 
   @override
-  ConstantValue evaluateConstructor(
-      ConstructorEntity constructor, ConstantValue evaluate()) {
+  ConstantValue evaluateConstructor(ConstructorEntity constructor,
+      InterfaceType type, ConstantValue evaluate()) {
     _spannableStack = _spannableStack.prepend(constructor);
+    var old = enclosingConstructedType;
+    enclosingConstructedType = type;
     ConstantValue result = evaluate();
+    enclosingConstructedType = old;
     _spannableStack = _spannableStack.tail;
     return result;
   }
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index a28c018..2a6813c 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -16,6 +16,7 @@
 import 'values.dart';
 
 enum ConstantExpressionKind {
+  AS,
   BINARY,
   BOOL,
   BOOL_FROM_ENVIRONMENT,
@@ -580,7 +581,8 @@
   @override
   ConstantValue evaluate(
       EvaluationEnvironment environment, ConstantSystem constantSystem) {
-    return environment.evaluateConstructor(target, () {
+    InterfaceType instanceType = computeInstanceType(environment);
+    return environment.evaluateConstructor(target, instanceType, () {
       InstanceData instanceData = computeInstanceData(environment);
       if (instanceData == null) {
         return new NonConstantValue();
@@ -607,8 +609,7 @@
         }
       }
       if (isValidAsConstant) {
-        return new ConstructedConstantValue(
-            computeInstanceType(environment), fieldValues);
+        return new ConstructedConstantValue(instanceType, fieldValues);
       } else {
         return new NonConstantValue();
       }
@@ -822,6 +823,67 @@
       commonElements.typeType;
 }
 
+/// Cast expressions: these may be from either explicit or implicit `as`
+/// checks.
+class AsConstantExpression extends ConstantExpression {
+  final ConstantExpression expression;
+  final DartType type;
+
+  AsConstantExpression(this.expression, this.type);
+
+  ConstantExpressionKind get kind => ConstantExpressionKind.AS;
+
+  accept(ConstantExpressionVisitor visitor, [context]) {
+    return visitor.visitAs(this, context);
+  }
+
+  @override
+  void _createStructuredText(StringBuffer sb) {
+    sb.write('As(value=');
+    expression._createStructuredText(sb);
+    sb.write(',type=$type)');
+  }
+
+  @override
+  ConstantValue evaluate(
+      EvaluationEnvironment environment, ConstantSystem constantSystem) {
+    ConstantValue expressionValue =
+        expression.evaluate(environment, constantSystem);
+    DartType expressionType =
+        expressionValue.getType(environment.commonElements);
+    DartType enclosingType = environment.enclosingConstructedType;
+    DartType superType = enclosingType != null
+        ? environment.substByContext(type, enclosingType)
+        : type;
+    if (!constantSystem.isSubtype(
+        environment.types, expressionType, superType)) {
+      // TODO(sigmund): consider reporting different messages and error
+      // locations for implicit vs explicit casts.
+      environment.reportError(expression, MessageKind.INVALID_CONSTANT_CAST,
+          {'constant': expression, 'type': expressionType, 'castType': type});
+      return new NonConstantValue();
+    }
+    return expressionValue;
+  }
+
+  @override
+  ConstantExpression apply(NormalizedArguments arguments) {
+    return new AsConstantExpression(expression.apply(arguments), type);
+  }
+
+  @override
+  int _computeHashCode() => 13 * type.hashCode + 17 * expression.hashCode;
+
+  @override
+  bool _equals(AsConstantExpression other) {
+    return expression == other.expression && type == other.type;
+  }
+
+  @override
+  InterfaceType getKnownType(CommonElements commonElements) =>
+      expression.getKnownType(commonElements);
+}
+
 /// Reference to a constant top-level or static field.
 class FieldConstantExpression extends ConstantExpression {
   final FieldEntity element;
@@ -2060,6 +2122,7 @@
     return constant.accept(this, context);
   }
 
+  R visitAs(AsConstantExpression exp, A context);
   R visitBool(BoolConstantExpression exp, A context);
   R visitInt(IntConstantExpression exp, A context);
   R visitDouble(DoubleConstantExpression exp, A context);
@@ -2127,6 +2190,13 @@
   }
 
   @override
+  void visitAs(AsConstantExpression exp, [_]) {
+    visit(exp.expression);
+    sb.write(' as ');
+    sb.write(exp.type);
+  }
+
+  @override
   void visitBool(BoolConstantExpression exp, [_]) {
     sb.write(exp.boolValue);
   }
diff --git a/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart b/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
index 7f640b3..467a5bf 100644
--- a/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
@@ -77,11 +77,7 @@
   MessageKind.MISSING_EXPRESSION_IN_THROW: const MessageTemplate(
       MessageKind.MISSING_EXPRESSION_IN_THROW,
       "Missing expression after 'throw'.",
-      howToFix: "Did you mean 'rethrow'?",
-      examples: const [
-        "main() { throw; }",
-        "main() { try { throw 0; } catch(e) { throw; } }",
-      ]), // Generated. Don't edit.
+      howToFix: "Did you mean 'rethrow'?"), // Generated. Don't edit.
   MessageKind.RETHROW_OUTSIDE_CATCH: const MessageTemplate(
       MessageKind.RETHROW_OUTSIDE_CATCH,
       "Rethrow must be inside of catch clause.",
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 51ffa6b..0bd3e70 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -207,6 +207,7 @@
   INVALID_BOOL_FROM_ENVIRONMENT_DEFAULT_VALUE_TYPE,
   INVALID_BREAK,
   INVALID_CASE_DEFAULT,
+  INVALID_CONSTANT_CAST,
   INVALID_CONSTANT_ADD_TYPES,
   INVALID_CONSTANT_BINARY_INT_TYPE,
   INVALID_CONSTANT_BINARY_NUM_TYPE,
@@ -3506,6 +3507,10 @@
           "constant binary + expression on 'num'. Must be a value of type "
           "'int' or 'double'."),
 
+      MessageKind.INVALID_CONSTANT_CAST: const MessageTemplate(
+          MessageKind.INVALID_CONSTANT_CAST,
+          "`#{constant}` of type '#{type}' is not a subtype of #{castType}."),
+
       MessageKind.INVALID_CONSTANT_ADD_TYPES: const MessageTemplate(
           MessageKind.INVALID_CONSTANT_ADD_TYPES,
           "`#{leftConstant}` of type '#{leftType}' and "
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index bc3d0c0..afceb3d 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -532,11 +532,7 @@
     }
   }
 
-  int sizeOfNode(jsAst.Node node) {
-    // TODO(sigmund): switch back to null aware operators (issue #24136)
-    var size = _nodeToSize[node];
-    return size == null ? 0 : size;
-  }
+  int sizeOfNode(jsAst.Node node) => _nodeToSize[node] ?? 0;
 
   String codeOf(Entity entity) {
     List<jsAst.Node> code = _entityToNodes[entity];
@@ -629,6 +625,10 @@
             new Duration(milliseconds: stopwatch.elapsedMilliseconds),
         dumpInfoDuration: new Duration(milliseconds: this.timing),
         noSuchMethodEnabled: closedWorld.backendUsage.isNoSuchMethodUsed,
+        isRuntimeTypeUsed: closedWorld.backendUsage.isRuntimeTypeUsed,
+        isIsolateInUse: closedWorld.backendUsage.isIsolateInUse,
+        isFunctionApplyUsed: closedWorld.backendUsage.isFunctionApplyUsed,
+        isMirrorsUsed: closedWorld.backendUsage.isMirrorsUsed,
         minified: compiler.options.enableMinification);
 
     ChunkedConversionSink<Object> sink = encoder.startChunkedConversion(
diff --git a/pkg/compiler/lib/src/io/source_file.dart b/pkg/compiler/lib/src/io/source_file.dart
index ff47c16..494111d 100644
--- a/pkg/compiler/lib/src/io/source_file.dart
+++ b/pkg/compiler/lib/src/io/source_file.dart
@@ -9,6 +9,7 @@
 import 'dart:typed_data' show Uint8List;
 
 import 'package:kernel/ast.dart' as kernel show Location, Source;
+
 import 'location_provider.dart' show LocationProvider;
 import '../../compiler_new.dart';
 
@@ -102,10 +103,6 @@
     if (colorize == null) {
       colorize = (text) => text;
     }
-    if (end > length) {
-      start = length - 1;
-      end = length;
-    }
 
     kernel.Location startLocation = kernelSource.getLocation(null, start);
     kernel.Location endLocation = kernelSource.getLocation(null, end);
@@ -142,9 +139,15 @@
         for (int line = lineStart; line <= lineEnd; line++) {
           String textLine = kernelSource.getTextLine(line + 1);
           if (line == lineStart) {
+            if (columnStart > textLine.length) {
+              columnStart = textLine.length;
+            }
             buf.write(textLine.substring(0, columnStart));
             buf.writeln(colorize(textLine.substring(columnStart)));
           } else if (line == lineEnd) {
+            if (columnEnd > textLine.length) {
+              columnEnd = textLine.length;
+            }
             buf.write(colorize(textLine.substring(0, columnEnd)));
             buf.writeln(textLine.substring(columnEnd));
           } else {
diff --git a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
index 0ac5234..14177b0 100644
--- a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
@@ -392,6 +392,9 @@
       for (int i = 0; i < selector.argumentCount; i++) {
         parameterNames.add('a$i');
       }
+      for (int i = 1; i <= selector.typeArgumentCount; i++) {
+        parameterNames.add('\$T$i');
+      }
     }
 
     jsAst.Name invocationName = _namer.invocationName(selector);
diff --git a/pkg/compiler/lib/src/js_model/closure_visitors.dart b/pkg/compiler/lib/src/js_model/closure_visitors.dart
index 4650e6b..28bd0f1 100644
--- a/pkg/compiler/lib/src/js_model/closure_visitors.dart
+++ b/pkg/compiler/lib/src/js_model/closure_visitors.dart
@@ -68,6 +68,11 @@
   /// have unique names.
   int _boxCounter = 0;
 
+  /// Set to `true` in the visitor if a type annotation is always needed.
+  ///
+  /// This is for instance the case for expressions like `o is T` and `o as T`.
+  bool _contextNeedsType = false;
+
   CapturedScopeBuilder(this._model, this._options, {bool hasThisLocal})
       : this._hasThisLocal = hasThisLocal;
 
@@ -414,6 +419,9 @@
       _capturedVariables.add(freeVariable);
       _markVariableAsUsed(freeVariable);
     }
+    for (ir.Node freeVariableForRti in savedScopeInfo.freeVariablesForRti) {
+      _markVariableAsUsed(freeVariableForRti, onlyForRtiChecks: true);
+    }
     if (_isInsideClosure && savedScopeInfo.thisUsedAsFreeVariable) {
       _currentScopeInfo.thisUsedAsFreeVariable = true;
     }
@@ -464,14 +472,32 @@
 
   @override
   visitTypeParameterType(ir.TypeParameterType type) {
-    _analyzeTypeVariable(type);
+    _analyzeTypeVariable(type, onlyIfNeedsRti: !_contextNeedsType);
   }
 
   @override
   visitTypeLiteral(ir.TypeLiteral node) {
-    if (node.type is ir.TypeParameterType) {
-      _analyzeTypeVariable(node.type, onlyIfNeedsRti: false);
-    }
+    bool oldContextNeedsType = _contextNeedsType;
+    _contextNeedsType = true;
+    node.visitChildren(this);
+    _contextNeedsType = oldContextNeedsType;
+  }
+
+  @override
+  visitIsExpression(ir.IsExpression node) {
+    bool oldContextNeedsType = _contextNeedsType;
+    _contextNeedsType = true;
+    node.visitChildren(this);
+    _contextNeedsType = oldContextNeedsType;
+  }
+
+  @override
+  visitAsExpression(ir.AsExpression node) {
+    bool oldContextNeedsType = _contextNeedsType;
+    _contextNeedsType =
+        !node.isTypeError || _options.implicitDowncastCheckPolicy.isEmitted;
+    node.visitChildren(this);
+    _contextNeedsType = oldContextNeedsType;
   }
 
   /// Returns true if the node is a field, or a constructor (factory or
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 63c2d8f..15e1ad0 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -1814,7 +1814,10 @@
   CommonElements get commonElements => _elementMap.commonElements;
 
   @override
-  InterfaceType substByContext(InterfaceType base, InterfaceType target) {
+  DartTypes get types => _elementMap.types;
+
+  @override
+  InterfaceType substByContext(DartType base, InterfaceType target) {
     return _elementMap._substByContext(base, target);
   }
 
diff --git a/pkg/compiler/lib/src/kernel/element_map_mixins.dart b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
index 8cdbb9c..8d08535 100644
--- a/pkg/compiler/lib/src/kernel/element_map_mixins.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
@@ -690,6 +690,21 @@
   }
 
   @override
+  ConstantExpression visitAsExpression(ir.AsExpression node) {
+    ConstantExpression expression = visit(node.operand);
+    if (expression == null) return null;
+    DartType type = elementMap.getDartType(node.type);
+    return new AsConstantExpression(expression, type);
+  }
+
+  @override
+  ConstantExpression visitInstantiation(ir.Instantiation node) {
+    // TODO(sigmund, sra): add a constant representation for instantiations.
+    // See issue 32774.
+    return visit(node.expression);
+  }
+
+  @override
   ConstantExpression visitNot(ir.Not node) {
     ConstantExpression expression = visit(node.operand);
     if (expression == null) return null;
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 37d3e65..90077cb 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -317,6 +317,21 @@
 
     void addProcedures(ir.Class c, {bool includeStatic}) {
       for (ir.Procedure member in c.procedures) {
+        if (member.isForwardingStub && member.isAbstract) {
+          // Skip abstract forwarding stubs. These are never emitted but they
+          // might shadow the inclusion of a mixed in method in code like:
+          //
+          //     class Super {}
+          //     class Mixin<T> {
+          //       void method(T t) {}
+          //     }
+          //     class Class extends Super with Mixin<int> {}
+          //     main() => new Class().method();
+          //
+          // Here a stub is created for `Super&Mixin.method` hiding that
+          // `Mixin.method` is inherited by `Class`.
+          continue;
+        }
         if (!includeStatic && member.isStatic) continue;
         var name = member.name.name;
         assert(!name.contains('#'));
diff --git a/pkg/compiler/lib/src/kernel/front_end_adapter.dart b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
index 2dd227a..9a4097f 100644
--- a/pkg/compiler/lib/src/kernel/front_end_adapter.dart
+++ b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
@@ -83,7 +83,7 @@
   Spannable span;
   if (message.span != null) {
     span = new SourceSpan(message.span.start.sourceUrl,
-        message.span.start.offset, message.span.start.offset + 1);
+        message.span.start.offset, message.span.end.offset);
   } else {
     span = NO_LOCATION_SPANNABLE;
   }
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 1f1d3c3..607e8e6 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -392,9 +392,9 @@
     librariesSpecificationUri = _resolveLibrariesSpecification(libraryRoot);
 
     if (strongMode) {
-      // Strong mode represents implicit downcasts explicitly, so assignments
-      // checks provide no additional value.
-      assignmentCheckPolicy = CheckPolicy.ignored;
+      // Strong mode always trusts type annotations (inferred or explicit), so
+      // assignments checks should be trusted.
+      assignmentCheckPolicy = CheckPolicy.trusted;
       if (omitImplicitChecks) {
         parameterCheckPolicy = CheckPolicy.trusted;
         implicitDowncastCheckPolicy = CheckPolicy.trusted;
diff --git a/pkg/compiler/lib/src/serialization/constant_serialization.dart b/pkg/compiler/lib/src/serialization/constant_serialization.dart
index bc0a163..46fade8 100644
--- a/pkg/compiler/lib/src/serialization/constant_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/constant_serialization.dart
@@ -198,6 +198,11 @@
   void visitAssert(AssertConstantExpression exp, ObjectEncoder context) {
     throw new UnsupportedError("AssertConstantExpression is not supported.");
   }
+
+  @override
+  void visitAs(AsConstantExpression exp, ObjectEncoder encoder) {
+    throw new UnsupportedError("AsConstantExpression is not supported.");
+  }
 }
 
 /// Utility class for deserializing [ConstantExpression]s.
@@ -305,6 +310,7 @@
             decoder.getElement(Key.IMPORT) as ImportElement);
       case ConstantExpressionKind.SYNTHETIC:
       case ConstantExpressionKind.ASSERT:
+      case ConstantExpressionKind.AS:
     }
     throw new UnsupportedError("Unexpected constant kind: ${kind} in $decoder");
   }
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index 65f12d5..486c774 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -746,6 +746,13 @@
   }
 
   @override
+  bool visitAs(AsConstantExpression exp1, covariant AsConstantExpression exp2) {
+    return strategy.test(
+            exp1, exp2, 'expression', exp1.expression, exp2.expression) &&
+        strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type);
+  }
+
+  @override
   bool visitBinary(
       BinaryConstantExpression exp1, covariant BinaryConstantExpression exp2) {
     return strategy.test(
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index eb334b9..0992bb1 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -98,7 +98,6 @@
       HInstruction original, DartType type,
       {int kind: HTypeConversion.CHECKED_MODE_CHECK}) {
     if (type == null) return original;
-    if (builder.options.strongMode) return original;
     HInstruction checkedOrTrusted = original;
     if (builder.options.assignmentCheckPolicy.isTrusted) {
       checkedOrTrusted = _trustType(original, type);
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 3fea8fd..0831c6e 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -55,7 +55,7 @@
         // the phi thinks it has because new optimizations may imply
         // changing it.
         // In theory we would need to mark
-        // the type of all other incoming edges as "unitialized" and take this
+        // the type of all other incoming edges as "uninitialized" and take this
         // into account when doing the propagation inside the phis. Just
         // setting the propagated type is however easier.
         phi.instructionType = phi.inputs[0].instructionType;
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index b36729d..01f27b2 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -242,6 +242,19 @@
         : const EmptyFunctionSetQuery();
     return result;
   }
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('FunctionSetNode(');
+    String comma = '';
+    cache.forEach((mask, query) {
+      sb.write(comma);
+      sb.write('$mask=$query');
+      comma = ',';
+    });
+    sb.write(')');
+    return sb.toString();
+  }
 }
 
 /// A set of functions that are the potential targets of all call sites sharing
@@ -265,6 +278,8 @@
 
   @override
   Iterable<MemberEntity> get functions => const <MemberEntity>[];
+
+  String toString() => '<empty>';
 }
 
 class FullFunctionSetQuery implements FunctionSetQuery {
@@ -296,4 +311,6 @@
         }),
         closedWorld);
   }
+
+  String toString() => '$_mask:$functions';
 }
diff --git a/pkg/compiler/testing.json b/pkg/compiler/testing.json
index 9a4b50d..e2ef599 100644
--- a/pkg/compiler/testing.json
+++ b/pkg/compiler/testing.json
@@ -14,8 +14,8 @@
     ],
 
     "exclude": [
-      "^tests/compiler/dart2js/data/.*",
       "^tests/compiler/dart2js/inference/data/super_invoke\\.dart",
+      "^tests/compiler/dart2js/old_frontend/data/.*",
       "^tests/compiler/dart2js/path with spaces/.*"
     ]
   }
diff --git a/pkg/compiler/testing_dart.json b/pkg/compiler/testing_dart.json
index 4ebf407..aa78e3e 100644
--- a/pkg/compiler/testing_dart.json
+++ b/pkg/compiler/testing_dart.json
@@ -16,7 +16,6 @@
     "exclude": [
       "^tests/compiler/dart2js/codegen_helper\\.dart",
       "^tests/compiler/dart2js/codegen/type_inference8_test\\.dart",
-      "^tests/compiler/dart2js/data/one_line_dart_program\\.dart",
       "^tests/compiler/dart2js/deferred/inline_restrictions_test\\.dart",
       "^tests/compiler/dart2js/deferred/load_graph_segmentation2_test\\.dart",
       "^tests/compiler/dart2js/deferred/load_graph_segmentation_test\\.dart",
@@ -48,9 +47,10 @@
       "^tests/compiler/dart2js/needs_no_such_method_test\\.dart",
       "^tests/compiler/dart2js/no_such_method_enabled_test\\.dart",
       "^tests/compiler/dart2js/output_collector\\.dart",
-      "^tests/compiler/dart2js/old_frontend/patch_test\\.dart",
+      "^tests/compiler/dart2js/old_frontend/data/one_line_dart_program\\.dart",
       "^tests/compiler/dart2js/old_frontend/message_kind_helper\\.dart",
       "^tests/compiler/dart2js/old_frontend/metadata_test\\.dart",
+      "^tests/compiler/dart2js/old_frontend/patch_test\\.dart",
       "^tests/compiler/dart2js/old_frontend/reexport_handled_test\\.dart",
       "^tests/compiler/dart2js/old_frontend/resolution_test\\.dart",
       "^tests/compiler/dart2js/quarantined/http_launch_data/http_launch_main_package\\.dart",
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 122b9ce..508e4b1 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -39,6 +39,7 @@
 import '../compiler/js_names.dart' as JS;
 import '../compiler/js_utils.dart' as JS;
 import '../compiler/module_builder.dart' show pathToJSIdentifier;
+import '../compiler/shared_compiler.dart';
 import '../compiler/type_utilities.dart';
 import '../js_ast/js_ast.dart' as JS;
 import '../js_ast/js_ast.dart' show js;
@@ -71,7 +72,11 @@
 // expressions (which result in JS.Expression) and statements
 // (which result in (JS.Statement).
 class CodeGenerator extends Object
-    with ClosureAnnotator, JSTypeRefCodegen, NullableTypeInference
+    with
+        ClosureAnnotator,
+        JSTypeRefCodegen,
+        NullableTypeInference,
+        SharedCompiler
     implements AstVisitor<JS.Node> {
   final AnalysisContext context;
   final SummaryDataStore summaryData;
@@ -254,6 +259,8 @@
 
   LibraryElement get currentLibrary => _currentElement.library;
 
+  Uri get currentLibraryUri => _currentElement.librarySource.uri;
+
   CompilationUnitElement get _currentCompilationUnit {
     for (var e = _currentElement;; e = e.enclosingElement) {
       if (e is CompilationUnitElement) return e;
@@ -2803,32 +2810,17 @@
     var typeFormals = _emitTypeFormals(type.typeFormals);
     if (_reifyGeneric(element)) formals.insertAll(0, typeFormals);
 
+    super.enterFunction(element.name, formals,
+        () => isPotentiallyMutated(body, parameters.parameters.last.element));
+
     JS.Block code = isSync
         ? _emitFunctionBody(element, parameters, body)
         : new JS.Block([
             _emitGeneratorFunction(element, parameters, body).toReturn()
               ..sourceInformation = _nodeStart(body)
           ]);
-    if (element.isOperator && formals.isNotEmpty) {
-      if (element.name == '[]=') {
-        // []= methods need to return the value. We could also address this at
-        // call sites, but it's cleaner to instead transform the operator method.
-        code = JS.alwaysReturnLastParameter(code, formals.last);
-      } else if (element.name == '==' && !element.source.isInSystemLibrary) {
-        // In Dart `operator ==` methods are not called with a null argument.
-        // This is handled before calling them. For performance reasons, we push
-        // this check inside the method, to simplify our `equals` helper.
-        //
-        // TODO(jmesserly): in most cases this check is not necessary, because
-        // the Dart code already handles it (typically by an `is` check).
-        // Eliminate it when possible.
-        code = new JS.Block([
-          js.statement('if (# == null) return false;', [formals.first]),
-          code
-        ]);
-      }
-    }
 
+    code = super.exitFunction(element.name, formals, code);
     return new JS.Fun(formals, code,
         typeParams: typeFormals, returnType: emitTypeRef(type.returnType));
   }
@@ -4163,9 +4155,7 @@
 
   @override
   JS.Statement visitReturnStatement(ReturnStatement node) {
-    var e = node.expression;
-    if (e == null) return new JS.Return();
-    return _visitExpression(e).toReturn();
+    return super.emitReturnStatement(_visitExpression(node.expression));
   }
 
   @override
diff --git a/pkg/dev_compiler/lib/src/compiler/js_utils.dart b/pkg/dev_compiler/lib/src/compiler/js_utils.dart
index 1710810..ff3296b 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_utils.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_utils.dart
@@ -26,22 +26,6 @@
   return fn;
 }
 
-/// Transform the function so the last parameter is always returned.
-///
-/// This is useful for indexed set methods, which otherwise would not have
-/// the right return value in JS.
-Block alwaysReturnLastParameter(Block body, Parameter lastParam) {
-  Statement blockBody = body;
-  if (Return.foundIn(body)) {
-    // If a return is inside body, transform `(params) { body }` to
-    // `(params) { (() => { body })(); return value; }`.
-    // TODO(jmesserly): we could instead generate the return differently,
-    // and avoid the immediately invoked function.
-    blockBody = new Call(new ArrowFun([], body), []).toStatement();
-  }
-  return new Block([blockBody, new Return(lastParam)]);
-}
-
 Set<Identifier> findMutatedVariables(Node scope) {
   var v = new MutationVisitor();
   scope.accept(v);
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
new file mode 100644
index 0000000..165028a
--- /dev/null
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2018, 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 '../compiler/js_metalet.dart' as JS;
+import '../compiler/js_names.dart' as JS;
+import '../compiler/js_utils.dart' as JS;
+import '../js_ast/js_ast.dart' as JS;
+import '../js_ast/js_ast.dart' show js;
+
+/// Shared code between Analyzer and Kernel backends.
+///
+/// This class should only implement functionality that depends purely on JS
+/// classes, rather than on Analyzer/Kernel types.
+abstract class SharedCompiler {
+  /// When inside a `[]=` operator, this will be a non-null value that should be
+  /// returned by any `return;` statement.
+  ///
+  /// This lets DDC use the setter method's return value directly.
+  final List<JS.Identifier> _operatorSetResultStack = [];
+
+  /// When compiling the body of a `operator []=` method, this will be non-null
+  /// and will indicate the the value that should be returned from any `return;`
+  /// statements.
+  JS.Identifier get _operatorSetResult {
+    var stack = _operatorSetResultStack;
+    return stack.isEmpty ? null : stack.last;
+  }
+
+  /// The import URI of current library.
+  Uri get currentLibraryUri;
+
+  void enterFunction(String name, List<JS.Parameter> formals,
+      bool Function() isLastParamMutated) {
+    if (name == '[]=') {
+      _operatorSetResultStack.add(isLastParamMutated()
+          ? new JS.TemporaryId((formals.last as JS.Identifier).name)
+          : formals.last);
+    } else {
+      _operatorSetResultStack.add(null);
+    }
+  }
+
+  JS.Block exitFunction(
+      String name, List<JS.Parameter> formals, JS.Block code) {
+    if (name == "==" &&
+        formals.isNotEmpty &&
+        currentLibraryUri.scheme != 'dart') {
+      // In Dart `operator ==` methods are not called with a null argument.
+      // This is handled before calling them. For performance reasons, we push
+      // this check inside the method, to simplify our `equals` helper.
+      //
+      // TODO(jmesserly): in most cases this check is not necessary, because
+      // the Dart code already handles it (typically by an `is` check).
+      // Eliminate it when possible.
+      code = js
+          .block('{ if (# == null) return false; #; }', [formals.first, code]);
+    }
+    var setOperatorResult = _operatorSetResultStack.removeLast();
+    if (setOperatorResult != null) {
+      // []= methods need to return the value. We could also address this at
+      // call sites, but it's less code size to handle inside the operator.
+      var valueParam = formals.last;
+      var statements = code.statements;
+      if (statements.isEmpty || !statements.last.alwaysReturns) {
+        statements.add(new JS.Return(setOperatorResult));
+      }
+      if (!identical(setOperatorResult, valueParam)) {
+        // If the value parameter was mutated, then we use a temporary
+        // variable to track the initial value
+        formals.last = setOperatorResult;
+        code = js
+            .block('{ let # = #; #; }', [valueParam, setOperatorResult, code]);
+      }
+    }
+    return code;
+  }
+
+  /// Emits a return statement `return <value>;`, handling special rules for
+  /// the `operator []=` method.
+  JS.Statement emitReturnStatement(JS.Expression value) {
+    if (_operatorSetResult != null) {
+      var result = new JS.Return(_operatorSetResult);
+      return value != null
+          ? new JS.Block([value.toStatement(), result])
+          : result;
+    }
+    return value != null ? value.toReturn() : new JS.Return();
+  }
+}
diff --git a/pkg/dev_compiler/lib/src/js_ast/nodes.dart b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
index 5d37dac..2f7f188 100644
--- a/pkg/dev_compiler/lib/src/js_ast/nodes.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
@@ -331,6 +331,12 @@
   /// JavaScript syntax error due to a redeclared identifier.
   bool shadows(Set<String> names) => false;
 
+  /// Whether this statement would always `return` if used as a funtion body.
+  ///
+  /// This is only well defined on the outermost block; it cannot be used for a
+  /// block inside of a loop (because of `break` and `continue`).
+  bool get alwaysReturns => false;
+
   /// If this statement [shadows] any name from [names], this will wrap it in a
   /// new scoped [Block].
   Statement toScopedBlock(Set<String> names) {
@@ -357,6 +363,10 @@
         isScope = false;
 
   @override
+  bool get alwaysReturns =>
+      statements.isNotEmpty && statements.last.alwaysReturns;
+
+  @override
   Block toBlock() => this;
 
   @override
@@ -413,6 +423,10 @@
   If(this.condition, this.then, this.otherwise);
   If.noElse(this.condition, this.then) : this.otherwise = null;
 
+  @override
+  bool get alwaysReturns =>
+      hasElse && then.alwaysReturns && otherwise.alwaysReturns;
+
   bool get hasElse => otherwise != null;
 
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitIf(this);
@@ -545,6 +559,9 @@
 
   Return([this.value = null]);
 
+  @override
+  bool get alwaysReturns => true;
+
   Statement toReturn() => this;
 
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitReturn(this);
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 87a5058..8e64b1d 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -16,6 +16,7 @@
 import '../compiler/js_names.dart' as JS;
 import '../compiler/js_utils.dart' as JS;
 import '../compiler/module_builder.dart' show pathToJSIdentifier;
+import '../compiler/shared_compiler.dart';
 import '../js_ast/js_ast.dart' as JS;
 import '../js_ast/js_ast.dart' show js;
 import '../js_ast/source_map_printer.dart' show NodeEnd, NodeSpan, HoverComment;
@@ -27,7 +28,8 @@
 import 'property_model.dart';
 import 'type_table.dart';
 
-class ProgramCompiler
+class ProgramCompiler extends Object
+    with SharedCompiler
     implements
         StatementVisitor<JS.Statement>,
         ExpressionVisitor<JS.Expression>,
@@ -248,6 +250,8 @@
 
   ClassHierarchy get hierarchy => types.hierarchy;
 
+  Uri get currentLibraryUri => _currentLibrary.importUri;
+
   JS.Program emitProgram(
       Component p, List<Component> summaries, List<Uri> summaryUris) {
     if (_moduleItems.isNotEmpty) {
@@ -2752,6 +2756,10 @@
     var typeFormals = _emitTypeFormals(f.typeParameters);
     formals.insertAll(0, typeFormals);
 
+    // TODO(jmesserly): need a way of determining if parameters are
+    // potentially mutated in Kernel. For now we assume all parameters are.
+    super.enterFunction(name, formals, () => true);
+
     JS.Block code = isSync
         ? _emitFunctionBody(f)
         : new JS.Block([
@@ -2759,25 +2767,7 @@
               ..sourceInformation = _nodeStart(f)
           ]);
 
-    if (name != null && formals.isNotEmpty) {
-      if (name == '[]=') {
-        // []= methods need to return the value. We could also address this at
-        // call sites, but it's cleaner to instead transform the operator method.
-        code = JS.alwaysReturnLastParameter(code, formals.last);
-      } else if (name == '==' && _currentLibrary.importUri.scheme != 'dart') {
-        // In Dart `operator ==` methods are not called with a null argument.
-        // This is handled before calling them. For performance reasons, we push
-        // this check inside the method, to simplify our `equals` helper.
-        //
-        // TODO(jmesserly): in most cases this check is not necessary, because
-        // the Dart code already handles it (typically by an `is` check).
-        // Eliminate it when possible.
-        code = new JS.Block([
-          js.statement('if (# == null) return false;', [formals.first]),
-          code
-        ]);
-      }
-    }
+    code = super.exitFunction(name, formals, code);
 
     return new JS.Fun(formals, code);
   }
@@ -3543,9 +3533,7 @@
 
   @override
   JS.Statement visitReturnStatement(ReturnStatement node) {
-    var e = node.expression;
-    if (e == null) return new JS.Return();
-    return _visitExpression(e).toReturn();
+    return super.emitReturnStatement(_visitExpression(node.expression));
   }
 
   @override
diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
index 4710a15..57e667a 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -8,18 +8,20 @@
 import 'package:front_end/src/base/performance_logger.dart';
 import 'package:kernel/target/targets.dart' show Target;
 
-import '../fasta/fasta_codes.dart' show LocatedMessage;
+import '../fasta/fasta_codes.dart' show FormattedMessage;
 import '../fasta/severity.dart' show Severity;
 
 import 'compilation_message.dart';
 import 'file_system.dart';
 import 'standard_file_system.dart';
 
+export '../fasta/fasta_codes.dart' show FormattedMessage;
+
 /// Callback used to report errors encountered during compilation.
 typedef void ErrorHandler(CompilationMessage error);
 
-typedef void ProblemHandler(LocatedMessage problem, Severity severity,
-    String formatted, int line, int column);
+typedef void ProblemHandler(FormattedMessage problem, Severity severity,
+    List<FormattedMessage> context);
 
 /// Front-end options relevant to compiler back ends.
 ///
diff --git a/pkg/front_end/lib/src/api_unstable/summary_worker.dart b/pkg/front_end/lib/src/api_unstable/summary_worker.dart
index 2144265..2fdc8e5 100644
--- a/pkg/front_end/lib/src/api_unstable/summary_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/summary_worker.dart
@@ -18,7 +18,7 @@
 export 'compiler_state.dart';
 
 export '../api_prototype/standard_file_system.dart' show StandardFileSystem;
-export '../fasta/fasta_codes.dart' show LocatedMessage;
+export '../fasta/fasta_codes.dart' show FormattedMessage;
 export '../fasta/severity.dart' show Severity;
 
 Future<InitializedCompilerState> initializeCompiler(
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index f0a3761..02f7650 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -38,6 +38,7 @@
 
 import '../fasta/fasta_codes.dart'
     show
+        FormattedMessage,
         LocatedMessage,
         Message,
         messageCantInferPackagesFromManyInputs,
@@ -204,32 +205,46 @@
         (_raw.reportMessages ?? (_raw.onError == null));
   }
 
-  void report(LocatedMessage message, Severity severity) {
+  FormattedMessage format(LocatedMessage message, Severity severity) {
+    int offset = message.charOffset;
+    Uri uri = message.uri;
+    Location location = offset == -1 ? null : getLocation(uri, offset);
+    String formatted =
+        command_line_reporting.format(message, severity, location: location);
+    return message.withFormatting(
+        formatted, location?.line ?? -1, location?.column ?? -1);
+  }
+
+  void report(LocatedMessage message, Severity severity,
+      {List<LocatedMessage> context}) {
+    context ??= [];
     if (_raw.onProblem != null) {
-      int offset = message.charOffset;
-      Uri uri = message.uri;
-      Location location = offset == -1 ? null : getLocation(uri, offset);
-      _raw.onProblem(
-          message,
-          severity,
-          command_line_reporting.format(message, severity, location: location),
-          location?.line ?? -1,
-          location?.column ?? -1);
+      _raw.onProblem(format(message, severity), severity,
+          context.map((message) => format(message, Severity.context)).toList());
       if (command_line_reporting.shouldThrowOn(severity)) {
         if (verbose) print(StackTrace.current);
         throw new deprecated_InputError(
-            uri,
-            offset,
+            message.uri,
+            message.charOffset,
             "Compilation aborted due to fatal "
             "${command_line_reporting.severityName(severity)}.");
       }
       return;
     }
+
+    // Deprecated reporting mechanisms
     if (_raw.onError != null) {
       _raw.onError(new _CompilationMessage(message, severity));
+      for (LocatedMessage message in context) {
+        _raw.onError(new _CompilationMessage(message, Severity.context));
+      }
     }
-
-    if (_reportMessages) command_line_reporting.report(message, severity);
+    if (_reportMessages) {
+      command_line_reporting.report(message, severity);
+      for (LocatedMessage message in context) {
+        command_line_reporting.report(message, Severity.context);
+      }
+    }
   }
 
   // TODO(askesc): Remove this and direct callers directly to report.
@@ -377,7 +392,11 @@
   ///
   /// This is an asynchronous method since file system operations may be
   /// required to locate/read the packages file as well as SDK metadata.
-  Future<UriTranslatorImpl> getUriTranslator() async {
+  Future<UriTranslatorImpl> getUriTranslator({bool bypassCache: false}) async {
+    if (bypassCache) {
+      _uriTranslator = null;
+      _packages = null;
+    }
     if (_uriTranslator == null) {
       ticker.logMs("Started building UriTranslator");
       var libraries = await _computeLibrarySpecification();
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index 80d8055..f6d512c 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -218,13 +218,13 @@
   }
 
   void addCompileTimeError(Message message, int charOffset, int length,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     library.addCompileTimeError(message, charOffset, length, fileUri,
         context: context);
   }
 
   void addProblem(Message message, int charOffset, int length,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     library.addProblem(message, charOffset, length, fileUri, context: context);
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index a252d1e..2737d27 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -80,7 +80,7 @@
   /// If [fileUri] is null, it defaults to `this.fileUri`.
   void addCompileTimeError(
       Message message, int charOffset, int length, Uri fileUri,
-      {bool wasHandled: false, LocatedMessage context}) {
+      {bool wasHandled: false, List<LocatedMessage> context}) {
     fileUri ??= this.fileUri;
     loader.addCompileTimeError(message, charOffset, length, fileUri,
         wasHandled: wasHandled, context: context);
@@ -88,7 +88,7 @@
 
   /// Add a problem with a severity determined by the severity of the message.
   void addProblem(Message message, int charOffset, int length, Uri fileUri,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     fileUri ??= this.fileUri;
     loader.addProblem(message, charOffset, length, fileUri, context: context);
   }
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index 54d8af3..1795c7e 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -60,8 +60,9 @@
   }
 
   /// Report [message], for example, by printing it.
-  void report(LocatedMessage message, Severity severity) {
-    options.report(message, severity);
+  void report(LocatedMessage message, Severity severity,
+      {List<LocatedMessage> context}) {
+    options.report(message, severity, context: context);
   }
 
   /// Report [message], for example, by printing it.
diff --git a/pkg/front_end/lib/src/fasta/constant_context.dart b/pkg/front_end/lib/src/fasta/constant_context.dart
index a6dac50..a4d646a 100644
--- a/pkg/front_end/lib/src/fasta/constant_context.dart
+++ b/pkg/front_end/lib/src/fasta/constant_context.dart
@@ -23,19 +23,4 @@
   /// This means that `Object()` and `[]` are equivalent to `const Object()` and
   /// `const []` respectively. `new Object()` is a compile-time error.
   inferred,
-
-  /// In a context that allows only constant values, but requires them to be
-  /// defined as `const` explicitly.  For example, in default values of optional
-  /// and named parameters.
-  ///
-  /// The following code should emit a compile-time error:
-  ///
-  ///     class Bar { const Bar(); }
-  ///     class Foo { void foo({Bar bar: Bar()}) {} }
-  ///
-  /// The following code should compile without errors:
-  ///
-  ///     class Bar { const Bar(); }
-  ///     class Foo { void foo({Bar bar: const Bar()}) {} }
-  needsExplicitConst,
 }
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes.dart b/pkg/front_end/lib/src/fasta/fasta_codes.dart
index d3b42b9..3d1368d 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes.dart
@@ -122,6 +122,31 @@
     if (result != 0) return result;
     return message.compareTo(message);
   }
+
+  FormattedMessage withFormatting(String formatted, int line, int column) {
+    return new FormattedMessage(this, formatted, line, column);
+  }
+}
+
+class FormattedMessage {
+  final LocatedMessage locatedMessage;
+
+  final String formatted;
+
+  final int line;
+
+  final int column;
+
+  const FormattedMessage(
+      this.locatedMessage, this.formatted, this.line, this.column);
+
+  Code get code => locatedMessage.code;
+
+  String get message => locatedMessage.message;
+
+  String get tip => locatedMessage.tip;
+
+  Map<String, dynamic> get arguments => locatedMessage.arguments;
 }
 
 String relativizeUri(Uri uri) {
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index f234c10..f1d773d 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -359,16 +359,6 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeCantDetermineConstness = messageCantDetermineConstness;
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageCantDetermineConstness = const MessageCode(
-    "CantDetermineConstness",
-    severity: Severity.error,
-    message:
-        r"""The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.""");
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeCantInferPackagesFromManyInputs =
     messageCantInferPackagesFromManyInputs;
 
@@ -2581,6 +2571,28 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String string)>
+    templateInternalProblemContextSeverity =
+    const Template<Message Function(String string)>(
+        messageTemplate:
+            r"""Non-context message has context severity: #string""",
+        withArguments: _withArgumentsInternalProblemContextSeverity);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string)> codeInternalProblemContextSeverity =
+    const Code<Message Function(String string)>(
+        "InternalProblemContextSeverity",
+        templateInternalProblemContextSeverity,
+        severity: Severity.internalProblem);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsInternalProblemContextSeverity(String string) {
+  return new Message(codeInternalProblemContextSeverity,
+      message: """Non-context message has context severity: $string""",
+      arguments: {'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeInternalProblemExtendingUnmodifiableScope =
     messageInternalProblemExtendingUnmodifiableScope;
 
@@ -3535,6 +3547,18 @@
         r"""Make sure there is an exponent, and remove any whitespace before it.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeMissingExpressionInThrow = messageMissingExpressionInThrow;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageMissingExpressionInThrow = const MessageCode(
+    "MissingExpressionInThrow",
+    analyzerCode: "MISSING_EXPRESSION_IN_THROW",
+    dart2jsCode: "*fatal*",
+    message: r"""Missing expression after 'throw'.""",
+    tip:
+        r"""Add an expression after 'throw' or use 'rethrow' to throw a caught exception""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeMissingFunctionParameters =
     messageMissingFunctionParameters;
 
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index fe2dddf9..9af08b2 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -45,6 +45,7 @@
   List<Uri> invalidatedUris = <Uri>[];
 
   DillTarget dillLoadedData;
+  Map<Uri, Source> dillLoadedDataUriToSource = <Uri, Source>{};
   List<LibraryBuilder> platformBuilders;
   Map<Uri, LibraryBuilder> userBuilders;
   final Uri initializeFromDillUri;
@@ -62,22 +63,27 @@
     entryPoint ??= context.options.inputs.single;
     return context.runInContext<Future<Component>>((CompilerContext c) async {
       IncrementalCompilerData data = new IncrementalCompilerData();
-      if (dillLoadedData == null) {
-        UriTranslator uriTranslator = await c.options.getUriTranslator();
-        ticker.logMs("Read packages file");
 
+      // TODO(jensj): We should only bypass the cache if .packages has been
+      // invalidated, but Flutter does not currently invalidate .packages.
+      UriTranslator uriTranslator =
+          await c.options.getUriTranslator(bypassCache: true);
+      ticker.logMs("Read packages file");
+
+      if (dillLoadedData == null) {
         List<int> summaryBytes = await c.options.loadSdkSummaryBytes();
         int bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
         if (initializeFromDillUri != null) {
           try {
-            bytesLength += await initializeFromDill(summaryBytes, c, data);
+            bytesLength +=
+                await initializeFromDill(summaryBytes, uriTranslator, c, data);
           } catch (e) {
             // We might have loaded x out of y libraries into the component.
             // To avoid any unforeseen problems start over.
             bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
           }
         }
-        appendLibraries(data, bytesLength, uriTranslator);
+        appendLibraries(data, bytesLength);
 
         try {
           await dillLoadedData.buildOutlines();
@@ -88,7 +94,7 @@
           initializedFromDill = false;
           data.reset();
           bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
-          appendLibraries(data, bytesLength, uriTranslator);
+          appendLibraries(data, bytesLength);
           await dillLoadedData.buildOutlines();
         }
         summaryBytes = null;
@@ -111,7 +117,7 @@
       }
 
       List<LibraryBuilder> reusedLibraries =
-          computeReusedLibraries(invalidatedUris);
+          computeReusedLibraries(invalidatedUris, uriTranslator);
       Set<Uri> reusedLibraryUris =
           new Set<Uri>.from(reusedLibraries.map((b) => b.uri));
       for (Uri uri in new Set<Uri>.from(dillLoadedData.loader.builders.keys)
@@ -127,7 +133,7 @@
 
       KernelIncrementalTarget userCodeOld = userCode;
       userCode = new KernelIncrementalTarget(
-          c.fileSystem, false, dillLoadedData, dillLoadedData.uriTranslator,
+          c.fileSystem, false, dillLoadedData, uriTranslator,
           uriToSource: c.uriToSource);
 
       for (LibraryBuilder library in reusedLibraries) {
@@ -157,38 +163,49 @@
         userCode.loader.builders.clear();
         userCode = userCodeOld;
         return new Component(
-            libraries: libraries, uriToSource: data.uriToSource);
+            libraries: libraries, uriToSource: <Uri, Source>{});
       }
       userCodeOld?.loader?.builders?.clear();
       userCodeOld = null;
 
       List<Library> libraries =
           new List<Library>.from(userCode.loader.libraries);
-      data.uriToSource.addAll(userCode.uriToSource);
+      Map<Uri, Source> uriToSource =
+          new Map<Uri, Source>.from(dillLoadedDataUriToSource);
+      uriToSource.addAll(userCode.uriToSource);
       Procedure mainMethod = componentWithDill == null
           ? data.userLoadedUriMain
           : componentWithDill.mainMethod;
+
       if (data.includeUserLoadedLibraries || fullComponent) {
-        addReusedLibraries(libraries, mainMethod, reusedLibraries, data);
+        addReusedLibraries(
+            libraries, mainMethod, entryPoint, reusedLibraries, data);
       }
 
       // Clean up.
       userCode.loader.releaseAncillaryResources();
 
       // This is the incremental component.
-      return new Component(libraries: libraries, uriToSource: data.uriToSource)
+      return new Component(libraries: libraries, uriToSource: uriToSource)
         ..mainMethod = mainMethod;
     });
   }
 
-  void addReusedLibraries(List<Library> libraries, Procedure mainMethod,
-      List<LibraryBuilder> reusedLibraries, IncrementalCompilerData data) {
+  void addReusedLibraries(
+      List<Library> libraries,
+      Procedure mainMethod,
+      Uri entry,
+      List<LibraryBuilder> reusedLibraries,
+      IncrementalCompilerData data) {
     Map<Uri, Library> libraryMap = <Uri, Library>{};
     for (Library library in libraries) {
       libraryMap[library.fileUri] = library;
     }
     List<Uri> worklist = new List<Uri>.from(libraryMap.keys);
     worklist.add(mainMethod?.enclosingLibrary?.fileUri);
+    if (entry != null) {
+      worklist.add(entry);
+    }
 
     Map<Uri, Library> potentiallyReferencedLibraries = <Uri, Library>{};
     for (LibraryBuilder library in reusedLibraries) {
@@ -246,7 +263,10 @@
   }
 
   // This procedure will try to load the dill file and will crash if it cannot.
-  Future<int> initializeFromDill(List<int> summaryBytes, CompilerContext c,
+  Future<int> initializeFromDill(
+      List<int> summaryBytes,
+      UriTranslator uriTranslator,
+      CompilerContext c,
       IncrementalCompilerData data) async {
     int bytesLength = 0;
     FileSystemEntity entity =
@@ -265,6 +285,20 @@
         new BinaryBuilder(initializationBytes, disableLazyReading: true)
             .readComponent(data.component);
 
+        // Check the any package-urls still point to the same file
+        // (e.g. the package still exists and hasn't been updated).
+        for (Library lib in data.component.libraries) {
+          if (lib.importUri.scheme == "package" &&
+              uriTranslator.translate(lib.importUri, false) != lib.fileUri) {
+            // Package has been removed or updated.
+            // This library should be thrown away.
+            // Everything that depends on it should be thrown away.
+            // TODO(jensj): Anything that doesn't depend on it can be kept.
+            // For now just don't initialize from this dill.
+            throw "Changed package";
+          }
+        }
+
         initializedFromDill = true;
         bytesLength += initializationBytes.length;
         for (Library lib in data.component.libraries) {
@@ -275,34 +309,23 @@
         data.includeUserLoadedLibraries = true;
         for (Uri uri in data.component.uriToSource.keys) {
           if (sdkUris.contains(uri)) continue;
-          data.uriToSource[uri] = data.component.uriToSource[uri];
+          dillLoadedDataUriToSource[uri] = data.component.uriToSource[uri];
         }
       }
     }
     return bytesLength;
   }
 
-  void appendLibraries(IncrementalCompilerData data, int bytesLength,
-      UriTranslator uriTranslator) {
+  void appendLibraries(IncrementalCompilerData data, int bytesLength) {
     if (data.component != null) {
-      List<Library> keepLibraries = <Library>[];
-      for (Library lib in data.component.libraries) {
-        if (lib.importUri.scheme != "package" ||
-            uriTranslator.translate(lib.importUri, false) != null) {
-          keepLibraries.add(lib);
-        }
-      }
-      data.component.libraries
-        ..clear()
-        ..addAll(keepLibraries);
-
       dillLoadedData.loader
           .appendLibraries(data.component, byteCount: bytesLength);
     }
     ticker.logMs("Appended libraries");
   }
 
-  List<LibraryBuilder> computeReusedLibraries(Iterable<Uri> invalidatedUris) {
+  List<LibraryBuilder> computeReusedLibraries(
+      Iterable<Uri> invalidatedUris, UriTranslator uriTranslator) {
     if (userCode == null && userBuilders == null) {
       return <LibraryBuilder>[];
     }
@@ -326,7 +349,10 @@
               invalidatedFileUris.contains(library.fileUri)) ||
           (library is DillLibraryBuilder &&
               uri != library.library.fileUri &&
-              invalidatedFileUris.contains(library.library.fileUri))) {
+              invalidatedFileUris.contains(library.library.fileUri)) ||
+          (library.uri.scheme == "package" &&
+              uriTranslator.translate(library.uri, false) !=
+                  library.target.fileUri)) {
         invalidatedImportUris.add(uri);
       }
       if (!recursive) return;
@@ -407,7 +433,6 @@
 
 class IncrementalCompilerData {
   bool includeUserLoadedLibraries;
-  Map<Uri, Source> uriToSource;
   Map<Uri, int> importUriToOrder;
   Procedure userLoadedUriMain;
   Component component;
@@ -418,7 +443,6 @@
 
   reset() {
     includeUserLoadedLibraries = false;
-    uriToSource = <Uri, Source>{};
     importUriToOrder = <Uri, int>{};
     userLoadedUriMain = null;
     component = null;
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 822a724..b3df16c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -76,8 +76,6 @@
 
 import '../names.dart';
 
-import 'constness_evaluator.dart' show evaluateConstness, ConstnessEffect;
-
 import 'fasta_accessors.dart';
 
 import 'kernel_api.dart';
@@ -185,12 +183,6 @@
   /// and where that was.
   Map<String, int> initializedFields;
 
-  /// Constructor invocations (either generative or factory) with not specified
-  /// `new` or `const` keywords.  The constness for these should be inferred
-  /// based on the subexpressions.
-  List<Expression> constructorInvocationsWithImplicitConstness =
-      new List<Expression>();
-
   BodyBuilder(
       KernelLibraryBuilder library,
       this.member,
@@ -398,7 +390,8 @@
     pushQualifiedReference(beginToken.next, periodBeforeName);
     if (arguments != null) {
       push(arguments);
-      endNewExpression(beginToken);
+      buildConstructorReferenceInvocation(
+          beginToken, beginToken.offset, Constness.explicitConst);
       push(popForValue());
     } else {
       String name = pop();
@@ -693,50 +686,6 @@
       unhandled("${builder.runtimeType}", "finishFunction", builder.charOffset,
           builder.fileUri);
     }
-
-    inferConstness();
-  }
-
-  // Infers constness of the constructor invocations collected so far in
-  // [constructorInvocationsWithImplicitConstness], then clears out the list.
-  void inferConstness() {
-    // The algorithm below takes advantage of the fact that for each expression
-    // that needs constness inference comes after all its subexpressions that
-    // also need constness inference in
-    // [constructorInvocationsWithImplicitConstness].
-    for (Expression invocation in constructorInvocationsWithImplicitConstness) {
-      if (invocation is ConstructorInvocation) {
-        ConstnessEffect constness =
-            evaluateConstness(invocation, coreTypes, uri).effect;
-        if (constness == ConstnessEffect.taintedConst) {
-          // TODO(dmitryas): Find a better way to unwrap the error node.
-          ShadowSyntheticExpression errorMessage = buildCompileTimeError(
-              fasta.messageCantDetermineConstness,
-              invocation.fileOffset,
-              noLength);
-          invocation.replaceWith(errorMessage.desugared);
-        } else {
-          invocation.isConst = constness == ConstnessEffect.allowedConst;
-        }
-      } else if (invocation is StaticInvocation) {
-        ConstnessEffect constness =
-            evaluateConstness(invocation, coreTypes, uri).effect;
-        if (constness == ConstnessEffect.taintedConst) {
-          // TODO(dmitryas): Find a better way to unwrap the error node.
-          ShadowSyntheticExpression errorMessage = buildCompileTimeError(
-              fasta.messageCantDetermineConstness,
-              invocation.fileOffset,
-              noLength);
-          invocation.replaceWith(errorMessage.desugared);
-        } else {
-          invocation.isConst = constness == ConstnessEffect.allowedConst;
-        }
-      } else {
-        unhandled("${invocation.runtimeType}", "inferConstness",
-            invocation.fileOffset, invocation.location.file);
-      }
-    }
-    constructorInvocationsWithImplicitConstness.clear();
   }
 
   @override
@@ -1071,7 +1020,7 @@
       LocatedMessage argMessage}) {
     Message message;
     Name kernelName = new Name(name, library.library);
-    LocatedMessage context;
+    List<LocatedMessage> context;
     if (candidate != null) {
       Uri uri = candidate.location.file;
       int offset = candidate.fileOffset;
@@ -1085,7 +1034,7 @@
         length = name.length;
         message = fasta.messageCandidateFound;
       }
-      context = message.withLocation(uri, offset, length);
+      context = [message.withLocation(uri, offset, length)];
     }
 
     if (isGetter) {
@@ -1131,7 +1080,9 @@
 
   @override
   Message warnUnresolvedGet(Name name, int charOffset,
-      {bool isSuper: false, bool reportWarning: true, LocatedMessage context}) {
+      {bool isSuper: false,
+      bool reportWarning: true,
+      List<LocatedMessage> context}) {
     Message message = isSuper
         ? fasta.templateSuperclassHasNoGetter.withArguments(name.name)
         : fasta.templateGetterNotFound.withArguments(name.name);
@@ -1144,7 +1095,9 @@
 
   @override
   Message warnUnresolvedSet(Name name, int charOffset,
-      {bool isSuper: false, bool reportWarning: true, LocatedMessage context}) {
+      {bool isSuper: false,
+      bool reportWarning: true,
+      List<LocatedMessage> context}) {
     Message message = isSuper
         ? fasta.templateSuperclassHasNoSetter.withArguments(name.name)
         : fasta.templateSetterNotFound.withArguments(name.name);
@@ -1157,7 +1110,9 @@
 
   @override
   Message warnUnresolvedMethod(Name name, int charOffset,
-      {bool isSuper: false, bool reportWarning: true, LocatedMessage context}) {
+      {bool isSuper: false,
+      bool reportWarning: true,
+      List<LocatedMessage> context}) {
     String plainName = name.name;
     int dotIndex = plainName.lastIndexOf(".");
     if (dotIndex != -1) {
@@ -2187,7 +2142,7 @@
   @override
   void beginFormalParameterDefaultValueExpression() {
     super.push(constantContext);
-    constantContext = ConstantContext.needsExplicitConst;
+    constantContext = ConstantContext.none;
   }
 
   @override
@@ -2514,11 +2469,6 @@
           argMessage: argMessage);
     }
     if (target is Constructor) {
-      if (constantContext == ConstantContext.needsExplicitConst &&
-          constness == Constness.implicit) {
-        return buildCompileTimeError(
-            fasta.messageCantDetermineConstness, charOffset, noLength);
-      }
       isConst =
           isConst || constantContext != ConstantContext.none && target.isConst;
       if ((isConst || constantContext == ConstantContext.inferred) &&
@@ -2526,19 +2476,10 @@
         return deprecated_buildCompileTimeError(
             "Not a const constructor.", charOffset);
       }
-      ShadowConstructorInvocation invocation = new ShadowConstructorInvocation(
-          target,
-          targetTypeArguments,
-          initialTarget,
-          forest.castArguments(arguments),
+      return new ShadowConstructorInvocation(target, targetTypeArguments,
+          initialTarget, forest.castArguments(arguments),
           isConst: isConst)
         ..fileOffset = charOffset;
-      if (constness == Constness.implicit &&
-          target.isConst &&
-          constantContext != ConstantContext.inferred) {
-        constructorInvocationsWithImplicitConstness.add(invocation);
-      }
-      return invocation;
     } else {
       Procedure procedure = target;
       if (procedure.isFactory) {
@@ -2549,22 +2490,10 @@
           return deprecated_buildCompileTimeError(
               "Not a const factory.", charOffset);
         }
-        if (constantContext == ConstantContext.needsExplicitConst &&
-            constness == Constness.implicit) {
-          return buildCompileTimeError(
-              fasta.messageCantDetermineConstness, charOffset, noLength);
-        }
-        ShadowFactoryConstructorInvocation invocation =
-            new ShadowFactoryConstructorInvocation(target, targetTypeArguments,
-                initialTarget, forest.castArguments(arguments),
-                isConst: isConst)
-              ..fileOffset = charOffset;
-        if (constness == Constness.implicit &&
-            procedure.isConst &&
-            constantContext != ConstantContext.inferred) {
-          constructorInvocationsWithImplicitConstness.add(invocation);
-        }
-        return invocation;
+        return new ShadowFactoryConstructorInvocation(target,
+            targetTypeArguments, initialTarget, forest.castArguments(arguments),
+            isConst: isConst)
+          ..fileOffset = charOffset;
       } else {
         return new ShadowStaticInvocation(
             target, forest.castArguments(arguments),
@@ -2679,6 +2608,12 @@
   }
 
   @override
+  void beginImplicitCreationExpression(Token token) {
+    debugEvent("beginImplicitCreationExpression");
+    super.push(constantContext);
+  }
+
+  @override
   void endConstLiteral(Token token) {
     debugEvent("endConstLiteral");
     var literal = pop();
@@ -2689,7 +2624,12 @@
   @override
   void endNewExpression(Token token) {
     debugEvent("NewExpression");
-    Token nameToken = token.next;
+    buildConstructorReferenceInvocation(
+        token.next, token.offset, Constness.explicitNew);
+  }
+
+  void buildConstructorReferenceInvocation(
+      Token nameToken, int offset, Constness constness) {
     Arguments arguments = pop();
     String name = pop();
     List<DartType> typeArguments = pop();
@@ -2715,28 +2655,27 @@
     ConstantContext savedConstantContext = pop();
     if (type is TypeDeclarationBuilder) {
       Expression expression = buildConstructorInvocation(
-          type,
-          nameToken,
-          arguments,
-          name,
-          typeArguments,
-          token.charOffset,
-          optional("const", token) || optional("@", token)
-              ? Constness.explicitConst
-              : Constness.explicitNew);
+          type, nameToken, arguments, name, typeArguments, offset, constness);
       push(deferredPrefix != null
           ? wrapInDeferredCheck(expression, deferredPrefix, checkOffset)
           : expression);
     } else if (type is ErrorAccessor) {
       push(type.buildError(arguments));
     } else {
-      push(throwNoSuchMethodError(forest.literalNull(token),
+      push(throwNoSuchMethodError(storeOffset(forest.literalNull(null), offset),
           debugName(getNodeName(type), name), arguments, nameToken.charOffset));
     }
     constantContext = savedConstantContext;
   }
 
   @override
+  void endImplicitCreationExpression(Token token) {
+    debugEvent("ImplicitCreationExpression");
+    buildConstructorReferenceInvocation(
+        token, token.offset, Constness.implicit);
+  }
+
+  @override
   Expression buildConstructorInvocation(
       TypeDeclarationBuilder type,
       Token nameToken,
@@ -2834,7 +2773,8 @@
   @override
   void endConstExpression(Token token) {
     debugEvent("endConstExpression");
-    endNewExpression(token);
+    buildConstructorReferenceInvocation(
+        token.next, token.offset, Constness.explicitConst);
   }
 
   @override
@@ -3624,7 +3564,7 @@
 
   @override
   Expression buildCompileTimeError(Message message, int charOffset, int length,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     library.addCompileTimeError(message, charOffset, length, uri,
         wasHandled: true, context: context);
     return new ShadowSyntheticExpression(library.loader
@@ -3681,7 +3621,7 @@
   }
 
   Statement buildCompileTimeErrorStatement(Message message, int charOffset,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     return new ShadowExpressionStatement(
         buildCompileTimeError(message, charOffset, noLength, context: context));
   }
@@ -3733,9 +3673,11 @@
                 .withArguments(name),
             offset,
             noLength,
-            context: fasta.templateFinalInstanceVariableAlreadyInitializedCause
-                .withArguments(name)
-                .withLocation(uri, builder.charOffset, noLength));
+            context: [
+              fasta.templateFinalInstanceVariableAlreadyInitializedCause
+                  .withArguments(name)
+                  .withLocation(uri, builder.charOffset, noLength)
+            ]);
         Builder constructor =
             library.loader.getDuplicatedFieldInitializerError();
         return buildInvalidInitializer(
@@ -3932,20 +3874,20 @@
 
   @override
   void addCompileTimeError(Message message, int charOffset, int length,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     library.addCompileTimeError(message, charOffset, length, uri,
         context: context);
   }
 
   @override
   void addProblem(Message message, int charOffset, int length,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     library.addProblem(message, charOffset, length, uri, context: context);
   }
 
   @override
   void addProblemErrorIfConst(Message message, int charOffset, int length,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     // TODO(askesc): Instead of deciding on the severity, this method should
     // take two messages: one to use when a constant expression is
     // required and one to use otherwise.
diff --git a/pkg/front_end/lib/src/fasta/kernel/constness_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constness_evaluator.dart
index ab7f9ce..8322954 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constness_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constness_evaluator.dart
@@ -6,7 +6,7 @@
 
 import 'package:kernel/core_types.dart' show CoreTypes;
 
-import 'package:kernel/visitor.dart' show ExpressionVisitor;
+import 'package:kernel/visitor.dart' show ExpressionVisitor, DartTypeVisitor;
 
 import '../names.dart'
     show
@@ -14,14 +14,12 @@
         barName,
         caretName,
         divisionName,
-        doubleAmpersandName,
-        doubleBarName,
-        doubleQuestionName,
         equalsName,
         greaterThanName,
         greaterThanOrEqualsName,
         identicalName,
         leftShiftName,
+        lengthName,
         lessThanName,
         lessThanOrEqualsName,
         minusName,
@@ -31,68 +29,19 @@
         percentName,
         plusName,
         rightShiftName,
-        tildaName,
+        tildeName,
         unaryMinusName;
 
 import '../fasta_codes.dart' show templateInternalVisitorUnsupportedDefault;
 
 import '../problems.dart' show unsupported;
 
-enum ConstnessEffect {
-  decidedNew,
-  allowedConst,
-  taintedConst,
-}
-
-enum ConstantKind {
-  nullConstant,
-  boolConstant,
-  intConstant,
-  doubleConstant,
-  stringConstant,
-  symbolConstant,
-  typeConstant,
-  listConstant,
-  mapConstant,
-  interfaceConstant,
-}
-
-class ConstnessInfo {
-  final ConstnessEffect effect;
-  final ConstantKind kind;
-  final Map<Reference, ConstnessInfo> fields;
-
-  // TODO(dmitryas): Find a way to impose the following restrictions:
-  //   * `kind == null || effect != ConstnessEffect.decidedNew`
-  //   * `fields == null || kind == ConstantKind.interfaceConstant`.
-  const ConstnessInfo(this.effect, [this.kind, this.fields]);
-
-  const ConstnessInfo.decidedNew()
-      : this(ConstnessEffect.decidedNew, null, null);
-
-  const ConstnessInfo.allowedConst(ConstantKind kind,
-      [Map<Reference, ConstnessInfo> fields])
-      : this(ConstnessEffect.allowedConst, kind, fields);
-
-  const ConstnessInfo.taintedConst(ConstantKind kind,
-      [Map<Reference, ConstnessInfo> fields])
-      : this(ConstnessEffect.taintedConst, kind, fields);
-
-  bool get isConst => effect != ConstnessEffect.decidedNew;
-
-  bool get isPrimitiveConstant => kind != ConstantKind.interfaceConstant;
-
-  bool get isInterfaceConstant => kind == ConstantKind.interfaceConstant;
-}
-
 /// Evaluates constness of the given constructor invocation.
 ///
 /// TODO(dmitryas): Share code with the constant evaluator from
 /// pkg/kernel/lib/transformations/constants.dart.
-class ConstnessEvaluator implements ExpressionVisitor<ConstnessInfo> {
-  final Map<Expression, ConstnessInfo> constnesses =
-      <Expression, ConstnessInfo>{};
-
+class ConstnessEvaluator
+    implements ExpressionVisitor<bool>, DartTypeVisitor<bool> {
   final CoreTypes coreTypes;
 
   /// [Uri] of the file containing the expressions that are to be evaluated.
@@ -115,285 +64,227 @@
     return defaultExpression(node);
   }
 
-  ConstnessInfo evaluate(Expression node) {
-    return node.accept(this);
+  @override
+  defaultDartType(DartType node) {
+    return unsupported(
+        templateInternalVisitorUnsupportedDefault
+            .withArguments("${node.runtimeType}")
+            .message,
+        -1,
+        uri);
   }
 
-  List<ConstnessInfo> evaluateList(List<Expression> nodes) {
-    List<ConstnessInfo> result = new List<ConstnessInfo>(nodes.length);
-    for (int i = 0; i < nodes.length; ++i) {
-      result[i] = nodes[i].accept(this);
+  @override
+  visitInvalidType(InvalidType node) => false;
+
+  @override
+  visitDynamicType(DynamicType node) => true;
+
+  @override
+  visitVoidType(VoidType node) => true;
+
+  @override
+  visitBottomType(BottomType node) => true;
+
+  @override
+  visitInterfaceType(InterfaceType node) {
+    for (var type in node.typeArguments) {
+      if (!type.accept(this)) return false;
     }
-    return result;
+    return true;
+  }
+
+  @override
+  visitVectorType(VectorType node) => true;
+
+  @override
+  visitFunctionType(FunctionType node) {
+    if (!node.returnType.accept(this)) return false;
+    for (var parameter in node.positionalParameters) {
+      if (!parameter.accept(this)) return false;
+    }
+    for (var parameter in node.namedParameters) {
+      if (!parameter.type.accept(this)) return false;
+    }
+    for (var typeParameter in node.typeParameters) {
+      if (!typeParameter.bound.accept(this)) return false;
+    }
+    return true;
+  }
+
+  @override
+  visitTypeParameterType(TypeParameterType node) => false;
+
+  @override
+  visitTypedefType(TypedefType node) {
+    for (var type in node.typeArguments) {
+      if (!type.accept(this)) return false;
+    }
+    return true;
+  }
+
+  bool evaluate(Expression node) {
+    return node.accept(this);
   }
 
   @override
   visitNullLiteral(NullLiteral node) {
-    return const ConstnessInfo.allowedConst(ConstantKind.nullConstant);
+    return true;
   }
 
   @override
   visitBoolLiteral(BoolLiteral node) {
-    return const ConstnessInfo.allowedConst(ConstantKind.boolConstant);
+    return true;
   }
 
   @override
   visitIntLiteral(IntLiteral node) {
-    return const ConstnessInfo.allowedConst(ConstantKind.intConstant);
+    return true;
   }
 
   @override
   visitDoubleLiteral(DoubleLiteral node) {
-    return const ConstnessInfo.allowedConst(ConstantKind.doubleConstant);
+    return true;
   }
 
   @override
   visitStringLiteral(StringLiteral node) {
-    return const ConstnessInfo.allowedConst(ConstantKind.stringConstant);
+    return true;
   }
 
   @override
   visitSymbolLiteral(SymbolLiteral node) {
-    return const ConstnessInfo.allowedConst(ConstantKind.symbolConstant);
+    return true;
   }
 
   @override
   visitTypeLiteral(TypeLiteral node) {
-    return const ConstnessInfo.allowedConst(ConstantKind.typeConstant);
+    // TODO(dmitryas): Figure out how to handle deferred types.
+    return node.type.accept(this);
   }
 
   @override
   visitListLiteral(ListLiteral node) {
-    if (node.isConst) {
-      return const ConstnessInfo.allowedConst(ConstantKind.listConstant);
-    }
-    return const ConstnessInfo.decidedNew();
+    return node.isConst;
   }
 
   @override
   visitMapLiteral(MapLiteral node) {
-    if (node.isConst) {
-      return const ConstnessInfo.allowedConst(ConstantKind.mapConstant);
-    }
-    return const ConstnessInfo.decidedNew();
+    return node.isConst;
   }
 
   @override
   visitConstructorInvocation(ConstructorInvocation node) {
-    if (constnesses[node] != null) return constnesses[node];
-
     if (!node.target.isConst) {
-      return const ConstnessInfo.decidedNew();
+      return false;
     }
 
-    List<ConstnessInfo> positionalArgumentsInfos =
-        new List<ConstnessInfo>(node.arguments.positional.length);
-    for (int i = 0; i < positionalArgumentsInfos.length; ++i) {
-      positionalArgumentsInfos[i] = node.arguments.positional[i].accept(this);
+    for (var type in node.arguments.types) {
+      if (!type.accept(this)) return false;
+    }
+    for (var expression in node.arguments.positional) {
+      if (!expression.accept(this)) return false;
+    }
+    for (var namedExpression in node.arguments.named) {
+      if (!namedExpression.value.accept(this)) return false;
     }
 
-    Map<String, ConstnessInfo> namedArgumentsInfos = <String, ConstnessInfo>{};
-    for (NamedExpression namedArgument in node.arguments.named) {
-      namedArgumentsInfos[namedArgument.name] =
-          namedArgument.value.accept(this);
-    }
-
-    ConstnessEffect resultEffect =
-        minConstnessEffectOnInfos(positionalArgumentsInfos);
-    if (resultEffect != null) {
-      resultEffect = minConstnessEffectOnPair(
-          resultEffect, minConstnessEffectOnInfos(namedArgumentsInfos.values));
-    } else {
-      resultEffect = minConstnessEffectOnInfos(namedArgumentsInfos.values);
-    }
-    resultEffect ??= ConstnessEffect.allowedConst;
-
-    if (resultEffect == ConstnessEffect.decidedNew) {
-      return const ConstnessInfo.decidedNew();
-    }
-
-    return constnesses[node] =
-        new ConstnessInfo(resultEffect, ConstantKind.interfaceConstant);
+    return true;
   }
 
   @override
   visitMethodInvocation(MethodInvocation node) {
-    Expression receiver = node.receiver;
-    ConstnessInfo receiverConstness = receiver.accept(this);
-    List<ConstnessInfo> positionalArgumentConstness =
-        new List<ConstnessInfo>(node.arguments.positional.length);
-    for (int i = 0; i < positionalArgumentConstness.length; ++i) {
-      positionalArgumentConstness[i] =
-          node.arguments.positional[i].accept(this);
-    }
-    Map<String, ConstnessInfo> namedArgumentConstness =
-        <String, ConstnessInfo>{};
-    for (NamedExpression namedArgument in node.arguments.named) {
-      namedArgumentConstness[namedArgument.name] =
-          namedArgument.value.accept(this);
+    if (node.arguments.named.isNotEmpty ||
+        node.arguments.types.isNotEmpty ||
+        !isConstantMethodName(node.name, node.arguments.positional.length)) {
+      return false;
     }
 
-    ConstnessEffect minimumConstnessEffect = receiverConstness.effect;
-    minimumConstnessEffect = minConstnessEffectOnPair(minimumConstnessEffect,
-        minConstnessEffectOnInfos(positionalArgumentConstness));
-    minimumConstnessEffect = minConstnessEffectOnPair(minimumConstnessEffect,
-        minConstnessEffectOnInfos(namedArgumentConstness.values));
-
-    if (minimumConstnessEffect == ConstnessEffect.decidedNew) {
-      return const ConstnessInfo.decidedNew();
+    if (!node.receiver.accept(this)) return false;
+    for (var expression in node.arguments.positional) {
+      if (!expression.accept(this)) return false;
     }
 
-    // Special case: ==.
-    if (node.name == equalsName) {
-      assert(node.arguments.positional.length == 1);
-      return new ConstnessInfo(
-          minimumConstnessEffect, ConstantKind.boolConstant);
-    }
-
-    // Check for operations that are known to yield a constant value, like the
-    // addition of two integer constants.
-    if (node.arguments.named.length == 0) {
-      List<ConstantKind> argumentsKinds =
-          new List<ConstantKind>(positionalArgumentConstness.length);
-      for (int i = 0; i < argumentsKinds.length; ++i) {
-        argumentsKinds[i] = positionalArgumentConstness[i].kind;
-      }
-      ConstantKind resultKind = evaluateConstantMethodInvocationKind(
-          receiverConstness.kind, node.name, argumentsKinds);
-      if (resultKind != null) {
-        return new ConstnessInfo(minimumConstnessEffect, resultKind);
-      }
-    }
-
-    return const ConstnessInfo.decidedNew();
+    return true;
   }
 
   @override
   visitLogicalExpression(LogicalExpression node) {
-    ConstnessInfo left = node.left.accept(this);
-    if (node.operator == doubleBarName) {
-      ConstnessInfo right = node.right.accept(this);
-      if (left.isConst && right.isConst) {
-        return new ConstnessInfo(
-            minConstnessEffectOnPair(left.effect, right.effect),
-            ConstantKind.boolConstant);
-      }
-      // TODO(dmitryas): Handle the case where [left] is `true`.
-    } else if (node.operator == doubleAmpersandName) {
-      ConstnessInfo right = node.right.accept(this);
-      if (left.isConst && right.isConst) {
-        return new ConstnessInfo(
-            minConstnessEffectOnPair(left.effect, right.effect),
-            ConstantKind.boolConstant);
-      }
-      // TODO(dmitryas): Handle the case when [left] is `false`.
-    } else if (node.operator == doubleQuestionName) {
-      ConstnessInfo right = node.right.accept(this);
-      if (left.isConst && left.kind == ConstantKind.nullConstant) {
-        if (right.isConst) {
-          return right;
-        }
-      } else {
-        if (left.isConst) {
-          return left;
-        }
-      }
-    }
-    return const ConstnessInfo.decidedNew();
+    return node.left.accept(this) && node.right.accept(this);
   }
 
   @override
   visitConditionalExpression(ConditionalExpression node) {
-    // TODO(dmitryas): Handle this case after boolean constants are handled.
-    return const ConstnessInfo.taintedConst(null);
+    return node.condition.accept(this) &&
+        node.then.accept(this) &&
+        node.otherwise.accept(this);
   }
 
   @override
   visitPropertyGet(PropertyGet node) {
-    // TODO(dmitryas): Handle this case after fields are handled.
-    ConstnessInfo receiverInfo = node.receiver.accept(this);
-    if (receiverInfo.isConst &&
-        receiverInfo.kind == ConstantKind.stringConstant) {
-      return new ConstnessInfo(receiverInfo.effect, ConstantKind.intConstant);
-    }
-    return const ConstnessInfo.taintedConst(null);
+    if (!isConstantPropertyName(node.name)) return false;
+    return node.receiver.accept(this);
   }
 
   @override
   visitLet(Let node) {
-    return node.body.accept(this);
+    return node.variable.initializer.accept(this) && node.body.accept(this);
   }
 
   @override
   visitVariableGet(VariableGet node) {
-    if (!node.variable.isConst) return const ConstnessInfo.decidedNew();
-    // TODO(dmitryas): Handle the case of recursive dependencies.
-    // TODO(dmitryas): Find a way to get fileUri of the variable.
-    return node.variable.initializer.accept(this);
+    return node.variable.isConst;
   }
 
   @override
   visitStaticGet(StaticGet node) {
     Member target = node.target;
     if (target is Field) {
-      if (target.isConst) {
-        if (this.uri == target.fileUri) {
-          return target.initializer.accept(this);
-        }
-        return target.initializer
-            .accept(new ConstnessEvaluator(coreTypes, target.fileUri));
-      } else {
-        return const ConstnessInfo.decidedNew();
-      }
+      return target.isConst;
     } else {
-      // TODO(dmitryas): Handle the case of a tear-off.
-      return const ConstnessInfo.taintedConst(null);
+      // TODO(dmitryas): Figure out how to deal with deferred functions.
+      return true;
     }
   }
 
   @override
   visitStringConcatenation(StringConcatenation node) {
-    List<ConstnessInfo> infos =
-        new List<ConstnessInfo>(node.expressions.length);
-    bool isPrimitiveConstant = true;
-    for (int i = 0; i < infos.length; ++i) {
-      infos[i] = node.expressions[i].accept(this);
-      isPrimitiveConstant = isPrimitiveConstant && infos[i].isPrimitiveConstant;
+    for (var expression in node.expressions) {
+      if (!expression.accept(this)) return false;
     }
-    ConstnessEffect effect = minConstnessEffectOnInfos(infos);
-
-    // Only primitive constants are allowed during const string interpolation.
-    if (effect == ConstnessEffect.decidedNew || !isPrimitiveConstant) {
-      return const ConstnessInfo.decidedNew();
-    }
-
-    return new ConstnessInfo(effect, ConstantKind.stringConstant);
+    return true;
   }
 
   @override
   visitStaticInvocation(StaticInvocation node) {
-    // TODO(dmitryas): Handle this case better.
     Member target = node.target;
-    if (target.name == identicalName) {
-      final TreeNode parent = target.parent;
-      if (parent is Library && parent == coreTypes.coreLibrary) {
-        assert(node.arguments.positional.length == 2);
-        ConstnessEffect effect = minConstnessEffectOnPair(
-            node.arguments.positional[0].accept(this).effect,
-            node.arguments.positional[1].accept(this).effect);
-        if (effect == ConstnessEffect.decidedNew) {
-          return const ConstnessInfo.decidedNew();
+    if (target is Procedure) {
+      if (target.isConst && target.isFactory) {
+        for (var type in node.arguments.types) {
+          if (!type.accept(this)) return false;
         }
-        return new ConstnessInfo(effect, ConstantKind.boolConstant);
+        for (var expression in node.arguments.positional) {
+          if (!expression.accept(this)) return false;
+        }
+        for (var namedExpression in node.arguments.named) {
+          if (!namedExpression.value.accept(this)) return false;
+        }
+        return true;
+      } else if (target.name == identicalName) {
+        final TreeNode parent = target.parent;
+        if (parent is Library && parent == coreTypes.coreLibrary) {
+          assert(node.arguments.positional.length == 2);
+          return node.arguments.positional[0].accept(this) &&
+              node.arguments.positional[1].accept(this);
+        }
       }
     }
-    return const ConstnessInfo.taintedConst(null);
+    return false;
   }
 
   @override
   visitAsExpression(AsExpression node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
+    return node.operand.accept(this) && node.type.accept(this);
   }
 
   @override
@@ -402,265 +293,131 @@
   }
 
   @override
-  visitInvalidExpression(InvalidExpression node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitInvalidExpression(InvalidExpression node) => false;
 
   @override
-  visitVariableSet(VariableSet node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitVariableSet(VariableSet node) => false;
 
   @override
-  visitPropertySet(PropertySet node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitPropertySet(PropertySet node) => false;
 
   @override
   visitDirectPropertyGet(DirectPropertyGet node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
+    if (!isConstantPropertyName(node.target.name)) return false;
+    return node.receiver.accept(this);
   }
 
   @override
-  visitDirectPropertySet(DirectPropertySet node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitDirectPropertySet(DirectPropertySet node) => false;
 
   @override
-  visitSuperPropertyGet(SuperPropertyGet node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitSuperPropertyGet(SuperPropertyGet node) => false;
 
   @override
-  visitSuperPropertySet(SuperPropertySet node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitSuperPropertySet(SuperPropertySet node) => false;
 
   @override
-  visitStaticSet(StaticSet node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitStaticSet(StaticSet node) => false;
 
   @override
   visitDirectMethodInvocation(DirectMethodInvocation node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
+    if (node.arguments.named.isNotEmpty ||
+        node.arguments.types.isNotEmpty ||
+        !isConstantMethodName(node.name, node.arguments.positional.length)) {
+      return false;
+    }
+
+    if (!node.receiver.accept(this)) return false;
+    for (var expression in node.arguments.positional) {
+      if (!expression.accept(this)) return false;
+    }
+
+    return true;
   }
 
   @override
-  visitSuperMethodInvocation(SuperMethodInvocation node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitSuperMethodInvocation(SuperMethodInvocation node) => false;
 
   @override
   visitIsExpression(IsExpression node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
+    return node.operand.accept(this) && node.type.accept(this);
   }
 
   @override
-  visitThisExpression(ThisExpression node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitThisExpression(ThisExpression node) => false;
 
   @override
-  visitRethrow(Rethrow node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitRethrow(Rethrow node) => false;
 
   @override
-  visitThrow(Throw node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitThrow(Throw node) => false;
 
   @override
-  visitAwaitExpression(AwaitExpression node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitAwaitExpression(AwaitExpression node) => false;
 
   @override
-  visitFunctionExpression(FunctionExpression node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitFunctionExpression(FunctionExpression node) => false;
 
   @override
-  visitConstantExpression(ConstantExpression node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitConstantExpression(ConstantExpression node) => true;
 
   @override
-  visitInstantiation(Instantiation node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitInstantiation(Instantiation node) => false;
 
   @override
-  visitLoadLibrary(LoadLibrary node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitLoadLibrary(LoadLibrary node) => false;
 
   @override
-  visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) => false;
 
   @override
-  visitVectorCreation(VectorCreation node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitVectorCreation(VectorCreation node) => false;
 
   @override
-  visitVectorGet(VectorGet node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitVectorGet(VectorGet node) => false;
 
   @override
-  visitVectorSet(VectorSet node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitVectorSet(VectorSet node) => false;
 
   @override
-  visitVectorCopy(VectorCopy node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
+  visitVectorCopy(VectorCopy node) => false;
 
   @override
-  visitClosureCreation(ClosureCreation node) {
-    // TODO(dmitryas): Handle this case.
-    return const ConstnessInfo.taintedConst(null);
-  }
-
-  /// Tells the minimum constness effect assuming the following:
-  ///   * [ConstnessEffect.allowedConst] > [ConstnessEffect.taintedConst]
-  ///   * [ConstnessEffect.taintedConst] > [ConstnessEffect.decidedNew]
-  static ConstnessEffect minConstnessEffectOnPair(
-      ConstnessEffect x, ConstnessEffect y) {
-    if (x == ConstnessEffect.decidedNew) {
-      return x;
-    }
-    if (x == ConstnessEffect.allowedConst) {
-      return y;
-    }
-    // x == ConstnessEffect.taintedConst.
-    if (y == ConstnessEffect.decidedNew) {
-      return y;
-    }
-    return x;
-  }
-
-  /// Calculates minimum constness effect in [effects] using
-  /// [minConstnessEffectOnPair].  Returns null if [effects] is null or empty.
-  static ConstnessEffect minConstnessEffect(Iterable<ConstnessEffect> effects) {
-    if (effects == null || effects.isEmpty) return null;
-
-    ConstnessEffect result = ConstnessEffect.allowedConst;
-    for (ConstnessEffect effect in effects) {
-      result = minConstnessEffectOnPair(result, effect);
-    }
-    return result;
-  }
-
-  /// Calculates minimum constness effect in [infos] using
-  /// [minConstnessEffectOnPair].  Returns null if [infos] is null or empty.
-  static ConstnessEffect minConstnessEffectOnInfos(
-      Iterable<ConstnessInfo> infos) {
-    if (infos == null || infos.isEmpty) return null;
-
-    ConstnessEffect result = ConstnessEffect.allowedConst;
-    for (ConstnessInfo info in infos) {
-      result = minConstnessEffectOnPair(result, info.effect);
-    }
-    return result;
-  }
+  visitClosureCreation(ClosureCreation node) => false;
 
   /// Returns null if `receiver.name(arguments)` is not a constant.
-  static ConstantKind evaluateConstantMethodInvocationKind(
-      ConstantKind receiver, Name name, List<ConstantKind> arguments) {
-    if (receiver == ConstantKind.stringConstant) {
-      if (arguments.length == 1) {
-        if (arguments[0] == ConstantKind.stringConstant) {
-          if (name == plusName) return ConstantKind.intConstant;
-        }
-      }
-    } else if (receiver == ConstantKind.boolConstant) {
-      if (arguments.length == 1) {
-        if (name == negationName) return ConstantKind.boolConstant;
-      } else if (arguments.length == 2) {
-        // TODO(dmitryas): Figure out if `&&` and `||` can be methods.
-      }
-    } else if (receiver == ConstantKind.intConstant) {
-      if (arguments.length == 0) {
-        if (name == unaryMinusName) return ConstantKind.intConstant;
-        if (name == tildaName) return ConstantKind.intConstant;
-      } else if (arguments.length == 1) {
-        if (arguments[0] == ConstantKind.intConstant) {
-          if (name == barName) return ConstantKind.intConstant;
-          if (name == ampersandName) return ConstantKind.intConstant;
-          if (name == caretName) return ConstantKind.intConstant;
-          if (name == leftShiftName) return ConstantKind.intConstant;
-          if (name == rightShiftName) return ConstantKind.intConstant;
-        }
-        if (arguments[0] == ConstantKind.intConstant ||
-            arguments[0] == ConstantKind.doubleConstant) {
-          if (name == plusName) return arguments[0];
-          if (name == minusName) return arguments[0];
-          if (name == multiplyName) return arguments[0];
-          if (name == divisionName) return arguments[0];
-          if (name == mustacheName) return arguments[0];
-          if (name == percentName) return arguments[0];
-          if (name == lessThanName) return ConstantKind.boolConstant;
-          if (name == lessThanOrEqualsName) return ConstantKind.boolConstant;
-          if (name == greaterThanOrEqualsName) return ConstantKind.boolConstant;
-          if (name == greaterThanName) return ConstantKind.boolConstant;
-        }
-      }
-    } else if (receiver == ConstantKind.doubleConstant) {
-      if (arguments.length == 0) {
-        if (name == unaryMinusName) return ConstantKind.doubleConstant;
-      } else if (arguments.length == 1) {
-        if (arguments[0] == ConstantKind.intConstant ||
-            arguments[0] == ConstantKind.doubleConstant) {
-          if (name == plusName) return ConstantKind.doubleConstant;
-          if (name == minusName) return ConstantKind.doubleConstant;
-          if (name == multiplyName) return ConstantKind.doubleConstant;
-          if (name == divisionName) return ConstantKind.doubleConstant;
-          if (name == mustacheName) return ConstantKind.doubleConstant;
-          if (name == percentName) return ConstantKind.doubleConstant;
-          if (name == lessThanName) return ConstantKind.boolConstant;
-          if (name == lessThanOrEqualsName) return ConstantKind.boolConstant;
-          if (name == greaterThanOrEqualsName) return ConstantKind.boolConstant;
-          if (name == greaterThanName) return ConstantKind.boolConstant;
-        }
-      }
+  static bool isConstantMethodName(Name name, int argumentCount) {
+    if (argumentCount == 0) {
+      if (name == tildeName) return true;
+      if (name == unaryMinusName) return true;
+    } else if (argumentCount == 1) {
+      if (name == ampersandName) return true;
+      if (name == barName) return true;
+      if (name == caretName) return true;
+      if (name == divisionName) return true;
+      if (name == equalsName) return true;
+      if (name == greaterThanName) return true;
+      if (name == greaterThanOrEqualsName) return true;
+      if (name == leftShiftName) return true;
+      if (name == lessThanName) return true;
+      if (name == lessThanOrEqualsName) return true;
+      if (name == minusName) return true;
+      if (name == multiplyName) return true;
+      if (name == mustacheName) return true;
+      if (name == negationName) return true;
+      if (name == percentName) return true;
+      if (name == plusName) return true;
+      if (name == rightShiftName) return true;
     }
+    return false;
+  }
 
-    return null;
+  static bool isConstantPropertyName(Name name) {
+    return name == lengthName;
   }
 }
 
 // TODO(32717): Remove this helper function when the issue is resolved.
-ConstnessInfo evaluateConstness(
-    Expression expression, CoreTypes coreTypes, Uri uri) {
+bool evaluateConstness(Expression expression, CoreTypes coreTypes, Uri uri) {
   return new ConstnessEvaluator(coreTypes, uri).evaluate(expression);
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index 2798fb5a..be422f2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -419,10 +419,12 @@
               "${interfaceMember.name.name}"),
           declaredMember.fileOffset,
           noLength,
-          context: templateOverriddenMethodCause
-              .withArguments(interfaceMember.name.name)
-              .withLocation(_getMemberUri(interfaceMember),
-                  interfaceMember.fileOffset, noLength));
+          context: [
+            templateOverriddenMethodCause
+                .withArguments(interfaceMember.name.name)
+                .withLocation(_getMemberUri(interfaceMember),
+                    interfaceMember.fileOffset, noLength)
+          ]);
     } else if (library.loader.target.backendTarget.strongMode &&
         declaredFunction?.typeParameters != null) {
       var substitution = <TypeParameter, DartType>{};
@@ -482,10 +484,12 @@
         fileOffset = declaredParameter.fileOffset;
       }
       library.addCompileTimeError(message, fileOffset, noLength, fileUri,
-          context: templateOverriddenMethodCause
-              .withArguments(interfaceMember.name.name)
-              .withLocation(_getMemberUri(interfaceMember),
-                  interfaceMember.fileOffset, noLength));
+          context: [
+            templateOverriddenMethodCause
+                .withArguments(interfaceMember.name.name)
+                .withLocation(_getMemberUri(interfaceMember),
+                    interfaceMember.fileOffset, noLength)
+          ]);
       return true;
     }
     return false;
@@ -533,10 +537,12 @@
               "${interfaceMember.name.name}"),
           declaredMember.fileOffset,
           noLength,
-          context: templateOverriddenMethodCause
-              .withArguments(interfaceMember.name.name)
-              .withLocation(interfaceMember.fileUri, interfaceMember.fileOffset,
-                  noLength));
+          context: [
+            templateOverriddenMethodCause
+                .withArguments(interfaceMember.name.name)
+                .withLocation(interfaceMember.fileUri,
+                    interfaceMember.fileOffset, noLength)
+          ]);
     }
     if (interfaceFunction.requiredParameterCount <
         declaredFunction.requiredParameterCount) {
@@ -547,10 +553,12 @@
               "${interfaceMember.name.name}"),
           declaredMember.fileOffset,
           noLength,
-          context: templateOverriddenMethodCause
-              .withArguments(interfaceMember.name.name)
-              .withLocation(interfaceMember.fileUri, interfaceMember.fileOffset,
-                  noLength));
+          context: [
+            templateOverriddenMethodCause
+                .withArguments(interfaceMember.name.name)
+                .withLocation(interfaceMember.fileUri,
+                    interfaceMember.fileOffset, noLength)
+          ]);
     }
     for (int i = 0;
         i < declaredFunction.positionalParameters.length &&
@@ -580,10 +588,12 @@
               "${interfaceMember.name.name}"),
           declaredMember.fileOffset,
           noLength,
-          context: templateOverriddenMethodCause
-              .withArguments(interfaceMember.name.name)
-              .withLocation(interfaceMember.fileUri, interfaceMember.fileOffset,
-                  noLength));
+          context: [
+            templateOverriddenMethodCause
+                .withArguments(interfaceMember.name.name)
+                .withLocation(interfaceMember.fileUri,
+                    interfaceMember.fileOffset, noLength)
+          ]);
     }
     int compareNamedParameters(VariableDeclaration p0, VariableDeclaration p1) {
       return p0.name.compareTo(p1.name);
@@ -613,10 +623,12 @@
                   "${interfaceMember.name.name}"),
               declaredMember.fileOffset,
               noLength,
-              context: templateOverriddenMethodCause
-                  .withArguments(interfaceMember.name.name)
-                  .withLocation(interfaceMember.fileUri,
-                      interfaceMember.fileOffset, noLength));
+              context: [
+                templateOverriddenMethodCause
+                    .withArguments(interfaceMember.name.name)
+                    .withLocation(interfaceMember.fileUri,
+                        interfaceMember.fileOffset, noLength)
+              ]);
           break outer;
         }
       }
@@ -711,10 +723,10 @@
       int originLength = typeVariables?.length ?? 0;
       int patchLength = patch.typeVariables?.length ?? 0;
       if (originLength != patchLength) {
-        patch.addCompileTimeError(
-            messagePatchClassTypeVariablesMismatch, patch.charOffset, noLength,
-            context: messagePatchClassOrigin.withLocation(
-                fileUri, charOffset, noLength));
+        patch.addCompileTimeError(messagePatchClassTypeVariablesMismatch,
+            patch.charOffset, noLength, context: [
+          messagePatchClassOrigin.withLocation(fileUri, charOffset, noLength)
+        ]);
       } else if (typeVariables != null) {
         int count = 0;
         for (KernelTypeVariableBuilder t in patch.typeVariables) {
@@ -723,9 +735,10 @@
       }
     } else {
       library.addCompileTimeError(messagePatchDeclarationMismatch,
-          patch.charOffset, noLength, patch.fileUri,
-          context: messagePatchDeclarationOrigin.withLocation(
-              fileUri, charOffset, noLength));
+          patch.charOffset, noLength, patch.fileUri, context: [
+        messagePatchDeclarationOrigin.withLocation(
+            fileUri, charOffset, noLength)
+      ]);
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 5bd9437..2d41321 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -201,8 +201,10 @@
               templateConflictsWithTypeVariable.withArguments(name),
               member.charOffset,
               name.length,
-              context: messageConflictsWithTypeVariableCause.withLocation(
-                  tv.fileUri, tv.charOffset, name.length));
+              context: [
+                messageConflictsWithTypeVariableCause.withLocation(
+                    tv.fileUri, tv.charOffset, name.length)
+              ]);
         }
       }
       setParent(name, member);
@@ -226,10 +228,12 @@
       if (existing != null) {
         addCompileTimeError(messageTypeVariableDuplicatedName, tv.charOffset,
             tv.name.length, fileUri,
-            context: templateTypeVariableDuplicatedNameCause
-                .withArguments(tv.name)
-                .withLocation(
-                    fileUri, existing.charOffset, existing.name.length));
+            context: [
+              templateTypeVariableDuplicatedNameCause
+                  .withArguments(tv.name)
+                  .withLocation(
+                      fileUri, existing.charOffset, existing.name.length)
+            ]);
       } else {
         typeVariablesByName[tv.name] = tv;
         if (owner is ClassBuilder) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
index e239fa77..ed62a8a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
@@ -235,8 +235,10 @@
     if (!isExternal) {
       patch.library.addCompileTimeError(
           messagePatchNonExternal, patch.charOffset, noLength, patch.fileUri,
-          context: messagePatchDeclarationOrigin.withLocation(
-              fileUri, charOffset, noLength));
+          context: [
+            messagePatchDeclarationOrigin.withLocation(
+                fileUri, charOffset, noLength)
+          ]);
       return false;
     }
     return true;
@@ -244,9 +246,9 @@
 
   void reportPatchMismatch(Builder patch) {
     library.addCompileTimeError(messagePatchDeclarationMismatch,
-        patch.charOffset, noLength, patch.fileUri,
-        context: messagePatchDeclarationOrigin.withLocation(
-            fileUri, charOffset, noLength));
+        patch.charOffset, noLength, patch.fileUri, context: [
+      messagePatchDeclarationOrigin.withLocation(fileUri, charOffset, noLength)
+    ]);
   }
 }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 1eff9b7..cfeaeab 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -661,15 +661,11 @@
         fieldInitializers[constructor] = myFieldInitializers;
         if (constructor.isConst && nonFinalFields.isNotEmpty) {
           builder.addCompileTimeError(messageConstConstructorNonFinalField,
-              constructor.fileOffset, noLength);
-          // TODO(askesc): Put as context argument when multiple contexts
-          // are supported.
-          for (Field field in nonFinalFields) {
-            builder.addCompileTimeError(
-                messageConstConstructorNonFinalFieldCause,
-                field.fileOffset,
-                noLength);
-          }
+              constructor.fileOffset, noLength,
+              context: nonFinalFields
+                  .map((field) => messageConstConstructorNonFinalFieldCause
+                      .withLocation(field.fileUri, field.fileOffset, noLength))
+                  .toList());
           nonFinalFields.clear();
         }
       }
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index d14ac1e..ac10060 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -20,6 +20,7 @@
         SummaryTemplate,
         Template,
         messagePlatformPrivateLibraryAccess,
+        templateInternalProblemContextSeverity,
         templateInternalProblemMissingSeverity,
         templateSourceBodySummary;
 
@@ -201,7 +202,7 @@
   /// otherwise it is added to [unhandledErrors].
   void addCompileTimeError(
       Message message, int charOffset, int length, Uri fileUri,
-      {bool wasHandled: false, LocatedMessage context}) {
+      {bool wasHandled: false, List<LocatedMessage> context}) {
     addMessage(message, charOffset, length, fileUri, Severity.error,
         wasHandled: wasHandled, context: context);
   }
@@ -209,7 +210,7 @@
   /// Register [message] as a problem with a severity determined by the
   /// intrinsic severity of the message.
   void addProblem(Message message, int charOffset, int length, Uri fileUri,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     Severity severity = message.code.severity;
     if (severity == null) {
       addMessage(message, charOffset, length, fileUri, Severity.error,
@@ -236,7 +237,7 @@
   /// three times by `OutlineBuilder`, `DietListener`, and `BodyBuilder`.
   bool addMessage(Message message, int charOffset, int length, Uri fileUri,
       Severity severity,
-      {bool wasHandled: false, LocatedMessage context}) {
+      {bool wasHandled: false, List<LocatedMessage> context}) {
     String trace = """
 message: ${message.message}
 charOffset: $charOffset
@@ -244,11 +245,16 @@
 severity: $severity
 """;
     if (!seenMessages.add(trace)) return false;
-    target.context
-        .report(message.withLocation(fileUri, charOffset, length), severity);
-    if (context != null) {
-      target.context.report(context, Severity.context);
+    if (message.code.severity == Severity.context) {
+      internalProblem(
+          templateInternalProblemContextSeverity
+              .withArguments(message.code.name),
+          charOffset,
+          fileUri);
     }
+    target.context.report(
+        message.withLocation(fileUri, charOffset, length), severity,
+        context: context);
     recordMessage(severity, message, charOffset, length, fileUri,
         context: context);
     if (severity == Severity.error) {
@@ -272,7 +278,7 @@
 
   void recordMessage(Severity severity, Message message, int charOffset,
       int length, Uri fileUri,
-      {LocatedMessage context}) {}
+      {List<LocatedMessage> context}) {}
 }
 
 String format(double d, int fractionDigits, int width) {
diff --git a/pkg/front_end/lib/src/fasta/names.dart b/pkg/front_end/lib/src/fasta/names.dart
index d58c171..ab5b774 100644
--- a/pkg/front_end/lib/src/fasta/names.dart
+++ b/pkg/front_end/lib/src/fasta/names.dart
@@ -60,6 +60,6 @@
 
 final Name rightShiftName = new Name(">>");
 
-final Name tildaName = new Name("~");
+final Name tildeName = new Name("~");
 
 final Name unaryMinusName = new Name("unary-");
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 353a654..6e9fb76 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -952,6 +952,16 @@
   }
 
   @override
+  void beginImplicitCreationExpression(Token token) {
+    listener?.beginImplicitCreationExpression(token);
+  }
+
+  @override
+  void endImplicitCreationExpression(Token token) {
+    listener?.endImplicitCreationExpression(token);
+  }
+
+  @override
   void handleEmptyStatement(Token token) {
     listener?.handleEmptyStatement(token);
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
index d53576c..c22e78d 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -126,10 +126,7 @@
       recoveryTemplate: templateExpectedType);
 
   /// Identifier is the start of a reference to a type declared elsewhere.
-  static const typeReference = const IdentifierContext('typeReference',
-      isScopeReference: true,
-      isBuiltInIdentifierAllowed: false,
-      recoveryTemplate: templateExpectedType);
+  static const typeReference = const TypeReferenceIdentifierContext();
 
   /// Identifier is part of a reference to a type declared elsewhere, but it's
   /// not the first identifier of the reference.
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index 3b096fb..92bb8c2 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -12,7 +12,8 @@
 
 import 'parser.dart' show Parser;
 
-import 'type_info.dart' show insertSyntheticIdentifierAfter;
+import 'type_info.dart'
+    show insertSyntheticIdentifierAfter, isValidTypeReference;
 
 import 'util.dart' show optional;
 
@@ -66,3 +67,72 @@
       optional('var', token) ||
       optional('void', token);
 }
+
+class TypeReferenceIdentifierContext extends IdentifierContext {
+  const TypeReferenceIdentifierContext()
+      : super('typeReference',
+            isScopeReference: true,
+            isBuiltInIdentifierAllowed: false,
+            recoveryTemplate: fasta.templateExpectedType);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token next = token.next;
+    assert(next.kind != IDENTIFIER_TOKEN);
+    if (isValidTypeReference(next)) {
+      return next;
+    }
+
+    // Recovery: skip over any annotations
+    while (optional('@', next)) {
+      // TODO(danrubel): Improve this error message to indicate that an
+      // annotation is not allowed before type arguments.
+      parser.reportRecoverableErrorWithToken(
+          next, fasta.templateUnexpectedToken);
+
+      Token annotation = next.next;
+      if (annotation.isIdentifier) {
+        if (optional('(', annotation.next)) {
+          if (annotation.next.endGroup.next.isIdentifier) {
+            token = annotation.next.endGroup;
+            next = token.next;
+          }
+        } else if (annotation.next.isIdentifier) {
+          token = annotation;
+          next = token.next;
+        }
+      }
+    }
+    if (isValidTypeReference(next)) {
+      return next;
+    } else if (next.isKeywordOrIdentifier) {
+      if (optional("void", next)) {
+        parser.reportRecoverableError(next, fasta.messageInvalidVoid);
+      } else if (next.type.isBuiltIn) {
+        parser.reportRecoverableErrorWithToken(
+            next, fasta.templateBuiltInIdentifierAsType);
+      } else {
+        parser.reportRecoverableErrorWithToken(
+            next, fasta.templateExpectedType);
+      }
+      return next;
+    }
+    parser.reportRecoverableErrorWithToken(next, fasta.templateExpectedType);
+    if (!isOneOfOrEof(next, ['>', ')', ']', '{', '}', ',', ';'])) {
+      // When in doubt, consume the token to ensure we make progress
+      token = next;
+      next = token.next;
+    }
+    // Insert a synthetic identifier to satisfy listeners.
+    return insertSyntheticIdentifierAfter(token, parser);
+  }
+}
+
+bool isOneOfOrEof(Token token, Iterable<String> followingValues) {
+  for (String tokenValue in followingValues) {
+    if (optional(tokenValue, token)) {
+      return true;
+    }
+  }
+  return token.isEof;
+}
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index e71259c..19ed1b1 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -516,6 +516,12 @@
     logEvent("DottedName");
   }
 
+  void beginImplicitCreationExpression(Token token) {}
+
+  void endImplicitCreationExpression(Token token) {
+    logEvent("ImplicitCreationExpression");
+  }
+
   void beginInitializedIdentifier(Token token) {}
 
   void endInitializedIdentifier(Token nameToken) {
diff --git a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
index 546501b..4b23332 100644
--- a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
@@ -46,12 +46,6 @@
   }
 }
 
-TypeContinuation typeContinuationFromMemberKind(
-        bool isVarAllowed, MemberKind memberKind) =>
-    (isVarAllowed || memberKind == MemberKind.GeneralizedFunctionType)
-        ? TypeContinuation.Required
-        : TypeContinuation.Optional;
-
 /// This class is used to parse modifiers in most locations where modifiers
 /// can occur. However, it isn't used when parsing a class or when parsing
 /// the modifiers of a member function (non-local),
@@ -211,7 +205,6 @@
 /// but does not call handleModifier or handleModifiers.
 class ModifierRecoveryContext2 {
   final Parser parser;
-  TypeContinuation typeContinuation;
   Token abstractToken;
   Token constToken;
   Token covariantToken;
@@ -230,13 +223,12 @@
   ModifierRecoveryContext2(this.parser);
 
   /// Parse modifiers for class methods and fields.
-  Token parseClassMemberModifiers(
-      Token token, TypeContinuation typeContinuation,
+  Token parseClassMemberModifiers(Token token,
       {Token externalToken,
       Token staticToken,
       Token covariantToken,
       Token varFinalOrConst}) {
-    token = parseModifiers(token, typeContinuation,
+    token = parseModifiers(token,
         externalToken: externalToken,
         staticToken: staticToken,
         covariantToken: covariantToken,
@@ -253,7 +245,7 @@
   Token parseModifiersAfterFactory(Token token,
       {Token externalToken, Token staticOrCovariant, Token varFinalOrConst}) {
     afterFactory = true;
-    token = parseModifiers(token, null,
+    token = parseModifiers(token,
         externalToken: externalToken,
         staticOrCovariant: staticOrCovariant,
         varFinalOrConst: varFinalOrConst);
@@ -266,9 +258,9 @@
   }
 
   /// Parse modifiers for top level functions and fields.
-  Token parseTopLevelModifiers(Token token, TypeContinuation typeContinuation,
+  Token parseTopLevelModifiers(Token token,
       {Token externalToken, Token varFinalOrConst}) {
-    token = parseModifiers(token, typeContinuation,
+    token = parseModifiers(token,
         externalToken: externalToken, varFinalOrConst: varFinalOrConst);
 
     reportExtraneousModifier(abstractToken);
@@ -280,7 +272,7 @@
   /// Parse modifiers for variable declarations.
   Token parseVariableDeclarationModifiers(Token token,
       {Token varFinalOrConst}) {
-    token = parseModifiers(token, null, varFinalOrConst: varFinalOrConst);
+    token = parseModifiers(token, varFinalOrConst: varFinalOrConst);
 
     reportExtraneousModifier(abstractToken);
     reportExtraneousModifier(covariantToken);
@@ -300,13 +292,12 @@
   /// `static` or `covariant`. The first non-null parameter of
   /// [staticOrCovariant], [staticToken], or [covariantToken] will be used,
   /// in that order, and the others ignored.
-  Token parseModifiers(Token token, TypeContinuation typeContinuation,
+  Token parseModifiers(Token token,
       {Token externalToken,
       Token staticToken,
       Token staticOrCovariant,
       Token covariantToken,
       Token varFinalOrConst}) {
-    this.typeContinuation = typeContinuation;
     if (externalToken != null) {
       this.externalToken = externalToken;
     }
@@ -390,7 +381,6 @@
     Token next = token.next;
     assert(optional('const', next));
     if (varFinalOrConst == null && covariantToken == null) {
-      typeContinuation ??= TypeContinuation.Optional;
       varFinalOrConst = constToken = next;
 
       if (afterFactory) {
@@ -474,7 +464,6 @@
     Token next = token.next;
     assert(optional('final', next));
     if (varFinalOrConst == null && !afterFactory) {
-      typeContinuation ??= TypeContinuation.Optional;
       varFinalOrConst = finalToken = next;
       return next;
     }
@@ -529,7 +518,6 @@
     Token next = token.next;
     assert(optional('var', next));
     if (varFinalOrConst == null && !afterFactory) {
-      typeContinuation = typeContinuationAfterVar(typeContinuation);
       varFinalOrConst = varToken = next;
       return next;
     }
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index f53eba3..f282ad6 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -1843,10 +1843,7 @@
     // ensureIdentifier methods in the various IdentifierContext subclasses.
 
     if (!next.isIdentifier) {
-      if (optional("void", next)) {
-        reportRecoverableError(next, fasta.messageInvalidVoid);
-        token = next;
-      } else if (next is ErrorToken) {
+      if (next is ErrorToken) {
         // TODO(brianwilkerson): This preserves the current semantics, but the
         // listener should not be recovering from this case, so this needs to be
         // reworked to recover in this method (probably inside the outermost
@@ -1898,13 +1895,8 @@
         reportRecoverableErrorWithToken(
             next, fasta.templateBuiltInIdentifierInDeclaration);
       } else if (!optional("dynamic", next)) {
-        if (context == IdentifierContext.typeReference &&
-            optional('.', next.next)) {
-          // Built in identifiers may be used as a prefix
-        } else {
-          reportRecoverableErrorWithToken(
-              next, fasta.templateBuiltInIdentifierAsType);
-        }
+        reportRecoverableErrorWithToken(
+            next, fasta.templateBuiltInIdentifierAsType);
       }
       token = next;
     } else if (!inPlainSync && next.type.isPseudo) {
@@ -2016,8 +2008,7 @@
       followingValues = [';', '=', ','];
     } else if (context == IdentifierContext.typedefDeclaration) {
       followingValues = ['(', '<', ';'];
-    } else if (context == IdentifierContext.typeReference ||
-        context == IdentifierContext.typeReferenceContinuation) {
+    } else if (context == IdentifierContext.typeReferenceContinuation) {
       followingValues = ['>', ')', ']', '}', ',', ';'];
     } else if (context == IdentifierContext.typeVariableDeclaration) {
       followingValues = ['<', '>', ';', '}'];
@@ -2748,7 +2739,6 @@
 
     Token externalToken;
     Token varFinalOrConst;
-    TypeContinuation typeContinuation;
 
     if (isModifier(next)) {
       if (optional('external', next)) {
@@ -2757,32 +2747,27 @@
       }
       if (isModifier(next)) {
         if (optional('final', next)) {
-          typeContinuation = TypeContinuation.Optional;
           varFinalOrConst = token = next;
           next = token.next;
         } else if (optional('var', next)) {
-          typeContinuation = TypeContinuation.OptionalAfterVar;
           varFinalOrConst = token = next;
           next = token.next;
         } else if (optional('const', next)) {
-          typeContinuation = TypeContinuation.Optional;
           varFinalOrConst = token = next;
           next = token.next;
         }
         if (isModifier(next)) {
           ModifierRecoveryContext2 context = new ModifierRecoveryContext2(this);
-          token = context.parseTopLevelModifiers(token, typeContinuation,
+          token = context.parseTopLevelModifiers(token,
               externalToken: externalToken, varFinalOrConst: varFinalOrConst);
           next = token.next;
 
-          typeContinuation = context.typeContinuation;
           externalToken = context.externalToken;
           varFinalOrConst = context.varFinalOrConst;
           context = null;
         }
       }
     }
-    typeContinuation ??= TypeContinuation.Required;
 
     Token beforeType = token;
     TypeInfo typeInfo = computeType(token, false);
@@ -2878,12 +2863,8 @@
       reportRecoverableErrorWithToken(
           getOrSet, fasta.templateExtraneousModifier);
     }
-    // TODO(danrubel): Use typeInfo when parsing fields.
-    if (typeInfo == noTypeInfo) {
-      beforeType = null;
-    }
     return parseFields(beforeStart, externalToken, null, null, varFinalOrConst,
-        beforeType, token, MemberKind.TopLevelField, typeContinuation);
+        beforeType, typeInfo, token, true);
   }
 
   Token parseFields(
@@ -2893,9 +2874,9 @@
       Token covariantToken,
       Token varFinalOrConst,
       Token beforeType,
+      TypeInfo typeInfo,
       Token beforeName,
-      MemberKind memberKind,
-      TypeContinuation typeContinuation) {
+      bool isTopLevel) {
     if (externalToken != null) {
       reportRecoverableError(externalToken, fasta.messageExternalField);
     }
@@ -2905,20 +2886,19 @@
         covariantToken = null;
       }
     }
-
-    bool isTopLevel = memberKind == MemberKind.TopLevelField;
-
-    if (beforeType != null) {
-      parseType(beforeType, typeContinuation, null, memberKind);
-    } else if (varFinalOrConst != null) {
-      listener.handleNoType(beforeName);
+    if (typeInfo == noTypeInfo) {
+      if (varFinalOrConst == null) {
+        reportRecoverableError(
+            beforeName.next, fasta.messageMissingConstFinalVarOrType);
+      }
     } else {
-      // Recovery
-      reportRecoverableError(
-          beforeName.next, fasta.messageMissingConstFinalVarOrType);
-      listener.handleNoType(beforeName);
+      if (varFinalOrConst != null && optional('var', varFinalOrConst)) {
+        reportRecoverableError(varFinalOrConst, fasta.messageTypeAfterVar);
+      }
     }
 
+    typeInfo.parseType(beforeType, this);
+
     IdentifierContext context = isTopLevel
         ? IdentifierContext.topLevelVariableDeclaration
         : IdentifierContext.fieldDeclaration;
@@ -3432,7 +3412,6 @@
   Token parseClassMemberImpl(Token token) {
     Token beforeStart = token = parseMetadataStar(token);
 
-    TypeContinuation typeContinuation;
     Token covariantToken;
     Token externalToken;
     Token staticToken;
@@ -3454,22 +3433,19 @@
         }
         if (isModifier(next)) {
           if (optional('final', next)) {
-            typeContinuation = TypeContinuation.Optional;
             varFinalOrConst = token = next;
             next = token.next;
           } else if (optional('var', next)) {
-            typeContinuation = TypeContinuation.OptionalAfterVar;
             varFinalOrConst = token = next;
             next = token.next;
           } else if (optional('const', next) && covariantToken == null) {
-            typeContinuation = TypeContinuation.Optional;
             varFinalOrConst = token = next;
             next = token.next;
           }
           if (isModifier(next)) {
             ModifierRecoveryContext2 context =
                 new ModifierRecoveryContext2(this);
-            token = context.parseClassMemberModifiers(token, typeContinuation,
+            token = context.parseClassMemberModifiers(token,
                 externalToken: externalToken,
                 staticToken: staticToken,
                 covariantToken: covariantToken,
@@ -3481,13 +3457,11 @@
             staticToken = context.staticToken;
             varFinalOrConst = context.varFinalOrConst;
 
-            typeContinuation = context.typeContinuation;
             context = null;
           }
         }
       }
     }
-    typeContinuation ??= TypeContinuation.Required;
 
     listener.beginMember();
 
@@ -3567,8 +3541,7 @@
             varFinalOrConst,
             beforeType,
             typeInfo,
-            getOrSet,
-            typeContinuation);
+            getOrSet);
       }
     } else if (typeInfo == noTypeInfo && varFinalOrConst == null) {
       Token next2 = next.next;
@@ -3608,22 +3581,8 @@
         reportRecoverableErrorWithToken(
             getOrSet, fasta.templateExtraneousModifier);
       }
-      // TODO(danrubel): Use typeInfo when parsing fields.
-      if (typeInfo == noTypeInfo) {
-        beforeType = null;
-      }
-      token = parseFields(
-          beforeStart,
-          externalToken,
-          staticToken,
-          covariantToken,
-          varFinalOrConst,
-          beforeType,
-          token,
-          staticToken != null
-              ? MemberKind.StaticField
-              : MemberKind.NonStaticField,
-          typeContinuation);
+      token = parseFields(beforeStart, externalToken, staticToken,
+          covariantToken, varFinalOrConst, beforeType, typeInfo, token, false);
     }
     listener.endMember();
     return token;
@@ -4173,9 +4132,6 @@
       return parseForStatement(token, null);
     } else if (identical(value, 'rethrow')) {
       return parseRethrowStatement(token);
-    } else if (identical(value, 'throw') && optional(';', token.next.next)) {
-      // TODO(kasperl): Stop dealing with throw here.
-      return parseRethrowStatement(token);
     } else if (identical(value, 'while')) {
       return parseWhileStatement(token);
     } else if (identical(value, 'do')) {
@@ -4598,9 +4554,24 @@
           token.next, POSTFIX_PRECEDENCE, allowCascades);
       listener.handleUnaryPrefixAssignmentExpression(operator);
       return token;
-    } else {
-      return parsePrimary(token, IdentifierContext.expression);
+    } else if (token.next.isIdentifier) {
+      Token identifier = token.next;
+      if (optional(".", identifier.next)) {
+        identifier = identifier.next.next;
+      }
+      if (identifier.isIdentifier) {
+        // Looking at `identifier ('.' identifier)?`.
+        if (optional("<", identifier.next)) {
+          BeginToken typeArguments = identifier.next;
+          Token endTypeArguments = typeArguments.endGroup;
+          if (endTypeArguments != null &&
+              optional(".", endTypeArguments.next)) {
+            return parseImplicitCreationExpression(token);
+          }
+        }
+      }
     }
+    return parsePrimary(token, IdentifierContext.expression);
   }
 
   Token parseArgumentOrIndexStar(Token token, Token typeArguments) {
@@ -5013,6 +4984,15 @@
     return token;
   }
 
+  Token parseImplicitCreationExpression(Token token) {
+    Token begin = token;
+    listener.beginImplicitCreationExpression(token);
+    token = parseConstructorReference(token);
+    token = parseRequiredArguments(token);
+    listener.endImplicitCreationExpression(begin);
+    return token;
+  }
+
   /// This method parses a list or map literal that is known to start with the
   /// keyword 'const'.
   ///
@@ -5883,6 +5863,17 @@
   Token parseThrowExpression(Token token, bool allowCascades) {
     Token throwToken = token.next;
     assert(optional('throw', throwToken));
+    if (optional(';', throwToken.next)) {
+      // TODO(danrubel): Find a better way to intercept the parseExpression
+      // recovery to generate this error message rather than explicitly
+      // checking the next token as we are doing here.
+      reportRecoverableError(
+          throwToken.next, fasta.messageMissingExpressionInThrow);
+      rewriter.insertTokenAfter(
+          throwToken,
+          new SyntheticStringToken(
+              TokenType.STRING, '""', throwToken.next.charOffset, 0));
+    }
     token = allowCascades
         ? parseExpression(throwToken)
         : parseExpressionWithoutCascade(throwToken);
@@ -5897,14 +5888,8 @@
   /// ```
   Token parseRethrowStatement(Token token) {
     Token throwToken = token.next;
-    assert(optional('rethrow', throwToken) || optional('throw', throwToken));
+    assert(optional('rethrow', throwToken));
     listener.beginRethrowStatement(throwToken);
-    // TODO(kasperl): Disallow throw here.
-    if (optional('throw', throwToken)) {
-      expect('throw', throwToken);
-    } else {
-      expect('rethrow', throwToken);
-    }
     token = ensureSemicolon(throwToken);
     listener.endRethrowStatement(throwToken, token);
     return token;
@@ -6351,8 +6336,7 @@
       Token varFinalOrConst,
       Token beforeType,
       TypeInfo typeInfo,
-      Token getOrSet,
-      TypeContinuation typeContinuation) {
+      Token getOrSet) {
     Token next = token.next;
     String value = next.stringValue;
 
@@ -6404,10 +6388,6 @@
             getOrSet,
             token);
       } else {
-        // TODO(danrubel): Use typeInfo when parsing fields.
-        if (typeInfo == noTypeInfo) {
-          beforeType = null;
-        }
         token = parseFields(
             beforeStart,
             externalToken,
@@ -6415,9 +6395,9 @@
             covariantToken,
             varFinalOrConst,
             beforeType,
+            typeInfo,
             token,
-            MemberKind.NonStaticField,
-            typeContinuation);
+            false);
       }
     }
 
diff --git a/pkg/front_end/lib/src/fasta/scanner/string_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/string_scanner.dart
index 5d86888..236b31e 100644
--- a/pkg/front_end/lib/src/fasta/scanner/string_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/string_scanner.dart
@@ -81,20 +81,3 @@
 
   bool atEndOfFile() => scanOffset >= string.length - 1;
 }
-
-/**
- * Scanner that creates tokens for a part of a larger [String], where the part
- * starts at the [baseOffset].
- */
-class SubStringScanner extends StringScanner {
-  final int baseOffset;
-
-  SubStringScanner(this.baseOffset, String string,
-      {bool includeComments: false})
-      : super(string, includeComments: includeComments);
-
-  @override
-  void beginToken() {
-    tokenStart = baseOffset + stringOffset;
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 36be86a..0bdf2dd 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -855,10 +855,12 @@
               templateDuplicatedParameterName.withArguments(formals[1].name),
               formals[1].charOffset,
               formals[1].name.length,
-              context: templateDuplicatedParameterNameCause
-                  .withArguments(formals[1].name)
-                  .withLocation(
-                      uri, formals[0].charOffset, formals[0].name.length));
+              context: [
+                templateDuplicatedParameterNameCause
+                    .withArguments(formals[1].name)
+                    .withLocation(
+                        uri, formals[0].charOffset, formals[0].name.length)
+              ]);
         }
       } else if (formals.length > 2) {
         Map<String, FormalParameterBuilder> seenNames =
@@ -869,11 +871,13 @@
             addCompileTimeError(
                 templateDuplicatedParameterName.withArguments(formal.name),
                 formal.charOffset,
-                formal.name.length);
-            addCompileTimeError(
-                templateDuplicatedParameterNameCause.withArguments(formal.name),
-                seenNames[formal.name].charOffset,
-                seenNames[formal.name].name.length);
+                formal.name.length,
+                context: [
+                  templateDuplicatedParameterNameCause
+                      .withArguments(formal.name)
+                      .withLocation(uri, seenNames[formal.name].charOffset,
+                          seenNames[formal.name].name.length)
+                ]);
           } else {
             seenNames[formal.name] = formal;
           }
@@ -1179,13 +1183,13 @@
 
   @override
   void addCompileTimeError(Message message, int charOffset, int length,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     library.addCompileTimeError(message, charOffset, length, uri,
         context: context);
   }
 
   void addProblem(Message message, int charOffset, int length,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     library.addProblem(message, charOffset, length, uri, context: context);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index c82040d..149991e 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -486,9 +486,11 @@
             deferred.charOffset,
             noLength,
             fileUri,
-            context: templateDeferredPrefixDuplicatedCause
-                .withArguments(name)
-                .withLocation(fileUri, other.charOffset, noLength));
+            context: [
+              templateDeferredPrefixDuplicatedCause
+                  .withArguments(name)
+                  .withLocation(fileUri, other.charOffset, noLength)
+            ]);
       }
       return existing
         ..exportScope.merge(builder.exportScope,
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index e3e168e..79676d4 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -527,10 +527,12 @@
                         .withArguments(builder.fullNameForErrors),
                     cls.charOffset,
                     noLength,
-                    context: templateIllegalMixinDueToConstructorsCause
-                        .withArguments(builder.fullNameForErrors)
-                        .withLocation(constructory.fileUri,
-                            constructory.charOffset, noLength));
+                    context: [
+                      templateIllegalMixinDueToConstructorsCause
+                          .withArguments(builder.fullNameForErrors)
+                          .withLocation(constructory.fileUri,
+                              constructory.charOffset, noLength)
+                    ]);
               }
             }
           }
@@ -761,7 +763,7 @@
 
   void recordMessage(Severity severity, Message message, int charOffset,
       int length, Uri fileUri,
-      {LocatedMessage context}) {
+      {List<LocatedMessage> context}) {
     if (instrumentation == null) return;
 
     if (charOffset == -1 &&
@@ -811,8 +813,13 @@
         // TODO(ahe): Should I add an InstrumentationValue for Message?
         new InstrumentationValueLiteral(message.code.name));
     if (context != null) {
-      instrumentation.record(context.uri, context.charOffset, "context",
-          new InstrumentationValueLiteral(context.code.name));
+      for (LocatedMessage contextMessage in context) {
+        instrumentation.record(
+            contextMessage.uri,
+            contextMessage.charOffset,
+            "context",
+            new InstrumentationValueLiteral(contextMessage.code.name));
+      }
     }
   }
 
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 795a7c7..dc8a017 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -277,6 +277,14 @@
   analyzerCode: EXPECTED_TYPE_NAME
   dart2jsCode: "*fatal*"
 
+MissingExpressionInThrow:
+  template: "Missing expression after 'throw'."
+  tip: "Add an expression after 'throw' or use 'rethrow' to throw a caught exception"
+  analyzerCode: MISSING_EXPRESSION_IN_THROW
+  dart2jsCode: "*fatal*"
+  statement:
+    - "throw;"
+
 MissingConstFinalVarOrType:
   template: "Variables must be declared using the keywords 'const', 'final', 'var' or a type name."
   tip: "Try adding the name of the type of the variable or the keyword 'var'."
@@ -1249,6 +1257,10 @@
   template: "Message code missing severity: #string"
   severity: INTERNAL_PROBLEM
 
+InternalProblemContextSeverity:
+  template: "Non-context message has context severity: #string"
+  severity: INTERNAL_PROBLEM
+
 InternalVerificationError:
   template: |
     Verification of the generated program failed:
@@ -2049,10 +2061,3 @@
   template: "Can't invoke the type '#type' because its declaration of `.call` is not a method."
   tip: "Change .call to a method or explicitly invoke .call."
   severity: ERROR
-
-# TODO(ahe): Remove this message when the underlying issue is fixed.
-CantDetermineConstness:
-  template: "The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here."
-  severity: ERROR
-  expression:
-    - "bool.fromEnvironment('fisk')"
diff --git a/pkg/front_end/test/fasta/assert_locations_test.dart b/pkg/front_end/test/fasta/assert_locations_test.dart
index a2e7355..e282b79 100644
--- a/pkg/front_end/test/fasta/assert_locations_test.dart
+++ b/pkg/front_end/test/fasta/assert_locations_test.dart
@@ -16,7 +16,7 @@
 
 import 'package:front_end/src/testing/compiler_common.dart' show compileScript;
 
-import 'package:front_end/src/fasta/fasta_codes.dart' show LocatedMessage;
+import 'package:front_end/src/fasta/fasta_codes.dart' show FormattedMessage;
 
 import 'package:front_end/src/fasta/severity.dart' show Severity;
 
@@ -137,9 +137,9 @@
   asyncTest(() async {
     Test test = generateTest();
     CompilerOptions options = new CompilerOptions()
-      ..onProblem = (LocatedMessage message, Severity severity,
-          String formatted, int line, int column) {
-        Expect.fail("Unexpected error: $formatted");
+      ..onProblem = (FormattedMessage message, Severity severity,
+          List<FormattedMessage> context) {
+        Expect.fail("Unexpected error: ${message.formatted}");
       }
       ..strongMode = true;
     Component p = await compileScript(test.source,
diff --git a/pkg/front_end/test/fasta/incremental_hello_test.dart b/pkg/front_end/test/fasta/incremental_hello_test.dart
index 7976f2d..f096675 100644
--- a/pkg/front_end/test/fasta/incremental_hello_test.dart
+++ b/pkg/front_end/test/fasta/incremental_hello_test.dart
@@ -21,16 +21,16 @@
 
 import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
 
-import 'package:front_end/src/fasta/fasta_codes.dart' show LocatedMessage;
+import 'package:front_end/src/fasta/fasta_codes.dart' show FormattedMessage;
 
 import 'package:front_end/src/fasta/incremental_compiler.dart'
     show IncrementalCompiler;
 
 import 'package:front_end/src/fasta/severity.dart' show Severity;
 
-void problemHandler(LocatedMessage message, Severity severity, String formatted,
-    int line, int column) {
-  throw "Unexpected message: $formatted";
+void problemHandler(FormattedMessage message, Severity severity,
+    List<FormattedMessage> context) {
+  throw "Unexpected message: ${message.formatted}";
 }
 
 test({bool sdkFromSource}) async {
diff --git a/pkg/front_end/test/fasta/messages_test.dart b/pkg/front_end/test/fasta/messages_test.dart
index 9386d6e..279bc8a 100644
--- a/pkg/front_end/test/fasta/messages_test.dart
+++ b/pkg/front_end/test/fasta/messages_test.dart
@@ -24,7 +24,7 @@
 import 'package:front_end/src/compute_platform_binaries_location.dart'
     show computePlatformBinariesLocation;
 
-import 'package:front_end/src/fasta/fasta_codes.dart' show LocatedMessage;
+import 'package:front_end/src/fasta/fasta_codes.dart' show FormattedMessage;
 
 import 'package:front_end/src/fasta/severity.dart'
     show Severity, severityEnumValues;
@@ -255,9 +255,9 @@
       ..write(message);
     buffer.write("\n${span.text}");
     for (List problem in problems) {
-      LocatedMessage messsage = problem[0];
-      String formatted = problem[2];
-      buffer.write("\nCode: ${messsage.code.name}");
+      FormattedMessage message = problem[0];
+      String formatted = message.formatted;
+      buffer.write("\nCode: ${message.code.name}");
       buffer.write("\n  > ");
       buffer.write(formatted.replaceAll("\n", "\n  > "));
     }
@@ -402,9 +402,9 @@
           ..sdkSummary = computePlatformBinariesLocation()
               .resolve("vm_platform_strong.dill")
           ..fileSystem = new HybridFileSystem(suite.fileSystem)
-          ..onProblem = (LocatedMessage problem, Severity severity,
-              String formatted, int line, int column) {
-            problems.add([problem, severity, formatted, line, column]);
+          ..onProblem = (FormattedMessage problem, Severity severity,
+              List<FormattedMessage> context) {
+            problems.add([problem, severity]);
           }
           ..strongMode = true,
         uri,
@@ -412,7 +412,7 @@
 
     List<List> unexpectedProblems = <List>[];
     for (List problem in problems) {
-      LocatedMessage message = problem[0];
+      FormattedMessage message = problem[0];
       if (message.code.name != example.expectedCode) {
         unexpectedProblems.add(problem);
       }
diff --git a/pkg/front_end/test/fasta/super_mixins_test.dart b/pkg/front_end/test/fasta/super_mixins_test.dart
index 450dac8..d0ad9eb 100644
--- a/pkg/front_end/test/fasta/super_mixins_test.dart
+++ b/pkg/front_end/test/fasta/super_mixins_test.dart
@@ -16,7 +16,7 @@
 import 'package:front_end/src/testing/compiler_common.dart' show compileScript;
 
 import 'package:front_end/src/fasta/fasta_codes.dart'
-    show LocatedMessage, codeSuperclassHasNoMethod;
+    show FormattedMessage, codeSuperclassHasNoMethod;
 
 import 'package:front_end/src/fasta/severity.dart' show Severity;
 
@@ -68,10 +68,11 @@
 ''';
 
 ProblemHandler _makeProblemHandler(Set<String> names) {
-  return (LocatedMessage message, Severity severity, String formatted, int line,
-      int column) {
+  return (FormattedMessage message, Severity severity,
+      List<FormattedMessage> context) {
     Expect.equals(Severity.error, severity);
     Expect.equals(codeSuperclassHasNoMethod, message.code);
+    Expect.isTrue(context.isEmpty);
     names.add(message.arguments['name']);
   };
 }
diff --git a/pkg/front_end/test/incremental_bulk_compiler_full.dart b/pkg/front_end/test/incremental_bulk_compiler_full.dart
index 6a78e85..ead6b7b 100644
--- a/pkg/front_end/test/incremental_bulk_compiler_full.dart
+++ b/pkg/front_end/test/incremental_bulk_compiler_full.dart
@@ -15,7 +15,7 @@
 import 'package:front_end/src/compute_platform_binaries_location.dart'
     show computePlatformBinariesLocation;
 
-import 'package:front_end/src/fasta/fasta_codes.dart' show LocatedMessage;
+import 'package:front_end/src/fasta/fasta_codes.dart' show FormattedMessage;
 
 import 'package:front_end/src/fasta/incremental_compiler.dart'
     show IncrementalCompiler;
@@ -60,8 +60,8 @@
   var options = new CompilerOptions()
     ..sdkRoot = sdkRoot
     ..librariesSpecificationUri = Uri.base.resolve("sdk/lib/libraries.json")
-    ..onProblem = (LocatedMessage message, Severity severity, String formatted,
-        int line, int column) {
+    ..onProblem = (FormattedMessage problem, Severity severity,
+        List<FormattedMessage> context) {
       // ignore
     }
     ..strongMode = strong;
diff --git a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
index 50cedd6..0d52517 100644
--- a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
@@ -66,5 +66,18 @@
     List<int> initializedDillData =
         new File.fromUri(fullDillFromInitialized).readAsBytesSync();
     checkIsEqual(normalDillData, initializedDillData);
+
+    // Also try without invalidating anything.
+    stopwatch.reset();
+    initializeResult = await initializedCompile(
+        dart2jsUrl, fullDillFromInitialized, initializeWith, []);
+    Expect.equals(initializeExpect, initializeResult);
+    print("Initialized compile(s) from ${initializeWith.pathSegments.last} "
+        "took ${stopwatch.elapsedMilliseconds} ms");
+
+    // Compare the two files.
+    initializedDillData =
+        new File.fromUri(fullDillFromInitialized).readAsBytesSync();
+    checkIsEqual(normalDillData, initializedDillData);
   }
 }
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
index b324e31..610c148 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -22,7 +22,7 @@
 import 'package:front_end/src/compute_platform_binaries_location.dart'
     show computePlatformBinariesLocation;
 
-import 'package:front_end/src/fasta/fasta_codes.dart' show LocatedMessage;
+import 'package:front_end/src/fasta/fasta_codes.dart' show FormattedMessage;
 
 import 'package:front_end/src/fasta/incremental_compiler.dart'
     show IncrementalCompiler;
@@ -174,15 +174,33 @@
       await new File.fromUri(platformUri).readAsBytes();
 
   List<int> newestWholeComponent;
+  MemoryFileSystem fs;
+  Map<String, String> sourceFiles;
+  CompilerOptions options;
+  TestIncrementalCompiler compiler;
   for (var world in worlds) {
-    MemoryFileSystem fs = new MemoryFileSystem(base);
+    bool brandNewWorld = true;
+    if (world["worldType"] == "updated") {
+      brandNewWorld = false;
+    }
+
+    if (brandNewWorld) {
+      fs = new MemoryFileSystem(base);
+    }
     fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryData);
     bool expectInitializeFromDill = false;
     if (newestWholeComponent != null && newestWholeComponent.isNotEmpty) {
       fs.entityForUri(initializeFrom).writeAsBytesSync(newestWholeComponent);
       expectInitializeFromDill = true;
     }
-    Map<String, String> sourceFiles = world["sources"];
+    if (world["expectInitializeFromDill"] != null) {
+      expectInitializeFromDill = world["expectInitializeFromDill"];
+    }
+    if (brandNewWorld) {
+      sourceFiles = new Map<String, String>.from(world["sources"]);
+    } else {
+      sourceFiles.addAll(world["sources"]);
+    }
     Uri packagesUri;
     for (String filename in sourceFiles.keys) {
       String data = sourceFiles[filename] ?? "";
@@ -194,32 +212,35 @@
       fs.entityForUri(uri).writeAsStringSync(data);
     }
 
-    CompilerOptions options = getOptions(strong);
-    options.fileSystem = fs;
-    options.sdkRoot = null;
-    options.sdkSummary = sdkSummary;
-    if (packagesUri != null) {
-      options.packagesFileUri = packagesUri;
+    if (brandNewWorld) {
+      options = getOptions(strong);
+      options.fileSystem = fs;
+      options.sdkRoot = null;
+      options.sdkSummary = sdkSummary;
+      if (packagesUri != null) {
+        options.packagesFileUri = packagesUri;
+      }
     }
     bool gotError = false;
     List<String> formattedErrors = <String>[];
     bool gotWarning = false;
     List<String> formattedWarnings = <String>[];
 
-    options.onProblem = (LocatedMessage message, Severity severity,
-        String formatted, int line, int column) {
+    options.onProblem = (FormattedMessage problem, Severity severity,
+        List<FormattedMessage> context) {
       if (severity == Severity.error) {
         gotError = true;
-        formattedErrors.add(formatted);
+        formattedErrors.add(problem.formatted);
       } else if (severity == Severity.warning) {
         gotWarning = true;
-        formattedWarnings.add(formatted);
+        formattedWarnings.add(problem.formatted);
       }
     };
 
     Uri entry = base.resolve(world["entry"]);
-    TestIncrementalCompiler compiler =
-        new TestIncrementalCompiler(options, entry, initializeFrom);
+    if (brandNewWorld) {
+      compiler = new TestIncrementalCompiler(options, entry, initializeFrom);
+    }
 
     if (world["invalidate"] != null) {
       for (var filename in world["invalidate"]) {
@@ -228,7 +249,7 @@
     }
 
     Stopwatch stopwatch = new Stopwatch()..start();
-    Component component = await compiler.computeDelta();
+    Component component = await compiler.computeDelta(fullComponent: true);
     if (world["errors"] == true && !gotError) {
       throw "Expected error, but didn't get any.";
     } else if (world["errors"] != true && gotError) {
@@ -254,19 +275,27 @@
       throw "Expected that initializedFromDill would be "
           "$expectInitializeFromDill but was ${compiler.initializedFromDill}";
     }
-    if (world["invalidate"] != null) {
-      Expect.equals(world["invalidate"].length,
-          compiler.invalidatedImportUrisForTesting.length);
-      List expectedInvalidatedUri = world["expectedInvalidatedUri"];
-      if (expectedInvalidatedUri != null) {
-        Expect.setEquals(
-            expectedInvalidatedUri
-                .map((s) => Uri.parse(substituteVariables(s, base))),
-            compiler.invalidatedImportUrisForTesting);
+    if (world["checkInvalidatedFiles"] != false) {
+      if (world["invalidate"] != null) {
+        Expect.equals(world["invalidate"].length,
+            compiler.invalidatedImportUrisForTesting.length);
+        List expectedInvalidatedUri = world["expectedInvalidatedUri"];
+        if (expectedInvalidatedUri != null) {
+          Expect.setEquals(
+              expectedInvalidatedUri
+                  .map((s) => Uri.parse(substituteVariables(s, base))),
+              compiler.invalidatedImportUrisForTesting);
+        }
+      } else {
+        Expect.isNull(compiler.invalidatedImportUrisForTesting);
+        Expect.isNull(world["expectedInvalidatedUri"]);
       }
-    } else {
-      Expect.isNull(compiler.invalidatedImportUrisForTesting);
-      Expect.isNull(world["expectedInvalidatedUri"]);
+    }
+
+    {
+      Component component2 = await compiler.computeDelta(fullComponent: true);
+      List<int> thisWholeComponent = serializeComponent(component2);
+      checkIsEqual(newestWholeComponent, thisWholeComponent);
     }
   }
 }
@@ -289,10 +318,10 @@
   var options = new CompilerOptions()
     ..sdkRoot = sdkRoot
     ..librariesSpecificationUri = Uri.base.resolve("sdk/lib/libraries.json")
-    ..onProblem = (LocatedMessage message, Severity severity, String formatted,
-        int line, int column) {
+    ..onProblem = (FormattedMessage problem, Severity severity,
+        List<FormattedMessage> context) {
       if (severity == Severity.error || severity == Severity.warning) {
-        Expect.fail("Unexpected error: $formatted");
+        Expect.fail("Unexpected error: ${problem.formatted}");
       }
     }
     ..strongMode = strong;
@@ -328,6 +357,14 @@
   throwOnEmptyMixinBodies(initializedComponent);
   bool result = compiler.initializedFromDill;
   await writeComponentToFile(initializedComponent, output);
+
+  var initializedComponent2 = await compiler.computeDelta(fullComponent: true);
+  throwOnEmptyMixinBodies(initializedComponent2);
+  Expect.equals(initializedComponent.libraries.length,
+      initializedComponent2.libraries.length);
+  Expect.equals(initializedComponent.uriToSource.length,
+      initializedComponent2.uriToSource.length);
+
   for (Uri invalidateUri in invalidateUris) {
     compiler.invalidate(invalidateUri);
   }
diff --git a/pkg/front_end/testcases/implicit_const_with_static_fields.dart.direct.expect b/pkg/front_end/testcases/implicit_const_with_static_fields.dart.direct.expect
index f928029..e086d53 100644
--- a/pkg/front_end/testcases/implicit_const_with_static_fields.dart.direct.expect
+++ b/pkg/front_end/testcases/implicit_const_with_static_fields.dart.direct.expect
@@ -10,6 +10,6 @@
 }
 static const field dynamic constTopLevelField = 42;
 static method main() → dynamic {
-  const self::C::•(self::C::constField);
-  const self::C::•(self::constTopLevelField);
+  new self::C::•(self::C::constField);
+  new self::C::•(self::constTopLevelField);
 }
diff --git a/pkg/front_end/testcases/implicit_const_with_static_fields.dart.direct.transformed.expect b/pkg/front_end/testcases/implicit_const_with_static_fields.dart.direct.transformed.expect
index f928029..e086d53 100644
--- a/pkg/front_end/testcases/implicit_const_with_static_fields.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/implicit_const_with_static_fields.dart.direct.transformed.expect
@@ -10,6 +10,6 @@
 }
 static const field dynamic constTopLevelField = 42;
 static method main() → dynamic {
-  const self::C::•(self::C::constField);
-  const self::C::•(self::constTopLevelField);
+  new self::C::•(self::C::constField);
+  new self::C::•(self::constTopLevelField);
 }
diff --git a/pkg/front_end/testcases/implicit_const_with_static_fields.dart.strong.expect b/pkg/front_end/testcases/implicit_const_with_static_fields.dart.strong.expect
index 90d9837..c4b4907 100644
--- a/pkg/front_end/testcases/implicit_const_with_static_fields.dart.strong.expect
+++ b/pkg/front_end/testcases/implicit_const_with_static_fields.dart.strong.expect
@@ -10,6 +10,6 @@
 }
 static const field core::int constTopLevelField = 42;
 static method main() → dynamic {
-  const self::C::•(self::C::constField);
-  const self::C::•(self::constTopLevelField);
+  new self::C::•(self::C::constField);
+  new self::C::•(self::constTopLevelField);
 }
diff --git a/pkg/front_end/testcases/implicit_const_with_static_fields.dart.strong.transformed.expect b/pkg/front_end/testcases/implicit_const_with_static_fields.dart.strong.transformed.expect
index 90d9837..c4b4907 100644
--- a/pkg/front_end/testcases/implicit_const_with_static_fields.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/implicit_const_with_static_fields.dart.strong.transformed.expect
@@ -10,6 +10,6 @@
 }
 static const field core::int constTopLevelField = 42;
 static method main() → dynamic {
-  const self::C::•(self::C::constField);
-  const self::C::•(self::constTopLevelField);
+  new self::C::•(self::C::constField);
+  new self::C::•(self::constTopLevelField);
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml
index 78c978d..e441068 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml
@@ -25,8 +25,11 @@
       .packages: dummy:${outDirUri}
     expectedLibraryCount: 2
   - entry: main.dart
-    invalidate:
-      - main.dart
+    # TODO(jensj): For now we don't initialize from dill when a package was
+    # changed.
+    #invalidate:
+    #  - main.dart
+    expectInitializeFromDill: false
     sources:
       main.dart: |
         main() {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
new file mode 100644
index 0000000..c9e0195
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
@@ -0,0 +1,16 @@
+# Copyright (c) 2018, 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.md file.
+
+# Invalidate nothing when the entrypoint  just exports another file
+# (which has main).
+
+type: basic
+entry: a.dart
+strong: true
+invalidate:
+sources:
+  a.dart: |
+    export 'b.dart';
+  b.dart: |
+    main() { print("hello"); }
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package.yaml
new file mode 100644
index 0000000..471546a
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package.yaml
@@ -0,0 +1,65 @@
+# Copyright (c) 2018, 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.md file.
+
+# Compile an application with a package and use it.
+# Then update the package from .packages.
+# The old package is still included in the dill file we initialize from,
+# but shouldn't cause trouble, nor be included in the output.
+
+type: newworld
+strong: false
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "package:dummy/b.dart";
+        main() {
+          print("hello");
+          b();
+        }
+      package_0.1.0/a.dart: |
+        a() {
+          la1();
+        }
+        la1() {
+          print("v0.1.0");
+        }
+      package_0.1.0/b.dart: |
+        import "a.dart";
+        b() {
+          a();
+        }
+      .packages: dummy:${outDirUri}package_0.1.0
+    expectedLibraryCount: 3
+  - entry: main.dart
+    # TODO(jensj): For now we don't initialize from dill when a package was
+    # changed.
+    #invalidate:
+    #  - main.dart
+    expectInitializeFromDill: false
+    sources:
+      main.dart: |
+        import "package:dummy/b.dart";
+        main() {
+          print("hello");
+          b();
+        }
+      package_0.1.0/a.dart: |
+        a() {
+          la1();
+        }
+        la1() {
+          print("v0.1.0");
+        }
+      package_0.1.0/b.dart: |
+        import "a.dart";
+        b() {
+          a();
+        }
+      package_0.1.1/b.dart: |
+        b() {
+          print("hello from v0.1.1");
+        }
+      .packages: dummy:${outDirUri}package_0.1.1
+    expectedLibraryCount: 2
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_2.yaml
new file mode 100644
index 0000000..fcf5918
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_2.yaml
@@ -0,0 +1,64 @@
+# Copyright (c) 2018, 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.md file.
+
+# Compile an application with a package and use it.
+# Then update the package from .packages.
+# The old package is still included in the dill file we initialize from,
+# but shouldn't cause trouble, nor be included in the output.
+
+type: newworld
+strong: false
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "package:dummy/b.dart";
+        main() {
+          print("hello");
+          b();
+        }
+      package_0.1.0/a.dart: |
+        a() {
+          la1();
+        }
+        la1() {
+          print("v0.1.0");
+        }
+      package_0.1.0/b.dart: |
+        import "a.dart";
+        b() {
+          a();
+        }
+      .packages: dummy:${outDirUri}package_0.1.0
+    expectedLibraryCount: 3
+  - entry: main.dart
+    invalidate:
+    # TODO(jensj): For now we don't initialize from dill when a package was
+    # changed.
+    expectInitializeFromDill: false
+    sources:
+      main.dart: |
+        import "package:dummy/b.dart";
+        main() {
+          print("hello");
+          b();
+        }
+      package_0.1.0/a.dart: |
+        a() {
+          la1();
+        }
+        la1() {
+          print("v0.1.0");
+        }
+      package_0.1.0/b.dart: |
+        import "a.dart";
+        b() {
+          a();
+        }
+      package_0.1.1/b.dart: |
+        b() {
+          print("hello from v0.1.1");
+        }
+      .packages: dummy:${outDirUri}package_0.1.1
+    expectedLibraryCount: 2
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_3.yaml
new file mode 100644
index 0000000..2516191
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_3.yaml
@@ -0,0 +1,45 @@
+# Copyright (c) 2018, 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.md file.
+
+# Compile an application with a package and use it.
+# Then update the package from .packages but change nothing else and call
+# computeDelta on the same compiler.
+# The output should not include the old package.
+
+type: newworld
+strong: false
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "package:dummy/b.dart";
+        main() {
+          print("hello");
+          b();
+        }
+      package_0.1.0/a.dart: |
+        a() {
+          la1();
+        }
+        la1() {
+          print("v0.1.0");
+        }
+      package_0.1.0/b.dart: |
+        import "a.dart";
+        b() {
+          a();
+        }
+      .packages: dummy:${outDirUri}package_0.1.0
+    expectedLibraryCount: 3
+  - entry: main.dart
+    worldType: updated
+    expectInitializeFromDill: false
+    checkInvalidatedFiles: false
+    sources:
+      package_0.1.1/b.dart: |
+        b() {
+          print("hello from v0.1.1");
+        }
+      .packages: dummy:${outDirUri}package_0.1.1
+    expectedLibraryCount: 2
\ No newline at end of file
diff --git a/pkg/front_end/testcases/magic_const.dart.direct.expect b/pkg/front_end/testcases/magic_const.dart.direct.expect
index 8595e97..31bfe5f 100644
--- a/pkg/front_end/testcases/magic_const.dart.direct.expect
+++ b/pkg/front_end/testcases/magic_const.dart.direct.expect
@@ -12,20 +12,14 @@
     : super core::Object::•()
     ;
 }
-static method foo({dynamic a = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:9: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-foo({a: Constant(), b: Constant(), c: []}) {}
-        ^", dynamic b = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:24: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-foo({a: Constant(), b: Constant(), c: []}) {}
-                       ^", dynamic c = <dynamic>[]}) → dynamic {}
+static method foo({dynamic a = new self::Constant::•(), dynamic b = new self::Constant::•(), dynamic c = <dynamic>[]}) → dynamic {}
 static method test() → dynamic {
   invalid-expression "pkg/front_end/testcases/magic_const.dart:18:9: Error: Not a const constructor.
   const NotConstant();
         ^";
-  const self::Constant::•();
+  new self::Constant::•();
   const dynamic x = const self::Constant::•();
-  invalid-expression "pkg/front_end/testcases/magic_const.dart:21:8: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-  bool.fromEnvironment(\"fisk\");
-       ^";
+  core::bool::fromEnvironment("fisk");
   const dynamic b = const core::bool::fromEnvironment("fisk");
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/magic_const.dart.direct.transformed.expect b/pkg/front_end/testcases/magic_const.dart.direct.transformed.expect
index 8595e97..31bfe5f 100644
--- a/pkg/front_end/testcases/magic_const.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/magic_const.dart.direct.transformed.expect
@@ -12,20 +12,14 @@
     : super core::Object::•()
     ;
 }
-static method foo({dynamic a = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:9: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-foo({a: Constant(), b: Constant(), c: []}) {}
-        ^", dynamic b = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:24: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-foo({a: Constant(), b: Constant(), c: []}) {}
-                       ^", dynamic c = <dynamic>[]}) → dynamic {}
+static method foo({dynamic a = new self::Constant::•(), dynamic b = new self::Constant::•(), dynamic c = <dynamic>[]}) → dynamic {}
 static method test() → dynamic {
   invalid-expression "pkg/front_end/testcases/magic_const.dart:18:9: Error: Not a const constructor.
   const NotConstant();
         ^";
-  const self::Constant::•();
+  new self::Constant::•();
   const dynamic x = const self::Constant::•();
-  invalid-expression "pkg/front_end/testcases/magic_const.dart:21:8: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-  bool.fromEnvironment(\"fisk\");
-       ^";
+  core::bool::fromEnvironment("fisk");
   const dynamic b = const core::bool::fromEnvironment("fisk");
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/magic_const.dart.strong.expect b/pkg/front_end/testcases/magic_const.dart.strong.expect
index f3197ea..d60f57e 100644
--- a/pkg/front_end/testcases/magic_const.dart.strong.expect
+++ b/pkg/front_end/testcases/magic_const.dart.strong.expect
@@ -12,20 +12,14 @@
     : super core::Object::•()
     ;
 }
-static method foo({dynamic a = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:9: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-foo({a: Constant(), b: Constant(), c: []}) {}
-        ^", dynamic b = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:24: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-foo({a: Constant(), b: Constant(), c: []}) {}
-                       ^", dynamic c = <dynamic>[]}) → dynamic {}
+static method foo({dynamic a = new self::Constant::•(), dynamic b = new self::Constant::•(), dynamic c = <dynamic>[]}) → dynamic {}
 static method test() → dynamic {
   invalid-expression "pkg/front_end/testcases/magic_const.dart:18:9: Error: Not a const constructor.
   const NotConstant();
         ^";
-  const self::Constant::•();
+  new self::Constant::•();
   const self::Constant x = const self::Constant::•();
-  invalid-expression "pkg/front_end/testcases/magic_const.dart:21:8: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-  bool.fromEnvironment(\"fisk\");
-       ^";
+  core::bool::fromEnvironment("fisk");
   const core::bool b = const core::bool::fromEnvironment("fisk");
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect b/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect
index f3197ea..d60f57e 100644
--- a/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect
@@ -12,20 +12,14 @@
     : super core::Object::•()
     ;
 }
-static method foo({dynamic a = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:9: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-foo({a: Constant(), b: Constant(), c: []}) {}
-        ^", dynamic b = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:24: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-foo({a: Constant(), b: Constant(), c: []}) {}
-                       ^", dynamic c = <dynamic>[]}) → dynamic {}
+static method foo({dynamic a = new self::Constant::•(), dynamic b = new self::Constant::•(), dynamic c = <dynamic>[]}) → dynamic {}
 static method test() → dynamic {
   invalid-expression "pkg/front_end/testcases/magic_const.dart:18:9: Error: Not a const constructor.
   const NotConstant();
         ^";
-  const self::Constant::•();
+  new self::Constant::•();
   const self::Constant x = const self::Constant::•();
-  invalid-expression "pkg/front_end/testcases/magic_const.dart:21:8: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-  bool.fromEnvironment(\"fisk\");
-       ^";
+  core::bool::fromEnvironment("fisk");
   const core::bool b = const core::bool::fromEnvironment("fisk");
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart
index 255ffe6..e797b0e 100644
--- a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart
@@ -2,8 +2,6 @@
 // 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.
 
-/*@testedFeatures=error*/
-
 const int foo = const int.fromEnvironment("fisk");
 
 class A {
@@ -18,8 +16,7 @@
 
 class C {
   fun() {
-    /*@error=CantDetermineConstness*/ B(
-        /*@error=CantDetermineConstness*/ A(foo));
+    B(A(foo));
   }
 }
 
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.expect b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.expect
index c486c02..6c29079 100644
--- a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.expect
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.expect
@@ -19,9 +19,7 @@
     : super core::Object::•()
     ;
   method fun() → dynamic {
-    invalid-expression "pkg/front_end/testcases/nested_implicit_const_with_env_var.dart:21:39: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-    /*@error=CantDetermineConstness*/ B(
-                                      ^";
+    new self::B::•(new self::A::•(self::foo));
   }
 }
 static const field core::int foo = const core::int::fromEnvironment("fisk");
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.transformed.expect b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.transformed.expect
index c486c02..6c29079 100644
--- a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.transformed.expect
@@ -19,9 +19,7 @@
     : super core::Object::•()
     ;
   method fun() → dynamic {
-    invalid-expression "pkg/front_end/testcases/nested_implicit_const_with_env_var.dart:21:39: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-    /*@error=CantDetermineConstness*/ B(
-                                      ^";
+    new self::B::•(new self::A::•(self::foo));
   }
 }
 static const field core::int foo = const core::int::fromEnvironment("fisk");
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.expect b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.expect
index c486c02..6c29079 100644
--- a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.expect
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.expect
@@ -19,9 +19,7 @@
     : super core::Object::•()
     ;
   method fun() → dynamic {
-    invalid-expression "pkg/front_end/testcases/nested_implicit_const_with_env_var.dart:21:39: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-    /*@error=CantDetermineConstness*/ B(
-                                      ^";
+    new self::B::•(new self::A::•(self::foo));
   }
 }
 static const field core::int foo = const core::int::fromEnvironment("fisk");
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.transformed.expect b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.transformed.expect
index c486c02..6c29079 100644
--- a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.transformed.expect
@@ -19,9 +19,7 @@
     : super core::Object::•()
     ;
   method fun() → dynamic {
-    invalid-expression "pkg/front_end/testcases/nested_implicit_const_with_env_var.dart:21:39: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-    /*@error=CantDetermineConstness*/ B(
-                                      ^";
+    new self::B::•(new self::A::•(self::foo));
   }
 }
 static const field core::int foo = const core::int::fromEnvironment("fisk");
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.expect
index de2c44c..6053292 100644
--- a/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.expect
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.expect
@@ -10,8 +10,8 @@
 }
 static method main() → dynamic {
   core::int foo = 42;
-  const self::A::•(5);
-  const self::A::•(5.+(5));
+  new self::A::•(5);
+  new self::A::•(5.+(5));
   new self::A::•(foo);
   new self::A::•(5.+(foo));
 }
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.transformed.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.transformed.expect
index de2c44c..6053292 100644
--- a/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.transformed.expect
@@ -10,8 +10,8 @@
 }
 static method main() → dynamic {
   core::int foo = 42;
-  const self::A::•(5);
-  const self::A::•(5.+(5));
+  new self::A::•(5);
+  new self::A::•(5.+(5));
   new self::A::•(foo);
   new self::A::•(5.+(foo));
 }
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.expect
index 4ee5522..d7f734b 100644
--- a/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.expect
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.expect
@@ -10,8 +10,8 @@
 }
 static method main() → dynamic {
   core::int foo = 42;
-  const self::A::•(5);
-  const self::A::•(5.{core::num::+}(5));
+  new self::A::•(5);
+  new self::A::•(5.{core::num::+}(5));
   new self::A::•(foo);
   new self::A::•(5.{core::num::+}(foo));
 }
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.transformed.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.transformed.expect
index 4ee5522..d7f734b 100644
--- a/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.transformed.expect
@@ -10,8 +10,8 @@
 }
 static method main() → dynamic {
   core::int foo = 42;
-  const self::A::•(5);
-  const self::A::•(5.{core::num::+}(5));
+  new self::A::•(5);
+  new self::A::•(5.{core::num::+}(5));
   new self::A::•(foo);
   new self::A::•(5.{core::num::+}(foo));
 }
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index b58cda9..e55935e 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -135,7 +135,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h.
-  static const int BinaryFormatVersion = 3;
+  static const int BinaryFormatVersion = 4;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index 22dbf96..9c1db32 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -392,7 +392,7 @@
   }
 
   visitYieldStatement(YieldStatement node) {
-    return new YieldStatement(clone(node.expression));
+    return new YieldStatement(clone(node.expression))..flags = node.flags;
   }
 
   visitVariableDeclaration(VariableDeclaration node) {
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index a839ff4..de93109 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -86,25 +86,32 @@
       ..packagesFileUri = packagesUri
       ..sdkSummary = platformKernelPath
       ..verbose = verbose
-      ..onProblem =
-          (message, Severity severity, String formatted, int line, int column) {
+      ..onProblem = (FormattedMessage message, Severity severity,
+          List<FormattedMessage> context) {
+        bool printMessage;
         switch (severity) {
           case Severity.error:
-          case Severity.errorLegacyWarning:
           case Severity.internalProblem:
             // TODO(sigmund): support emitting code with errors as long as they
             // are handled in the generated code (issue #30194).
-            errors.add(formatted);
-            stderr.writeln(formatted);
+            printMessage = true;
+            errors.add(message.formatted);
             break;
           case Severity.nit:
+            printMessage = false;
             break;
           case Severity.warning:
-            if (!suppressWarnings) stderr.writeln(formatted);
+            printMessage = !suppressWarnings;
             break;
+          case Severity.errorLegacyWarning:
           case Severity.context:
-            stderr.writeln(formatted);
-            break;
+            throw "Unexpected severity: $severity";
+        }
+        if (printMessage) {
+          stderr.writeln(message.formatted);
+          for (FormattedMessage message in context) {
+            stderr.writeln(message.formatted);
+          }
         }
       };
   }
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index ebb7792..d8644fa 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -209,20 +209,29 @@
       ..strongMode = options['strong']
       ..sdkSummary = sdkRoot.resolve(platformKernelDill)
       ..onProblem =
-          (message, Severity severity, String formatted, int line, int column) {
+          (message, Severity severity, List<FormattedMessage> context) {
+        bool printMessage;
         switch (severity) {
           case Severity.error:
-          case Severity.errorLegacyWarning:
           case Severity.internalProblem:
-            _outputStream.writeln(formatted);
-            errors.add(formatted);
+            printMessage = true;
+            errors.add(message.formatted);
             break;
           case Severity.nit:
+            printMessage = false;
             break;
           case Severity.warning:
-          case Severity.context:
-            _outputStream.writeln(formatted);
+            printMessage = true;
             break;
+          case Severity.errorLegacyWarning:
+          case Severity.context:
+            throw "Unexpected severity: $severity";
+        }
+        if (printMessage) {
+          _outputStream.writeln(message.formatted);
+          for (FormattedMessage message in context) {
+            _outputStream.writeln(message.formatted);
+          }
         }
       };
     if (options.wasParsed('filesystem-root')) {
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index f4e9f38..7c23deb 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -53,6 +53,7 @@
   void visitParameter(Parameter expr) => visitDefault(expr);
   void visitNarrow(Narrow expr) => visitDefault(expr);
   void visitJoin(Join expr) => visitDefault(expr);
+  void visitUse(Use expr) => visitDefault(expr);
   void visitCall(Call expr) => visitDefault(expr);
 }
 
@@ -135,6 +136,24 @@
   }
 }
 
+/// Artificial use of [arg]. Removed during summary normalization.
+class Use extends Statement {
+  TypeExpr arg;
+
+  Use(this.arg);
+
+  @override
+  void accept(StatementVisitor visitor) => visitor.visitUse(this);
+
+  @override
+  String dump() => "$label = _Use ($arg)";
+
+  @override
+  Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+          CallHandler callHandler) =>
+      throw 'Use statements should be removed during summary normalization';
+}
+
 /// Call site.
 class Call extends Statement {
   final Selector selector;
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index f9bdcb1..8d48f99 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -61,6 +61,8 @@
     for (Statement st in statements) {
       if (st is Call) {
         _normalizeExpr(st, false);
+      } else if (st is Use) {
+        _normalizeExpr(st.arg, true);
       }
     }
 
@@ -69,6 +71,7 @@
 
   TypeExpr _normalizeExpr(TypeExpr st, bool isResultUsed) {
     assertx(!_inLoop);
+    assertx(st is! Use);
     if (st is Statement) {
       if (isResultUsed && (st is Call)) {
         st.setResultUsed();
@@ -137,6 +140,11 @@
   }
 
   @override
+  void visitUse(Use expr) {
+    throw '\'Use\' statement should not be referenced: $expr';
+  }
+
+  @override
   void visitCall(Call expr) {
     for (int i = 0; i < expr.args.values.length; i++) {
       expr.args.values[i] = _normalizeExpr(expr.args.values[i], true);
@@ -485,6 +493,18 @@
     return narrow;
   }
 
+  // Add an artificial use of given expression in order to make it possible to
+  // infer its type even if it is not used in a summary.
+  void _addUse(TypeExpr arg) {
+    if (arg is Narrow) {
+      _addUse(arg.arg);
+    } else if (arg is Join || arg is Call) {
+      _summary.add(new Use(arg));
+    } else {
+      assertx(arg is Type || arg is Parameter);
+    }
+  }
+
   Type _staticType(Expression node) =>
       new Type.fromStatic(node.getStaticType(_environment));
 
@@ -553,7 +573,7 @@
 
   @override
   TypeExpr visitConditionalExpression(ConditionalExpression node) {
-    _visit(node.condition);
+    _addUse(_visit(node.condition));
 
     Join v = new Join(null, node.getStaticType(_environment));
     _summary.add(v);
@@ -652,8 +672,8 @@
 
   @override
   TypeExpr visitLogicalExpression(LogicalExpression node) {
-    _visit(node.left);
-    _visit(node.right);
+    _addUse(_visit(node.left));
+    _addUse(_visit(node.right));
     return _boolType;
   }
 
@@ -812,7 +832,7 @@
 
   @override
   TypeExpr visitNot(Not node) {
-    _visit(node.operand);
+    _addUse(_visit(node.operand));
     return _boolType;
   }
 
@@ -960,7 +980,7 @@
   @override
   TypeExpr visitAssertStatement(AssertStatement node) {
     if (!kRemoveAsserts) {
-      _visit(node.condition);
+      _addUse(_visit(node.condition));
       if (node.message != null) {
         _visit(node.message);
       }
@@ -1017,7 +1037,7 @@
   TypeExpr visitForStatement(ForStatement node) {
     node.variables.forEach(visitVariableDeclaration);
     if (node.condition != null) {
-      _visit(node.condition);
+      _addUse(_visit(node.condition));
     }
     node.updates.forEach(_visit);
     _visit(node.body);
@@ -1036,7 +1056,7 @@
 
   @override
   TypeExpr visitIfStatement(IfStatement node) {
-    _visit(node.condition);
+    _addUse(_visit(node.condition));
     _visit(node.then);
     if (node.otherwise != null) {
       _visit(node.otherwise);
@@ -1099,7 +1119,7 @@
 
   @override
   visitWhileStatement(WhileStatement node) {
-    _visit(node.condition);
+    _addUse(_visit(node.condition));
     _visit(node.body);
   }
 
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart b/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart
new file mode 100644
index 0000000..a22bad2
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2018, 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.
+
+dynamic foo() => null;
+bool bar() => null;
+
+void bool_expressions() {
+  if (foo()) {}
+  while (bar()) {}
+  for (int i = 0; i < 10; i++) {}
+  bool x = bar();
+  bool y = true;
+  if (x is bool) {
+    y = x ? true : foo();
+    y = bar() || bar();
+  }
+  x = foo() && foo();
+  y = !y;
+  assert(y);
+}
+
+main() {}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart.expect
new file mode 100644
index 0000000..b36ef8c
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/bool_expressions.dart.expect
@@ -0,0 +1,27 @@
+------------ #lib::foo ------------
+
+RESULT: _T {}?
+------------ #lib::bar ------------
+
+RESULT: _T {}?
+------------ #lib::bool_expressions ------------
+t0* = _Call direct [#lib::foo] ()
+t1* = _Call direct [#lib::bar] ()
+t2* = _Call [dart.core::num::+] (_T (dart.core::int)+?, _T (dart.core::int)+)
+i = _Join [dart.core::int] (_T (dart.core::int)+, t2)
+t4* = _Call [dart.core::num::<] (i, _T (dart.core::int)+)
+t5* = _Call direct [#lib::bar] ()
+x = _Join [dart.core::bool] (t5, _T (dart.core::bool)+)
+t7* = _Call direct [#lib::foo] ()
+t8* = _Call direct [#lib::bar] ()
+t9* = _Call direct [#lib::bar] ()
+t10* = _Call direct [#lib::foo] ()
+t11* = _Call direct [#lib::foo] ()
+t12 = _Join [dynamic] (_T (dart.core::bool)+, t7)
+t13 = _Narrow (t12 to _T ANY?)
+t14 = _Narrow (t13 to _T (dart.core::bool)+?)
+y = _Join [dart.core::bool] (_T (dart.core::bool)+, t14, _T (dart.core::bool)+, _T (dart.core::bool)+)
+RESULT: _T {}?
+------------ #lib::main ------------
+
+RESULT: _T {}?
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
index 44d8318..2cad426 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
@@ -9,12 +9,12 @@
 ------------ #lib::foo ------------
 %a1 = _Parameter #0 [_T (dart.core::Object)+?]
 %a2 = _Parameter #1 [_T (dart.core::Object)+?]
-t2 = _Call direct get [#lib::someStatic] ()
+t2* = _Call direct get [#lib::someStatic] ()
 t3 = _Call direct [#lib::A::] (_T (#lib::A))
 a1 = _Join [dart.core::Object] (%a1, _T (#lib::A), _T (#lib::B))
 t5 = _Call direct [#lib::bar] (a1, _T (dart.core::int)+)
 t6 = _Call direct [#lib::B::] (_T (#lib::B))
-t7 = _Call [dart.core::Object::==] (a1, %a2)
+t7* = _Call [dart.core::Object::==] (a1, %a2)
 t8 = _Join [dart.core::Object] (a1, %a2)
 t9 = _Narrow (t8 to _T (dart.core::Object)+?)
 RESULT: t9
@@ -37,7 +37,7 @@
 %x = _Parameter #0 [_T (dart.core::int)+?]
 t1* = _Call [dart.core::num::+] (_T (dart.core::int)+?, _T (dart.core::int)+)
 i = _Join [dart.core::int] (_T (dart.core::int)+, t1)
-t3 = _Call [dart.core::num::<] (i, _T (dart.core::int)+)
+t3* = _Call [dart.core::num::<] (i, _T (dart.core::int)+)
 t4* = _Call [dart.core::num::+] (_T (dart.core::int)+?, _T (dart.core::int)+)
 x = _Join [dart.core::int] (%x, t4)
 RESULT: x
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
index 2513602..e7c4fe3 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
@@ -17,7 +17,7 @@
   }
   operator *([@vm.inferred-type.metadata=#lib::_Vector?] self::_Vector a) → core::double {
     core::double result = 0.0;
-    for (core::int i = 0; i.{core::num::<}([@vm.direct-call.metadata=#lib::_Vector::_length] [@vm.inferred-type.metadata=!] this.{self::_Vector::_length}); i = i.{core::num::+}(1))
+    for (core::int i = 0; [@vm.inferred-type.metadata=dart.core::bool?] i.{core::num::<}([@vm.direct-call.metadata=#lib::_Vector::_length] [@vm.inferred-type.metadata=!] this.{self::_Vector::_length}); i = i.{core::num::+}(1))
       result = [@vm.direct-call.metadata=dart.core::_Double::+??] [@vm.inferred-type.metadata=dart.core::_Double] result.{core::double::+}([@vm.direct-call.metadata=dart.core::_Double::*] [@vm.inferred-type.metadata=dart.core::_Double] [@vm.direct-call.metadata=#lib::_Vector::[]] [@vm.inferred-type.metadata=dart.core::_Double] this.{self::_Vector::[]}(i).{core::double::*}([@vm.direct-call.metadata=#lib::_Vector::[]??] [@vm.inferred-type.metadata=dart.core::_Double] a.{self::_Vector::[]}(i)));
     return result;
   }
@@ -26,7 +26,7 @@
 [@vm.inferred-type.metadata=dart.core::_Double?]static field core::double x = 0.0;
 static method main(core::List<core::String> args) → dynamic {
   core::Stopwatch timer = let final core::Stopwatch #t4 = new core::Stopwatch::•() in let final dynamic #t5 = [@vm.direct-call.metadata=dart.core::Stopwatch::start] #t4.{core::Stopwatch::start}() in #t4;
-  for (core::int i = 0; i.{core::num::<}(100000000); i = i.{core::num::+}(1)) {
+  for (core::int i = 0; [@vm.inferred-type.metadata=dart.core::bool?] i.{core::num::<}(100000000); i = i.{core::num::+}(1)) {
     self::x = [@vm.direct-call.metadata=dart.core::_Double::+??] [@vm.inferred-type.metadata=dart.core::_Double] [@vm.inferred-type.metadata=dart.core::_Double?] self::x.{core::double::+}([@vm.direct-call.metadata=#lib::_Vector::*??] [@vm.inferred-type.metadata=dart.core::_Double] [@vm.inferred-type.metadata=#lib::_Vector?] self::v.{self::_Vector::*}([@vm.inferred-type.metadata=#lib::_Vector?] self::v));
   }
   [@vm.direct-call.metadata=dart.core::Stopwatch::stop] timer.{core::Stopwatch::stop}();
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index b4d3d75..05ac9d1 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -1059,17 +1059,6 @@
 DART_EXPORT bool Dart_IsDart2Snapshot(const uint8_t* snapshot_buffer);
 
 /**
- * Schedules an interrupt for the specified isolate.
- *
- * When the isolate is interrupted, the isolate interrupt callback
- * will be invoked with 'isolate' as the current isolate (see
- * Dart_SetIsolateEventHandler).
- *
- * \param isolate The isolate to be interrupted.
- */
-DART_EXPORT void Dart_InterruptIsolate(Dart_Isolate isolate);
-
-/**
  * Make isolate runnable.
  *
  * When isolates are spawned this function is used to indicate that
@@ -1242,15 +1231,6 @@
 DART_EXPORT Dart_Handle Dart_HandleMessage();
 
 /**
- * Handles all pending messages for the current isolate.
- *
- * May generate an unhandled exception error.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_HandleMessages();
-
-/**
  * Drains the microtask queue, then blocks the calling thread until the current
  * isolate recieves a message, then handles all messages.
  *
diff --git a/runtime/lib/compact_hash.dart b/runtime/lib/compact_hash.dart
index 82bc532..6f55f41 100644
--- a/runtime/lib/compact_hash.dart
+++ b/runtime/lib/compact_hash.dart
@@ -78,19 +78,14 @@
   static const int _UNUSED_PAIR = 0;
   static const int _DELETED_PAIR = 1;
 
-  // On 32-bit, the top bits are wasted to avoid Mint allocation.
-  // TODO(koda): Reclaim the bits by making the compiler treat hash patterns
-  // as unsigned words.
+  // The top bits are wasted to avoid Mint allocation.
   static int _indexSizeToHashMask(int indexSize) {
     int indexBits = indexSize.bitLength - 2;
-    return internal.is64Bit
-        ? (1 << (32 - indexBits)) - 1
-        : (1 << (30 - indexBits)) - 1;
+    return (1 << (30 - indexBits)) - 1;
   }
 
   static int _hashPattern(int fullHash, int hashMask, int size) {
     final int maskedHash = fullHash & hashMask;
-    // TODO(koda): Consider keeping bit length and use left shift.
     return (maskedHash == 0) ? (size >> 1) : maskedHash * (size >> 1);
   }
 
diff --git a/runtime/lib/integers_patch.dart b/runtime/lib/integers_patch.dart
index c7116c7..ef98727 100644
--- a/runtime/lib/integers_patch.dart
+++ b/runtime/lib/integers_patch.dart
@@ -32,7 +32,7 @@
         return null; // Empty.
       }
     }
-    var smiLimit = is64Bit ? 18 : 9;
+    var smiLimit = 9;
     if ((last - ix) >= smiLimit) {
       return null; // May not fit into a Smi.
     }
@@ -117,7 +117,7 @@
 
   static int _parseRadix(
       String source, int radix, int start, int end, int sign) {
-    int tableIndex = (radix - 2) * 4 + (is64Bit ? 2 : 0);
+    int tableIndex = (radix - 2) * 2;
     int blockSize = _PARSE_LIMITS[tableIndex];
     int length = end - start;
     if (length <= blockSize) {
@@ -143,7 +143,7 @@
     int positiveOverflowLimit = 0;
     int negativeOverflowLimit = 0;
     if (_limitIntsTo64Bits) {
-      tableIndex = tableIndex << 1; // pre-multiply by 2 for simpler indexing
+      tableIndex = tableIndex << 1; // Pre-multiply by 2 for simpler indexing.
       positiveOverflowLimit = _int64OverflowLimits[tableIndex];
       if (positiveOverflowLimit == 0) {
         positiveOverflowLimit =
@@ -159,14 +159,10 @@
         if (result >= positiveOverflowLimit) {
           if ((result > positiveOverflowLimit) ||
               (smi > _int64OverflowLimits[tableIndex + 2])) {
-            // Although the unsigned overflow limits do not depend on the
-            // platform, the multiplier and block size, which are used to
-            // compute it, do.
-            int X = is64Bit ? 1 : 0;
             if (radix == 16 &&
-                !(result >= _int64UnsignedOverflowLimits[X] &&
-                    (result > _int64UnsignedOverflowLimits[X] ||
-                        smi > _int64UnsignedSmiOverflowLimits[X])) &&
+                !(result >= _int64UnsignedOverflowLimit &&
+                    (result > _int64UnsignedOverflowLimit ||
+                        smi > _int64UnsignedSmiOverflowLimit)) &&
                 blockEnd + blockSize > end) {
               return (result * multiplier) + smi;
             }
@@ -211,43 +207,42 @@
 
   // For each radix, 2-36, how many digits are guaranteed to fit in a smi,
   // and magnitude of such a block (radix ** digit-count).
-  // 32-bit limit/multiplier at (radix - 2)*4, 64-bit limit at (radix-2)*4+2
   static const _PARSE_LIMITS = const [
-    30, 1073741824, 62, 4611686018427387904, // radix: 2
-    18, 387420489, 39, 4052555153018976267,
-    15, 1073741824, 30, 1152921504606846976,
-    12, 244140625, 26, 1490116119384765625, //  radix: 5
-    11, 362797056, 23, 789730223053602816,
-    10, 282475249, 22, 3909821048582988049,
-    10, 1073741824, 20, 1152921504606846976,
-    9, 387420489, 19, 1350851717672992089,
-    9, 1000000000, 18, 1000000000000000000, //  radix: 10
-    8, 214358881, 17, 505447028499293771,
-    8, 429981696, 17, 2218611106740436992,
-    8, 815730721, 16, 665416609183179841,
-    7, 105413504, 16, 2177953337809371136,
-    7, 170859375, 15, 437893890380859375, //    radix: 15
-    7, 268435456, 15, 1152921504606846976,
-    7, 410338673, 15, 2862423051509815793,
-    7, 612220032, 14, 374813367582081024,
-    7, 893871739, 14, 799006685782884121,
-    6, 64000000, 14, 1638400000000000000, //    radix: 20
-    6, 85766121, 14, 3243919932521508681,
-    6, 113379904, 13, 282810057883082752,
-    6, 148035889, 13, 504036361936467383,
-    6, 191102976, 13, 876488338465357824,
-    6, 244140625, 13, 1490116119384765625, //   radix: 25
-    6, 308915776, 13, 2481152873203736576,
-    6, 387420489, 13, 4052555153018976267,
-    6, 481890304, 12, 232218265089212416,
-    6, 594823321, 12, 353814783205469041,
-    6, 729000000, 12, 531441000000000000, //    radix: 30
-    6, 887503681, 12, 787662783788549761,
-    6, 1073741824, 12, 1152921504606846976,
-    5, 39135393, 12, 1667889514952984961,
-    5, 45435424, 12, 2386420683693101056,
-    5, 52521875, 12, 3379220508056640625, //    radix: 35
-    5, 60466176, 11, 131621703842267136,
+    30, 1073741824, // radix: 2
+    18, 387420489,
+    15, 1073741824,
+    12, 244140625, //  radix: 5
+    11, 362797056,
+    10, 282475249,
+    10, 1073741824,
+    9, 387420489,
+    9, 1000000000, //  radix: 10
+    8, 214358881,
+    8, 429981696,
+    8, 815730721,
+    7, 105413504,
+    7, 170859375, //    radix: 15
+    7, 268435456,
+    7, 410338673,
+    7, 612220032,
+    7, 893871739,
+    6, 64000000, //    radix: 20
+    6, 85766121,
+    6, 113379904,
+    6, 148035889,
+    6, 191102976,
+    6, 244140625, //   radix: 25
+    6, 308915776,
+    6, 387420489,
+    6, 481890304,
+    6, 594823321,
+    6, 729000000, //    radix: 30
+    6, 887503681,
+    6, 1073741824,
+    5, 39135393,
+    5, 45435424,
+    5, 52521875, //    radix: 35
+    5, 60466176,
   ];
 
   /// Flag indicating if integers are limited by 64 bits
@@ -257,11 +252,8 @@
   static const _maxInt64 = 0x7fffffffffffffff;
   static const _minInt64 = -_maxInt64 - 1;
 
-  static const _int64UnsignedOverflowLimits = const [0xfffffffff, 0xf];
-  static const _int64UnsignedSmiOverflowLimits = const [
-    0xfffffff,
-    0xfffffffffffffff
-  ];
+  static const _int64UnsignedOverflowLimit = 0xfffffffff;
+  static const _int64UnsignedSmiOverflowLimit = 0xfffffff;
 
   /// In the `--limit-ints-to-64-bits` mode calculation of the expression
   ///
diff --git a/runtime/observatory/tests/service/bad_reload/v1/main.dart b/runtime/observatory/tests/service/bad_reload/v1/main.dart
index f9abf8b..5b930e8 100644
--- a/runtime/observatory/tests/service/bad_reload/v1/main.dart
+++ b/runtime/observatory/tests/service/bad_reload/v1/main.dart
@@ -9,5 +9,5 @@
 
 main() {
   RawReceivePort keepAlive = new RawReceivePort();
-  print('slave isolate running');
+  print('spawned isolate running');
 }
diff --git a/runtime/observatory/tests/service/bad_reload/v2/main.dart b/runtime/observatory/tests/service/bad_reload/v2/main.dart
index 2617291..5a9b293b 100644
--- a/runtime/observatory/tests/service/bad_reload/v2/main.dart
+++ b/runtime/observatory/tests/service/bad_reload/v2/main.dart
@@ -10,5 +10,5 @@
 
 main() {
   RawReceivePort keepAlive = new RawReceivePort();
-  print('slave isolate running');
+  print('spawned isolate running');
 }
diff --git a/runtime/observatory/tests/service/bad_reload_test.dart b/runtime/observatory/tests/service/bad_reload_test.dart
index b099a56..8e9aed7 100644
--- a/runtime/observatory/tests/service/bad_reload_test.dart
+++ b/runtime/observatory/tests/service/bad_reload_test.dart
@@ -51,17 +51,17 @@
     await vm.reloadIsolates();
     expect(vm.isolates.length, 2);
 
-    // Find the slave isolate.
-    Isolate slaveIsolate =
+    // Find the spawned isolate.
+    Isolate spawnedIsolate =
         vm.isolates.firstWhere((Isolate i) => i != mainIsolate);
-    expect(slaveIsolate, isNotNull);
+    expect(spawnedIsolate, isNotNull);
 
     // Invoke test in v1.
-    String v1 = await invokeTest(slaveIsolate);
+    String v1 = await invokeTest(spawnedIsolate);
     expect(v1, 'apple');
 
     // Reload to v2.
-    var response = await slaveIsolate.reloadSources(
+    var response = await spawnedIsolate.reloadSources(
       rootLibUri: v2Uri.toString(),
     );
     // Observe that it failed.
@@ -73,7 +73,7 @@
     expect(reasonForCancelling['message'], contains('library_isnt_here_man'));
 
     // Invoke test in v2.
-    String v2 = await invokeTest(slaveIsolate);
+    String v2 = await invokeTest(spawnedIsolate);
     expect(v2, 'apple');
   }
 ];
diff --git a/runtime/observatory/tests/service/complex_reload/v1/main.dart b/runtime/observatory/tests/service/complex_reload/v1/main.dart
index ce7e29f..1e0596f 100644
--- a/runtime/observatory/tests/service/complex_reload/v1/main.dart
+++ b/runtime/observatory/tests/service/complex_reload/v1/main.dart
@@ -9,5 +9,5 @@
 
 main() {
   RawReceivePort keepAlive = new RawReceivePort();
-  print('slave isolate running');
+  print('spawned isolate running');
 }
diff --git a/runtime/observatory/tests/service/complex_reload_test.dart b/runtime/observatory/tests/service/complex_reload_test.dart
index 45d6f72..e1c6e36 100644
--- a/runtime/observatory/tests/service/complex_reload_test.dart
+++ b/runtime/observatory/tests/service/complex_reload_test.dart
@@ -53,17 +53,17 @@
     await vm.reloadIsolates();
     expect(vm.isolates.length, 2);
 
-    // Find the slave isolate.
-    Isolate slaveIsolate =
+    // Find the spawned isolate.
+    Isolate spawnedIsolate =
         vm.isolates.firstWhere((Isolate i) => i != mainIsolate);
-    expect(slaveIsolate, isNotNull);
+    expect(spawnedIsolate, isNotNull);
 
     // Invoke test in v1.
-    String v1 = await invokeTest(slaveIsolate);
+    String v1 = await invokeTest(spawnedIsolate);
     expect(v1, 'apple');
 
     // Reload to v2.
-    var response = await slaveIsolate.reloadSources(
+    var response = await spawnedIsolate.reloadSources(
       rootLibUri: v2Uri.toString(),
       packagesUri: v2PackagesUri.toString(),
     );
@@ -71,17 +71,17 @@
     expect(response['success'], isTrue);
 
     // Invoke test in v2.
-    String v2 = await invokeTest(slaveIsolate);
+    String v2 = await invokeTest(spawnedIsolate);
     expect(v2, 'fooLib');
 
     // Reload to v3.
-    response = await slaveIsolate.reloadSources(
+    response = await spawnedIsolate.reloadSources(
       rootLibUri: v3Uri.toString(),
     );
     expect(response['success'], isTrue);
 
     // Invoke test in v3.
-    String v3 = await invokeTest(slaveIsolate);
+    String v3 = await invokeTest(spawnedIsolate);
     expect(v3, 'cabbage');
   }
 ];
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 423d363..f83553e 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -22,20 +22,6 @@
 
 [ $builder_tag == asan ]
 cc/CodeImmutability: Fail, OK # Address Sanitizer turns a crash into a failure.
-cc/IsolateReload_DanglingGetter_Class: Fail # Issue 28349
-cc/IsolateReload_DanglingGetter_Instance: Fail # Issue 28349
-cc/IsolateReload_LiveStack: Fail # Issue 28349
-cc/IsolateReload_PendingSuperCall: Fail # Issue 28349
-cc/IsolateReload_SmiFastPathStubs: Fail # Issue 28349
-cc/IsolateReload_TearOff_AddArguments: Fail # Issue 28349
-cc/IsolateReload_TearOff_AddArguments2: Fail # Issue 28349
-cc/IsolateReload_TearOff_Class_Identity: Fail # Issue 28349
-cc/IsolateReload_TearOff_Instance_Equality: Fail # Issue 28349
-cc/IsolateReload_TearOff_Library_Identity: Fail # Issue 28349
-cc/IsolateReload_TearOff_List_Set: Fail # Issue 28349
-cc/IsolateReload_TypeIdentity: Fail # Issue 28349
-cc/IsolateReload_TypeIdentityGeneric: Fail # Issue 28349
-cc/IsolateReload_TypeIdentityParameter: Fail # Issue 28349
 
 [ $compiler == app_jit ]
 dart/snapshot_version_test: Fail, OK # Expects to find script snapshot relative to Dart source.
@@ -60,7 +46,6 @@
 [ $compiler == dartk ]
 cc/DartAPI_New: Fail
 cc/DartAPI_TypeGetParameterizedTypes: Crash
-cc/IsolateReload_TearOff_Parameter_Count_Mismatch: Pass, Fail # Issue 32781
 dart/redirection_type_shuffling_test/00: RuntimeError
 dart/redirection_type_shuffling_test/none: RuntimeError
 
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index cfe69b9..2356a6e 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -1062,12 +1062,18 @@
     const Register crn = ConcreteRegister(rn);
     EmitFPIntCvtOp(SCVTFD, static_cast<Register>(vd), crn, kWord);
   }
-  void fcvtzds(Register rd, VRegister vn) {
+  void fcvtzdsx(Register rd, VRegister vn) {
     ASSERT(rd != R31);
     ASSERT(rd != CSP);
     const Register crd = ConcreteRegister(rd);
     EmitFPIntCvtOp(FCVTZDS, crd, static_cast<Register>(vn));
   }
+  void fcvtzdsw(Register rd, VRegister vn) {
+    ASSERT(rd != R31);
+    ASSERT(rd != CSP);
+    const Register crd = ConcreteRegister(rd);
+    EmitFPIntCvtOp(FCVTZDS, crd, static_cast<Register>(vn), kWord);
+  }
   void fmovdd(VRegister vd, VRegister vn) { EmitFPOneSourceOp(FMOVDD, vd, vn); }
   void fabsd(VRegister vd, VRegister vn) { EmitFPOneSourceOp(FABSD, vd, vn); }
   void fnegd(VRegister vd, VRegister vn) { EmitFPOneSourceOp(FNEGD, vd, vn); }
@@ -1358,9 +1364,17 @@
     LslImmediate(dst, src, kSmiTagSize);
   }
 
-  void BranchIfNotSmi(Register reg, Label* label) { tbnz(label, reg, kSmiTag); }
+  void BranchIfNotSmi(Register reg, Label* label) {
+    ASSERT(kSmiTagMask == 1);
+    ASSERT(kSmiTag == 0);
+    tbnz(label, reg, 0);
+  }
 
-  void BranchIfSmi(Register reg, Label* label) { tbz(label, reg, kSmiTag); }
+  void BranchIfSmi(Register reg, Label* label) {
+    ASSERT(kSmiTagMask == 1);
+    ASSERT(kSmiTag == 0);
+    tbz(label, reg, 0);
+  }
 
   void Branch(const StubEntry& stub_entry,
               Register pp,
@@ -1444,6 +1458,11 @@
     kValueCanBeSmi,
   };
 
+  enum CanBeHeapPointer {
+    kValueIsNotHeapPointer,
+    kValueCanBeHeapPointer,
+  };
+
   // Storing into an object.
   void StoreIntoObject(Register object,
                        const Address& dest,
@@ -1583,6 +1602,22 @@
                       Register tmp,
                       OperandSize sz);
 
+  void AssertSmiInRange(
+      Register object,
+      CanBeHeapPointer can_be_heap_pointer = kValueIsNotHeapPointer) {
+#if defined(DEBUG)
+    Label ok;
+    if (can_be_heap_pointer == kValueCanBeHeapPointer) {
+      BranchIfNotSmi(object, &ok);
+    }
+    cmp(object, Operand(object, SXTW, 0));
+    b(&ok, EQ);
+    Stop("Smi out of range");
+
+    Bind(&ok);
+#endif
+  }
+
  private:
   AssemblerBuffer buffer_;  // Contains position independent code.
   ObjectPoolWrapper object_pool_wrapper_;
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index a41fad24..523688b 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -2576,17 +2576,73 @@
   EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(DoubleReturn, test->entry()));
 }
 
-ASSEMBLER_TEST_GENERATE(Fcvtzds, assembler) {
+ASSEMBLER_TEST_GENERATE(Fcvtzdsx, assembler) {
   __ LoadDImmediate(V0, 42.0);
-  __ fcvtzds(R0, V0);
+  __ fcvtzdsx(R0, V0);
   __ ret();
 }
 
-ASSEMBLER_TEST_RUN(Fcvtzds, test) {
+ASSEMBLER_TEST_RUN(Fcvtzdsx, test) {
   typedef int64_t (*Int64Return)() DART_UNUSED;
   EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
 }
 
+ASSEMBLER_TEST_GENERATE(Fcvtzdsw, assembler) {
+  __ LoadDImmediate(V0, 42.0);
+  __ fcvtzdsw(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtzdsw, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtzdsx_overflow, assembler) {
+  __ LoadDImmediate(V0, 1e20);
+  __ fcvtzdsx(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtzdsx_overflow, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMaxInt64, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtzdsx_overflow_negative, assembler) {
+  __ LoadDImmediate(V0, -1e20);
+  __ fcvtzdsx(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtzdsx_overflow_negative, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMinInt64, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtzdsw_overflow, assembler) {
+  __ LoadDImmediate(V0, 1e10);
+  __ fcvtzdsw(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtzdsw_overflow, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMaxInt32, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtzdsw_overflow_negative, assembler) {
+  __ LoadDImmediate(V0, -1e10);
+  __ fcvtzdsw(R0, V0);
+  __ sxtw(R0, R0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtzdsw_overflow_negative, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMinInt32, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
 ASSEMBLER_TEST_GENERATE(Scvtfdx, assembler) {
   __ LoadImmediate(R0, 42);
   __ scvtfdx(V0, R0);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 83a80ff..eb5b532 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -521,7 +521,10 @@
     return CompareImmediate(reg, Immediate(immediate));
   }
 
-  void testl(Register reg, const Immediate& imm) { testq(reg, imm); }
+  void testl(Register reg, const Immediate& imm) {
+    Immediate imm2(imm.value() & 0xffffffffll);
+    testq(reg, imm2);
+  }
   void testb(const Address& address, const Immediate& imm);
 
   void testq(Register reg, const Immediate& imm);
@@ -709,6 +712,11 @@
     kValueCanBeSmi,
   };
 
+  enum CanBeHeapPointer {
+    kValueIsNotHeapPointer,
+    kValueCanBeHeapPointer,
+  };
+
   // Destroys value.
   void StoreIntoObject(Register object,      // Object we are storing into.
                        const Address& dest,  // Where we are storing into.
@@ -932,6 +940,26 @@
                                            Register array,
                                            Register index);
 
+  void AssertSmiInRange(
+      Register object,
+      CanBeHeapPointer can_be_heap_pointer = kValueIsNotHeapPointer) {
+#if defined(DEBUG)
+    Register tmp = object == TMP ? TMP2 : TMP;
+    Label ok;
+    if (can_be_heap_pointer == kValueCanBeHeapPointer) {
+      testl(object, Immediate(kSmiTagMask));
+      ASSERT(kSmiTag == 0);
+      j(ZERO, &ok);
+    }
+    movsxd(tmp, object);
+    cmpq(tmp, object);
+    j(EQUAL, &ok);
+    Stop("Smi out of range");
+
+    Bind(&ok);
+#endif
+  }
+
   static Address VMTagAddress() {
     return Address(THR, Thread::vm_tag_offset());
   }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 25fb8a7..d710b8c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -657,12 +657,12 @@
                                         &runtime_call);
 
   __ Bind(&runtime_call);
-  __ PushObject(Object::null_object());       // Make room for the result.
-  __ pushq(RAX);                              // Push the source object.
-  __ PushObject(dst_type);  // Push the type of the destination.
-  __ pushq(RDX);            // Instantiator type arguments.
-  __ pushq(RCX);            // Function type arguments.
-  __ PushObject(dst_name);  // Push the name of the destination.
+  __ PushObject(Object::null_object());  // Make room for the result.
+  __ pushq(RAX);                         // Push the source object.
+  __ PushObject(dst_type);               // Push the type of the destination.
+  __ pushq(RDX);                         // Instantiator type arguments.
+  __ pushq(RCX);                         // Function type arguments.
+  __ PushObject(dst_name);               // Push the name of the destination.
   __ LoadUniqueObject(RAX, test_cache);
   __ pushq(RAX);
   GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index c4425ed..00e1ecf 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -1552,10 +1552,10 @@
   return Utils::IsPowerOfTwo(Utils::Abs(int_value));
 }
 
-static intptr_t RepresentationBits(Representation r) {
+static intptr_t SignificantRepresentationBits(Representation r) {
   switch (r) {
     case kTagged:
-      return kBitsPerWord - 1;
+      return 31;
     case kUnboxedInt32:
     case kUnboxedUint32:
       return 32;
@@ -1569,7 +1569,7 @@
 
 static int64_t RepresentationMask(Representation r) {
   return static_cast<int64_t>(static_cast<uint64_t>(-1) >>
-                              (64 - RepresentationBits(r)));
+                              (64 - SignificantRepresentationBits(r)));
 }
 
 static bool ToIntegerConstant(Value* value, int64_t* result) {
@@ -2130,7 +2130,8 @@
       break;
 
     case Token::kSHL: {
-      const intptr_t kMaxShift = RepresentationBits(representation()) - 1;
+      const intptr_t kMaxShift =
+          SignificantRepresentationBits(representation()) - 1;
       if (rhs == 0) {
         return left()->definition();
       } else if ((rhs < 0) || (rhs >= kMaxShift)) {
@@ -2317,8 +2318,16 @@
 }
 
 Definition* AssertBooleanInstr::Canonicalize(FlowGraph* flow_graph) {
-  if (FLAG_eliminate_type_checks && (value()->Type()->ToCid() == kBoolCid)) {
-    return value()->definition();
+  if (FLAG_eliminate_type_checks) {
+    if (value()->Type()->ToCid() == kBoolCid) {
+      return value()->definition();
+    }
+
+    // In strong mode type is already verified either by static analysis
+    // or runtime checks, so AssertBoolean just ensures that value is not null.
+    if (Isolate::Current()->strong() && !value()->Type()->is_nullable()) {
+      return value()->definition();
+    }
   }
 
   return this;
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 1b5ccc7..380601f 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -439,13 +439,13 @@
   Label done;
   Isolate* isolate = Isolate::Current();
 
-  if (isolate->type_checks() || isolate->strong()) {
+  if (isolate->type_checks()) {
     __ CompareObject(reg, Bool::True());
     __ b(&done, EQ);
     __ CompareObject(reg, Bool::False());
     __ b(&done, EQ);
   } else {
-    ASSERT(isolate->asserts());
+    ASSERT(isolate->asserts() || isolate->strong());
     __ CompareObject(reg, Object::null_instance());
     __ b(&done, NE);
   }
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 08cfa0b..3bd1061 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -437,13 +437,13 @@
   Label done;
   Isolate* isolate = Isolate::Current();
 
-  if (isolate->type_checks() || isolate->strong()) {
+  if (isolate->type_checks()) {
     __ CompareObject(reg, Bool::True());
     __ b(&done, EQ);
     __ CompareObject(reg, Bool::False());
     __ b(&done, EQ);
   } else {
-    ASSERT(isolate->asserts());
+    ASSERT(isolate->asserts() || isolate->strong());
     __ CompareObject(reg, Object::null_instance());
     __ b(&done, NE);
   }
@@ -955,9 +955,13 @@
     case kTwoByteStringCid:
     case kExternalOneByteStringCid:
     case kExternalTwoByteStringCid:
+      return CompileType::FromCid(kSmiCid);
+
     case kTypedDataInt32ArrayCid:
     case kTypedDataUint32ArrayCid:
-      return CompileType::FromCid(kSmiCid);
+      // TODO(erikcorry): Perhaps this can return a faster type.  See
+      // https://github.com/dart-lang/sdk/issues/32582
+      return CompileType::Int();
 
     default:
       UNIMPLEMENTED();
@@ -1231,7 +1235,6 @@
         default:
           UNREACHABLE();
       }
-      __ SmiTag(result);
       break;
     case kTwoByteStringCid:
     case kExternalTwoByteStringCid:
@@ -1245,12 +1248,15 @@
         default:
           UNREACHABLE();
       }
-      __ SmiTag(result);
       break;
     default:
       UNREACHABLE();
       break;
   }
+  if (representation_ == kTagged) {
+    ASSERT(can_pack_into_smi());
+    __ SmiTag(result);
+  }
 }
 
 Representation StoreIndexedInstr::RequiredInputRepresentation(
@@ -2723,18 +2729,27 @@
   if (locs.in(1).IsConstant()) {
     const Object& constant = locs.in(1).constant();
     ASSERT(constant.IsSmi());
-    // Immediate shift operation takes 6 bits for the count.
-    const intptr_t kCountLimit = 0x3F;
+    // Immediate shift operation takes 5 bits for the count.
+    const intptr_t kCountLimit = 0x1F;
+    // These should be around the same size.
+    COMPILE_ASSERT(kCountLimit + 1 == kSmiBits + 2);
     const intptr_t value = Smi::Cast(constant).Value();
     ASSERT((0 < value) && (value < kCountLimit));
     if (shift_left->can_overflow()) {
       // Check for overflow (preserve left).
-      __ LslImmediate(TMP, left, value);
-      __ cmp(left, Operand(TMP, ASR, value));
+      __ LslImmediate(TMP, left, value, kWord);
+      __ cmpw(left, Operand(TMP, ASR, value));
       __ b(deopt, NE);  // Overflow.
     }
-    // Shift for result now we know there is no overflow.
+    // Shift for result now we know there is no overflow.  This writes the full
+    // 64 bits of the output register, but unless we are in truncating mode the
+    // top bits will just be sign extension bits.
     __ LslImmediate(result, left, value);
+    if (shift_left->is_truncating()) {
+      // This preserves the invariant that Smis only use the low 32 bits of the
+      // register, the high bits being sign extension bits.
+      __ sxtw(result, result);
+    }
     return;
   }
 
@@ -2742,28 +2757,33 @@
   const Register right = locs.in(1).reg();
   Range* right_range = shift_left->right_range();
   if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) {
-    // TODO(srdjan): Implement code below for is_truncating().
     // If left is constant, we know the maximal allowed size for right.
     const Object& obj = shift_left->left()->BoundConstant();
-    if (obj.IsSmi()) {
-      const intptr_t left_int = Smi::Cast(obj).Value();
-      if (left_int == 0) {
-        __ CompareRegisters(right, ZR);
-        __ b(deopt, MI);
-        __ mov(result, ZR);
-        return;
-      }
-      const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int);
-      const bool right_needs_check =
-          !RangeUtils::IsWithin(right_range, 0, max_right - 1);
-      if (right_needs_check) {
-        __ CompareImmediate(right,
-                            reinterpret_cast<int64_t>(Smi::New(max_right)));
-        __ b(deopt, CS);
-      }
-      __ SmiUntag(TMP, right);
-      __ lslv(result, left, TMP);
+    // Even though we have a non-Smi constant on the left, we might still emit
+    // a Smi op here.  In that case the Smi check above will have deopted, so
+    // we can't reach this point. Emit a breakpoint to be sure.
+    if (!obj.IsSmi()) {
+      __ Breakpoint();
+      return;
     }
+    const intptr_t left_int = Smi::Cast(obj).Value();
+    if (left_int == 0) {
+      __ CompareRegisters(right, ZR);
+      __ b(deopt, MI);
+      __ mov(result, ZR);
+      return;
+    }
+    const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int);
+    const bool right_needs_check =
+        !RangeUtils::IsWithin(right_range, 0, max_right - 1);
+    if (right_needs_check) {
+      __ CompareImmediate(right,
+                          reinterpret_cast<int64_t>(Smi::New(max_right)));
+      __ b(deopt, CS);
+    }
+    __ SmiUntag(TMP, right);
+    __ lslv(result, left, TMP);
+    ASSERT(!shift_left->is_truncating());
     return;
   }
 
@@ -2787,7 +2807,11 @@
       __ SmiUntag(TMP, right);
       __ lslv(result, left, TMP);
     }
+    if (shift_left->is_truncating()) {
+      __ sxtw(result, result);
+    }
   } else {
+    // If we can overflow.
     if (right_needs_check) {
       ASSERT(shift_left->CanDeoptimize());
       __ CompareImmediate(right,
@@ -2795,15 +2819,16 @@
       __ b(deopt, CS);
     }
     // Left is not a constant.
-    // Check if count too large for handling it inlined.
+    // Check if count is too large for handling it inlined.
     __ SmiUntag(TMP, right);
     // Overflow test (preserve left, right, and TMP);
     const Register temp = locs.temp(0).reg();
-    __ lslv(temp, left, TMP);
-    __ asrv(TMP2, temp, TMP);
-    __ CompareRegisters(left, TMP2);
+    __ lslvw(temp, left, TMP);
+    __ asrvw(TMP2, temp, TMP);
+    __ cmpw(left, Operand(TMP2));
     __ b(deopt, NE);  // Overflow.
-    // Shift for result now we know there is no overflow.
+    // Shift for result now we know there is no overflow.  This is a 64 bit
+    // operation, so no sign extension is needed.
     __ lslv(result, left, TMP);
   }
 }
@@ -2885,18 +2910,20 @@
 
   switch (op_kind()) {
     case Token::kADD:
-      __ adds(result, left, Operand(right));
+      __ addsw(result, left, Operand(right));
       __ b(slow_path->entry_label(), VS);
+      __ sxtw(result, result);
       break;
     case Token::kSUB:
-      __ subs(result, left, Operand(right));
+      __ subsw(result, left, Operand(right));
       __ b(slow_path->entry_label(), VS);
+      __ sxtw(result, result);
       break;
     case Token::kMUL:
       __ SmiUntag(TMP, left);
-      __ mul(result, TMP, right);
-      __ smulh(TMP, TMP, right);
-      // TMP: result bits 64..127.
+      __ smull(result, TMP, right);
+      __ AsrImmediate(TMP, result, 31);
+      // TMP: result bits 31-63
       __ cmp(TMP, Operand(result, ASR, 63));
       __ b(slow_path->entry_label(), NE);
       break;
@@ -2921,8 +2948,8 @@
 
       __ SmiUntag(TMP, right);
       __ lslv(result, left, TMP);
-      __ asrv(TMP2, result, TMP);
-      __ CompareRegisters(left, TMP2);
+      __ asrvw(TMP2, result, TMP);
+      __ cmp(left, Operand(TMP2, SXTW, 0));
       __ b(slow_path->entry_label(), NE);  // Overflow.
       break;
     case Token::kSHR:
@@ -2932,6 +2959,8 @@
                           reinterpret_cast<int64_t>(Smi::New(Smi::kBits)));
       __ b(slow_path->entry_label(), CS);
 
+      __ AssertSmiInRange(left);
+      __ AssertSmiInRange(right);
       __ SmiUntag(result, right);
       __ SmiUntag(TMP, left);
       __ asrv(result, TMP, result);
@@ -2941,6 +2970,7 @@
       UNIMPLEMENTED();
   }
   __ Bind(slow_path->exit_label());
+  __ AssertSmiInRange(result, Assembler::kValueCanBeHeapPointer);
 }
 
 class CheckedSmiComparisonSlowPath : public SlowPathCode {
@@ -3131,20 +3161,28 @@
       case Token::kADD: {
         if (deopt == NULL) {
           __ AddImmediate(result, left, imm);
+          if (is_truncating()) {
+            __ sxtw(result, result);
+          }
         } else {
-          __ AddImmediateSetFlags(result, left, imm);
+          __ AddImmediateSetFlags(result, left, imm, kWord);
           __ b(deopt, VS);
+          __ sxtw(result, result);
         }
         break;
       }
       case Token::kSUB: {
         if (deopt == NULL) {
           __ AddImmediate(result, left, -imm);
+          if (is_truncating()) {
+            __ sxtw(result, result);
+          }
         } else {
           // Negating imm and using AddImmediateSetFlags would not detect the
-          // overflow when imm == kMinInt64.
-          __ SubImmediateSetFlags(result, left, imm);
+          // overflow when imm == kMinInt32.
+          __ SubImmediateSetFlags(result, left, imm, kWord);
           __ b(deopt, VS);
+          __ sxtw(result, result);
         }
         break;
       }
@@ -3152,12 +3190,14 @@
         // Keep left value tagged and untag right value.
         const intptr_t value = Smi::Cast(constant).Value();
         __ LoadImmediate(TMP, value);
-        __ mul(result, left, TMP);
+        __ smull(result, left, TMP);
         if (deopt != NULL) {
-          __ smulh(TMP, left, TMP);
-          // TMP: result bits 64..127.
+          __ AsrImmediate(TMP, result, 31);
+          // TMP: result bits 31..63.
           __ cmp(TMP, Operand(result, ASR, 63));
           __ b(deopt, NE);
+        } else if (is_truncating()) {
+          __ sxtw(result, result);
         }
         break;
       }
@@ -3168,9 +3208,10 @@
         const intptr_t shift_count =
             Utils::ShiftForPowerOfTwo(Utils::Abs(value)) + kSmiTagSize;
         ASSERT(kSmiTagSize == 1);
-        __ AsrImmediate(TMP, left, 63);
+        __ AsrImmediate(TMP, left, 31);  // All 1s or all 0s.
         ASSERT(shift_count > 1);  // 1, -1 case handled above.
         const Register temp = TMP2;
+        // Adjust so that we round to 0 instead of round down.
         __ add(temp, left, Operand(TMP, LSR, 64 - shift_count));
         ASSERT(shift_count > 0);
         __ AsrImmediate(result, temp, shift_count);
@@ -3205,6 +3246,7 @@
         UNREACHABLE();
         break;
     }
+    __ AssertSmiInRange(result);
     return;
   }
 
@@ -3213,18 +3255,26 @@
     case Token::kADD: {
       if (deopt == NULL) {
         __ add(result, left, Operand(right));
+        if (is_truncating()) {
+          __ sxtw(result, result);
+        }
       } else {
-        __ adds(result, left, Operand(right));
+        __ addsw(result, left, Operand(right));
         __ b(deopt, VS);
+        __ sxtw(result, result);
       }
       break;
     }
     case Token::kSUB: {
       if (deopt == NULL) {
         __ sub(result, left, Operand(right));
+        if (is_truncating()) {
+          __ sxtw(result, result);
+        }
       } else {
-        __ subs(result, left, Operand(right));
+        __ subsw(result, left, Operand(right));
         __ b(deopt, VS);
+        __ sxtw(result, result);
       }
       break;
     }
@@ -3232,10 +3282,13 @@
       __ SmiUntag(TMP, left);
       if (deopt == NULL) {
         __ mul(result, TMP, right);
+        if (is_truncating()) {
+          __ sxtw(result, result);
+        }
       } else {
-        __ mul(result, TMP, right);
-        __ smulh(TMP, TMP, right);
-        // TMP: result bits 64..127.
+        __ smull(result, TMP, right);
+        __ AsrImmediate(TMP, result, 31);
+        // TMP: result bits 31..63.
         __ cmp(TMP, Operand(result, ASR, 63));
         __ b(deopt, NE);
       }
@@ -3270,7 +3323,7 @@
 
       // Check the corner case of dividing the 'MIN_SMI' with -1, in which
       // case we cannot tag the result.
-      __ CompareImmediate(result, 0x4000000000000000LL);
+      __ CompareImmediate(result, 0x40000000LL);
       __ b(deopt, EQ);
       __ SmiTag(result);
       break;
@@ -3315,8 +3368,10 @@
         __ b(deopt, LT);
       }
       __ SmiUntag(TMP, right);
-      // sarl operation masks the count to 6 bits.
-      const intptr_t kCountLimit = 0x3F;
+      // The asrv operation masks the count to 6 bits, but any shift between 31
+      // and 63 gives the same result because 32 bit Smis are stored sign
+      // extended in the registers.
+      const intptr_t kCountLimit = 0x1F;
       if (!RangeUtils::OnlyLessThanOrEqualTo(right_range(), kCountLimit)) {
         __ LoadImmediate(TMP2, kCountLimit);
         __ CompareRegisters(TMP, TMP2);
@@ -3345,6 +3400,7 @@
       UNREACHABLE();
       break;
   }
+  __ AssertSmiInRange(result);
 }
 
 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(Zone* zone,
@@ -3497,10 +3553,17 @@
   ASSERT((from_representation() == kUnboxedInt32) ||
          (from_representation() == kUnboxedUint32));
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
+  const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
   LocationSummary* summary = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+      LocationSummary(zone, kNumInputs, kNumTemps,
+                      ValueFitsSmi() ? LocationSummary::kNoCall
+                                     : LocationSummary::kCallOnSlowPath);
+  // Get two distinct registers for input and output, plus a temp
+  // register for testing for overflow and allocating a Mint.
   summary->set_in(0, Location::RequiresRegister());
+  if (!ValueFitsSmi()) {
+    summary->set_temp(0, Location::RequiresRegister());
+  }
   summary->set_out(0, Location::RequiresRegister());
   return summary;
 }
@@ -3509,16 +3572,51 @@
   Register value = locs()->in(0).reg();
   Register out = locs()->out(0).reg();
   ASSERT(value != out);
+  Label done;
 
-  ASSERT(kSmiTagSize == 1);
-  // TODO(vegorov) implement and use UBFM/SBFM for this.
-  __ LslImmediate(out, value, 32);
   if (from_representation() == kUnboxedInt32) {
-    __ AsrImmediate(out, out, 32 - kSmiTagSize);
+    ASSERT(kSmiTag == 0);
+    // Signed Bitfield Insert in Zero instruction extracts the 31 significant
+    // bits from a Smi.
+    __ sbfiz(out, value, kSmiTagSize, 32 - kSmiTagSize);
+    if (ValueFitsSmi()) {
+      return;
+    }
+    Register temp = locs()->temp(0).reg();
+    __ cmp(out, Operand(value, LSL, 1));
+    __ b(&done, EQ);  // Jump if the sbfiz instruction didn't lose info.
+    BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), out,
+                                    temp);
+    __ sxtw(temp, value);
   } else {
     ASSERT(from_representation() == kUnboxedUint32);
-    __ LsrImmediate(out, out, 32 - kSmiTagSize);
+    ASSERT(kSmiTag == 0);
+    // A 32 bit positive Smi has one tag bit and one unused sign bit,
+    // leaving only 30 bits for the payload.
+    __ ubfiz(out, value, kSmiTagSize, kSmiBits);
+    if (ValueFitsSmi()) {
+      return;
+    }
+    Register temp = locs()->temp(0).reg();
+    __ TestImmediate(value, 0xc0000000);
+    __ b(&done, EQ);  // Jump if both bits are zero.
+    BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), out,
+                                    temp);
+    __ ubfiz(temp, value, 0, 32);  // Zero extend word.
   }
+
+  __ StoreToOffset(locs()->temp(0).reg(), out,
+                   Mint::value_offset() - kHeapObjectTag);
+
+#if defined(DEBUG)
+  Label skip_smi_test;
+  __ b(&skip_smi_test);
+  __ Bind(&done);
+  __ AssertSmiInRange(out, Assembler::kValueCanBeHeapPointer);
+  __ Bind(&skip_smi_test);
+#else
+  __ Bind(&done);
+#endif
 }
 
 LocationSummary* BoxInt64Instr::MakeLocationSummary(Zone* zone,
@@ -3546,7 +3644,8 @@
   }
 
   ASSERT(kSmiTag == 0);
-  __ LslImmediate(out, in, kSmiTagSize);
+  __ LslImmediate(out, in, kSmiTagSize, kWord);
+  __ sxtw(out, out);
   Label done;
   __ cmp(in, Operand(out, ASR, kSmiTagSize));
   __ b(&done, EQ);
@@ -4287,8 +4386,9 @@
   switch (op_kind()) {
     case Token::kNEGATE: {
       Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp);
-      __ subs(result, ZR, Operand(value));
+      __ subsw(result, ZR, Operand(value));
       __ b(deopt, VS);
+      __ sxtw(result, result);
       break;
     }
     case Token::kBIT_NOT:
@@ -4299,6 +4399,7 @@
     default:
       UNREACHABLE();
   }
+  __ AssertSmiInRange(result);
 }
 
 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(Zone* zone,
@@ -4350,7 +4451,7 @@
   const Register value = locs()->in(0).reg();
   const VRegister result = locs()->out(0).fpu_reg();
   __ SmiUntag(TMP, value);
-  __ scvtfdx(result, TMP);
+  __ scvtfdw(result, TMP);
 }
 
 LocationSummary* Int64ToDoubleInstr::MakeLocationSummary(Zone* zone,
@@ -4394,12 +4495,13 @@
   __ fcmpd(VTMP, VTMP);
   __ b(&do_call, VS);
 
-  __ fcvtzds(result, VTMP);
+  __ fcvtzdsx(result, VTMP);
   // Overflow is signaled with minint.
 
   // Check for overflow and that it fits into Smi.
-  __ CompareImmediate(result, 0xC000000000000000);
-  __ b(&do_call, MI);
+  __ AsrImmediate(TMP, result, 30);
+  __ cmp(TMP, Operand(result, ASR, 63));
+  __ b(&do_call, NE);
   __ SmiTag(result);
   __ b(&done);
   __ Bind(&do_call);
@@ -4416,6 +4518,7 @@
                                args_info, locs(), ICData::Handle(),
                                ICData::kStatic);
   __ Bind(&done);
+  __ AssertSmiInRange(result, Assembler::kValueCanBeHeapPointer);
 }
 
 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(Zone* zone,
@@ -4439,11 +4542,13 @@
   __ fcmpd(value, value);
   __ b(deopt, VS);
 
-  __ fcvtzds(result, value);
+  __ fcvtzdsx(result, value);
   // Check for overflow and that it fits into Smi.
-  __ CompareImmediate(result, 0xC000000000000000);
-  __ b(deopt, MI);
+  __ AsrImmediate(TMP, result, 30);
+  __ cmp(TMP, Operand(result, ASR, 63));
+  __ b(deopt, NE);
   __ SmiTag(result);
+  __ AssertSmiInRange(result);
 }
 
 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone,
@@ -4712,7 +4817,7 @@
 
   // Check the corner case of dividing the 'MIN_SMI' with -1, in which
   // case we cannot tag the result.
-  __ CompareImmediate(result_div, 0x4000000000000000);
+  __ CompareImmediate(result_div, 0x40000000);
   __ b(deopt, EQ);
   // result_mod <- left - right * result_div.
   __ msub(result_mod, TMP, result_div, result_mod);
@@ -5241,6 +5346,10 @@
   Register shifter = locs()->in(1).reg();
 
   // TODO(johnmccutchan): Use range information to avoid these checks.
+  // Assert this is a legitimate Smi in debug mode, but does not assert
+  // anything about the range relative to the bit width.
+  __ AssertSmiInRange(shifter);
+
   __ SmiUntag(TMP, shifter);
   __ CompareImmediate(TMP, 0);
   // If shift value is < 0, deoptimize.
@@ -5260,7 +5369,7 @@
 
   __ CompareImmediate(TMP, kShifterLimit);
   // If shift value is > 31, return zero.
-  __ csel(out, out, ZR, GT);
+  __ csel(out, ZR, out, GT);
 }
 
 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Zone* zone,
diff --git a/runtime/vm/compiler/backend/il_dbc.cc b/runtime/vm/compiler/backend/il_dbc.cc
index e9504a4..093c340 100644
--- a/runtime/vm/compiler/backend/il_dbc.cc
+++ b/runtime/vm/compiler/backend/il_dbc.cc
@@ -196,7 +196,7 @@
     __ Push(locs()->in(0).reg());
   }
   Isolate* isolate = Isolate::Current();
-  __ AssertBoolean((isolate->type_checks() || isolate->strong()) ? 1 : 0);
+  __ AssertBoolean(isolate->type_checks() ? 1 : 0);
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
                                  token_pos());
   compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 83661ab..86a74e8 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -312,13 +312,13 @@
   Label done;
   Isolate* isolate = Isolate::Current();
 
-  if (isolate->type_checks() || isolate->strong()) {
+  if (isolate->type_checks()) {
     __ CompareObject(reg, Bool::True());
     __ j(EQUAL, &done, Assembler::kNearJump);
     __ CompareObject(reg, Bool::False());
     __ j(EQUAL, &done, Assembler::kNearJump);
   } else {
-    ASSERT(isolate->asserts());
+    ASSERT(isolate->asserts() || isolate->strong());
     __ CompareObject(reg, Object::null_instance());
     __ j(NOT_EQUAL, &done, Assembler::kNearJump);
   }
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 9128f93..1e292ce 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -405,13 +405,13 @@
   Label done;
   Isolate* isolate = Isolate::Current();
 
-  if (isolate->type_checks() || isolate->strong()) {
+  if (isolate->type_checks()) {
     __ CompareObject(reg, Bool::True());
     __ j(EQUAL, &done, Assembler::kNearJump);
     __ CompareObject(reg, Bool::False());
     __ j(EQUAL, &done, Assembler::kNearJump);
   } else {
-    ASSERT(isolate->asserts());
+    ASSERT(isolate->asserts() || isolate->strong());
     __ CompareObject(reg, Object::null_instance());
     __ j(NOT_EQUAL, &done, Assembler::kNearJump);
   }
@@ -951,6 +951,61 @@
   }
 }
 
+class BoxAllocationSlowPath : public SlowPathCode {
+ public:
+  BoxAllocationSlowPath(Instruction* instruction,
+                        const Class& cls,
+                        Register result)
+      : instruction_(instruction), cls_(cls), result_(result) {}
+
+  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    if (Assembler::EmittingComments()) {
+      __ Comment("%s slow path allocation of %s", instruction_->DebugName(),
+                 String::Handle(cls_.ScrubbedName()).ToCString());
+    }
+    __ Bind(entry_label());
+    const Code& stub = Code::ZoneHandle(
+        compiler->zone(), StubCode::GetAllocationStubForClass(cls_));
+    const StubEntry stub_entry(stub);
+
+    LocationSummary* locs = instruction_->locs();
+
+    locs->live_registers()->Remove(Location::RegisterLocation(result_));
+
+    compiler->SaveLiveRegisters(locs);
+    compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
+                           stub_entry, RawPcDescriptors::kOther, locs);
+    compiler->AddStubCallTarget(stub);
+    __ MoveRegister(result_, RAX);
+    compiler->RestoreLiveRegisters(locs);
+    __ jmp(exit_label());
+  }
+
+  static void Allocate(FlowGraphCompiler* compiler,
+                       Instruction* instruction,
+                       const Class& cls,
+                       Register result,
+                       Register temp) {
+    if (compiler->intrinsic_mode()) {
+      __ TryAllocate(cls, compiler->intrinsic_slow_path_label(),
+                     Assembler::kFarJump, result, temp);
+    } else {
+      BoxAllocationSlowPath* slow_path =
+          new BoxAllocationSlowPath(instruction, cls, result);
+      compiler->AddSlowPathCode(slow_path);
+
+      __ TryAllocate(cls, slow_path->entry_label(), Assembler::kFarJump, result,
+                     temp);
+      __ Bind(slow_path->exit_label());
+    }
+  }
+
+ private:
+  Instruction* instruction_;
+  const Class& cls_;
+  const Register result_;
+};
+
 CompileType LoadIndexedInstr::ComputeType() const {
   switch (class_id_) {
     case kArrayCid:
@@ -978,11 +1033,13 @@
     case kTwoByteStringCid:
     case kExternalOneByteStringCid:
     case kExternalTwoByteStringCid:
-    case kTypedDataInt32ArrayCid:
-    case kTypedDataUint32ArrayCid:
       return CompileType::FromCid(kSmiCid);
 
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
     case kTypedDataInt64ArrayCid:
+      // TODO(erikcorry): Perhaps this can return a faster type.  See
+      // https://github.com/dart-lang/sdk/issues/32582
       return CompileType::Int();
 
     default:
@@ -1165,16 +1222,24 @@
 
 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Zone* zone,
                                                          bool opt) const {
+  const bool might_box = (representation() == kTagged) && !can_pack_into_smi();
   const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  const intptr_t kNumTemps = might_box ? 2 : 0;
+  LocationSummary* summary = new (zone) LocationSummary(
+      zone, kNumInputs, kNumTemps,
+      might_box ? LocationSummary::kCallOnSlowPath : LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresRegister());
   // The smi index is either untagged (element size == 1), or it is left smi
   // tagged (for all element sizes > 1).
   summary->set_in(1, index_scale() == 1 ? Location::WritableRegister()
                                         : Location::RequiresRegister());
   summary->set_out(0, Location::RequiresRegister());
+
+  if (might_box) {
+    summary->set_temp(0, Location::RequiresRegister());
+    summary->set_temp(1, Location::RequiresRegister());
+  }
+
   return summary;
 }
 
@@ -1206,7 +1271,6 @@
         default:
           UNREACHABLE();
       }
-      __ SmiTag(result);
       break;
     case kTwoByteStringCid:
     case kExternalTwoByteStringCid:
@@ -1220,12 +1284,34 @@
         default:
           UNREACHABLE();
       }
-      __ SmiTag(result);
       break;
     default:
       UNREACHABLE();
       break;
   }
+  if (representation_ == kTagged) {
+    if (can_pack_into_smi()) {
+      __ SmiTag(result);
+    } else {
+      // If the value cannot fit in a smi then allocate a mint box for it.
+      Register temp = locs()->temp(0).reg();
+      Register temp2 = locs()->temp(1).reg();
+      // Temp register needs to be manually preserved on allocation slow-path.
+      locs()->live_registers()->Add(locs()->temp(0), kUnboxedInt32);
+
+      ASSERT(temp != result);
+      __ MoveRegister(temp, result);
+      __ SmiTag(result);
+
+      Label done;
+      __ TestImmediate(temp, Immediate(0xc0000000ll));
+      __ j(ZERO, &done);
+      BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(),
+                                      result, temp2);
+      __ movq(FieldAddress(result, Mint::value_offset()), temp);
+      __ Bind(&done);
+    }
+  }
 }
 
 Representation StoreIndexedInstr::RequiredInputRepresentation(
@@ -1688,61 +1774,6 @@
   }
 }
 
-class BoxAllocationSlowPath : public SlowPathCode {
- public:
-  BoxAllocationSlowPath(Instruction* instruction,
-                        const Class& cls,
-                        Register result)
-      : instruction_(instruction), cls_(cls), result_(result) {}
-
-  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
-    if (Assembler::EmittingComments()) {
-      __ Comment("%s slow path allocation of %s", instruction_->DebugName(),
-                 String::Handle(cls_.ScrubbedName()).ToCString());
-    }
-    __ Bind(entry_label());
-    const Code& stub = Code::ZoneHandle(
-        compiler->zone(), StubCode::GetAllocationStubForClass(cls_));
-    const StubEntry stub_entry(stub);
-
-    LocationSummary* locs = instruction_->locs();
-
-    locs->live_registers()->Remove(Location::RegisterLocation(result_));
-
-    compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
-                           stub_entry, RawPcDescriptors::kOther, locs);
-    compiler->AddStubCallTarget(stub);
-    __ MoveRegister(result_, RAX);
-    compiler->RestoreLiveRegisters(locs);
-    __ jmp(exit_label());
-  }
-
-  static void Allocate(FlowGraphCompiler* compiler,
-                       Instruction* instruction,
-                       const Class& cls,
-                       Register result,
-                       Register temp) {
-    if (compiler->intrinsic_mode()) {
-      __ TryAllocate(cls, compiler->intrinsic_slow_path_label(),
-                     Assembler::kFarJump, result, temp);
-    } else {
-      BoxAllocationSlowPath* slow_path =
-          new BoxAllocationSlowPath(instruction, cls, result);
-      compiler->AddSlowPathCode(slow_path);
-
-      __ TryAllocate(cls, slow_path->entry_label(), Assembler::kFarJump, result,
-                     temp);
-      __ Bind(slow_path->exit_label());
-    }
-  }
-
- private:
-  Instruction* instruction_;
-  const Class& cls_;
-  const Register result_;
-};
-
 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(Zone* zone,
                                                               bool opt) const {
   const intptr_t kNumInputs = 2;
@@ -2664,27 +2695,32 @@
   if (locs.in(1).IsConstant()) {
     const Object& constant = locs.in(1).constant();
     ASSERT(constant.IsSmi());
-    // shlq operation masks the count to 6 bits.
-    const intptr_t kCountLimit = 0x3F;
+    // shll operation masks the count to 5 bits.
+    const intptr_t kCountLimit = 0x1F;
     const intptr_t value = Smi::Cast(constant).Value();
     ASSERT((0 < value) && (value < kCountLimit));
     if (shift_left->can_overflow()) {
       if (value == 1) {
         // Use overflow flag.
-        __ shlq(left, Immediate(1));
+        __ shll(left, Immediate(1));
         __ j(OVERFLOW, deopt);
+        __ movsxd(left, left);
         return;
       }
       // Check for overflow.
       Register temp = locs.temp(0).reg();
       __ movq(temp, left);
-      __ shlq(left, Immediate(value));
-      __ sarq(left, Immediate(value));
+      __ shll(left, Immediate(value));
+      __ sarl(left, Immediate(value));
+      __ movsxd(left, left);
       __ cmpq(left, temp);
       __ j(NOT_EQUAL, deopt);  // Overflow.
     }
     // Shift for result now we know there is no overflow.
     __ shlq(left, Immediate(value));
+    if (shift_left->is_truncating()) {
+      __ movsxd(left, left);
+    }
     return;
   }
 
@@ -2695,23 +2731,32 @@
     // TODO(srdjan): Implement code below for is_truncating().
     // If left is constant, we know the maximal allowed size for right.
     const Object& obj = shift_left->left()->BoundConstant();
-    if (obj.IsSmi()) {
-      const intptr_t left_int = Smi::Cast(obj).Value();
-      if (left_int == 0) {
-        __ CompareImmediate(right, Immediate(0));
-        __ j(NEGATIVE, deopt);
-        return;
-      }
-      const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int);
-      const bool right_needs_check =
-          !RangeUtils::IsWithin(right_range, 0, max_right - 1);
-      if (right_needs_check) {
-        __ CompareImmediate(
-            right, Immediate(reinterpret_cast<int64_t>(Smi::New(max_right))));
-        __ j(ABOVE_EQUAL, deopt);
-      }
-      __ SmiUntag(right);
-      __ shlq(left, right);
+    // Even though we have a non-Smi constant on the left, we might still emit
+    // a Smi op here.  In that case the Smi check above will have deopted, so
+    // we can't reach this point. Emit a breakpoint to be sure.
+    if (!obj.IsSmi()) {
+      __ int3();
+      return;
+    }
+    const intptr_t left_int = Smi::Cast(obj).Value();
+    if (left_int == 0) {
+      __ CompareImmediate(right, Immediate(0));
+      __ j(NEGATIVE, deopt);
+      return;
+    }
+    const intptr_t max_right = kSmiBits - Utils::HighestBit(left_int);
+    const bool right_needs_check =
+        !RangeUtils::IsWithin(right_range, 0, max_right - 1);
+    if (right_needs_check) {
+      __ CompareImmediate(
+          right, Immediate(reinterpret_cast<int64_t>(Smi::New(max_right))));
+      __ j(ABOVE_EQUAL, deopt);
+    }
+    __ AssertSmiInRange(right);
+    __ SmiUntag(right);
+    __ shlq(left, right);
+    if (shift_left->is_truncating()) {
+      __ movsxd(left, left);
     }
     return;
   }
@@ -2735,13 +2780,18 @@
       __ xorq(left, left);
       __ jmp(&done, Assembler::kNearJump);
       __ Bind(&is_not_zero);
+      __ AssertSmiInRange(right);
       __ SmiUntag(right);
       __ shlq(left, right);
       __ Bind(&done);
     } else {
+      __ AssertSmiInRange(right);
       __ SmiUntag(right);
       __ shlq(left, right);
     }
+    if (shift_left->is_truncating()) {
+      __ movsxd(left, left);
+    }
   } else {
     if (right_needs_check) {
       ASSERT(shift_left->CanDeoptimize());
@@ -2751,16 +2801,18 @@
     }
     // Left is not a constant.
     Register temp = locs.temp(0).reg();
-    // Check if count too large for handling it inlined.
-    __ movq(temp, left);
+    // Check if count is too large for handling it inlined.
+    __ movl(temp, left);
+    __ AssertSmiInRange(right);
     __ SmiUntag(right);
     // Overflow test (preserve temp and right);
-    __ shlq(left, right);
-    __ sarq(left, right);
-    __ cmpq(left, temp);
+    __ shll(temp, right);
+    __ sarl(temp, right);
+    __ cmpl(temp, left);
     __ j(NOT_EQUAL, deopt);  // Overflow.
     // Shift for result now we know there is no overflow.
     __ shlq(left, right);
+    ASSERT(!shift_left->is_truncating());
   }
 }
 
@@ -2861,19 +2913,23 @@
   switch (op_kind()) {
     case Token::kADD:
       __ movq(result, left);
-      __ addq(result, right);
+      __ addl(result, right);
       __ j(OVERFLOW, slow_path->entry_label());
+      __ movsxd(result, result);
       break;
     case Token::kSUB:
       __ movq(result, left);
-      __ subq(result, right);
+      __ subl(result, right);
       __ j(OVERFLOW, slow_path->entry_label());
+      __ movsxd(result, result);
       break;
     case Token::kMUL:
       __ movq(result, left);
+      __ AssertSmiInRange(result);
       __ SmiUntag(result);
-      __ imulq(result, right);
+      __ imull(result, right);
       __ j(OVERFLOW, slow_path->entry_label());
+      __ movsxd(result, result);
       break;
     case Token::kBIT_OR:
       ASSERT(left == result);
@@ -2894,13 +2950,15 @@
       __ j(ABOVE_EQUAL, slow_path->entry_label());
 
       __ movq(RCX, right);
+      __ AssertSmiInRange(RCX);
       __ SmiUntag(RCX);
       __ movq(result, left);
-      __ shlq(result, RCX);
+      __ shll(result, RCX);
       __ movq(TMP, result);
-      __ sarq(TMP, RCX);
-      __ cmpq(TMP, left);
+      __ sarl(TMP, RCX);
+      __ cmpl(TMP, left);
       __ j(NOT_EQUAL, slow_path->entry_label());
+      __ movsxd(result, result);
       break;
     case Token::kSHR: {
       Label shift_count_ok;
@@ -2909,6 +2967,8 @@
       __ cmpq(right, Immediate(Smi::RawValue(Smi::kBits)));
       __ j(ABOVE_EQUAL, slow_path->entry_label());
 
+      __ AssertSmiInRange(left);
+      __ AssertSmiInRange(right);
       __ movq(RCX, right);
       __ SmiUntag(RCX);
       __ movq(result, left);
@@ -3166,20 +3226,41 @@
     const int64_t imm = reinterpret_cast<int64_t>(constant.raw());
     switch (op_kind()) {
       case Token::kADD: {
-        __ AddImmediate(left, Immediate(imm));
-        if (deopt != NULL) __ j(OVERFLOW, deopt);
+        if (deopt != NULL) {
+          __ AddImmediate(left, Immediate(imm), Assembler::k32Bit);
+          __ j(OVERFLOW, deopt);
+        } else {
+          __ AddImmediate(left, Immediate(imm), Assembler::k64Bit);
+        }
+        if (deopt != NULL || is_truncating()) {
+          __ movsxd(left, left);
+        }
         break;
       }
       case Token::kSUB: {
-        __ SubImmediate(left, Immediate(imm));
-        if (deopt != NULL) __ j(OVERFLOW, deopt);
+        if (deopt != NULL) {
+          __ SubImmediate(left, Immediate(imm), Assembler::k32Bit);
+          __ j(OVERFLOW, deopt);
+        } else {
+          __ SubImmediate(left, Immediate(imm), Assembler::k64Bit);
+        }
+        if (deopt != NULL || is_truncating()) {
+          __ movsxd(left, left);
+        }
         break;
       }
       case Token::kMUL: {
         // Keep left value tagged and untag right value.
         const intptr_t value = Smi::Cast(constant).Value();
-        __ MulImmediate(left, Immediate(value));
-        if (deopt != NULL) __ j(OVERFLOW, deopt);
+        if (deopt != NULL) {
+          __ MulImmediate(left, Immediate(value), Assembler::k32Bit);
+          __ j(OVERFLOW, deopt);
+        } else {
+          __ MulImmediate(left, Immediate(value), Assembler::k64Bit);
+        }
+        if (deopt != NULL || is_truncating()) {
+          __ movsxd(left, left);
+        }
         break;
       }
       case Token::kTRUNCDIV: {
@@ -3191,7 +3272,9 @@
         ASSERT(kSmiTagSize == 1);
         Register temp = locs()->temp(0).reg();
         __ movq(temp, left);
-        __ sarq(temp, Immediate(63));
+        // Since Smis are sign extended this is enough shift to put all-1s or
+        // all-0s in the temp register.
+        __ sarq(temp, Immediate(31));
         ASSERT(shift_count > 1);  // 1, -1 case handled above.
         __ shrq(temp, Immediate(64 - shift_count));
         __ addq(left, temp);
@@ -3220,8 +3303,10 @@
       }
 
       case Token::kSHR: {
-        // sarq operation masks the count to 6 bits.
-        const intptr_t kCountLimit = 0x3F;
+        // The sarq operation masks the count to 6 bits, but any shift between
+        // 31 and 63 gives the same result because 32 bit Smis are stored sign
+        // extended in the registers.
+        const intptr_t kCountLimit = 0x1F;
         const intptr_t value = Smi::Cast(constant).Value();
         __ sarq(left,
                 Immediate(Utils::Minimum(value + kSmiTagSize, kCountLimit)));
@@ -3233,6 +3318,7 @@
         UNREACHABLE();
         break;
     }
+    __ AssertSmiInRange(left);
     return;
   }  // locs()->in(1).IsConstant().
 
@@ -3240,19 +3326,40 @@
     const Address& right = locs()->in(1).ToStackSlotAddress();
     switch (op_kind()) {
       case Token::kADD: {
-        __ addq(left, right);
-        if (deopt != NULL) __ j(OVERFLOW, deopt);
+        if (deopt != NULL) {
+          __ addl(left, right);
+          __ j(OVERFLOW, deopt);
+        } else {
+          __ addq(left, right);
+        }
+        if (deopt != NULL || is_truncating()) {
+          __ movsxd(left, left);
+        }
         break;
       }
       case Token::kSUB: {
-        __ subq(left, right);
-        if (deopt != NULL) __ j(OVERFLOW, deopt);
+        if (deopt != NULL) {
+          __ subl(left, right);
+          __ j(OVERFLOW, deopt);
+        } else {
+          __ subq(left, right);
+        }
+        if (deopt != NULL || is_truncating()) {
+          __ movsxd(left, left);
+        }
         break;
       }
       case Token::kMUL: {
         __ SmiUntag(left);
-        __ imulq(left, right);
-        if (deopt != NULL) __ j(OVERFLOW, deopt);
+        if (deopt != NULL) {
+          __ imull(left, right);
+          __ j(OVERFLOW, deopt);
+        } else {
+          __ imulq(left, right);
+        }
+        if (deopt != NULL || is_truncating()) {
+          __ movsxd(left, left);
+        }
         break;
       }
       case Token::kBIT_AND: {
@@ -3281,19 +3388,40 @@
   Register right = locs()->in(1).reg();
   switch (op_kind()) {
     case Token::kADD: {
-      __ addq(left, right);
-      if (deopt != NULL) __ j(OVERFLOW, deopt);
+      if (deopt != NULL) {
+        __ addl(left, right);
+        __ j(OVERFLOW, deopt);
+      } else {
+        __ addq(left, right);
+      }
+      if (deopt != NULL || is_truncating()) {
+        __ movsxd(left, left);
+      }
       break;
     }
     case Token::kSUB: {
-      __ subq(left, right);
-      if (deopt != NULL) __ j(OVERFLOW, deopt);
+      if (deopt != NULL) {
+        __ subl(left, right);
+        __ j(OVERFLOW, deopt);
+      } else {
+        __ subq(left, right);
+      }
+      if (deopt != NULL || is_truncating()) {
+        __ movsxd(left, left);
+      }
       break;
     }
     case Token::kMUL: {
       __ SmiUntag(left);
-      __ imulq(left, right);
-      if (deopt != NULL) __ j(OVERFLOW, deopt);
+      if (deopt != NULL) {
+        __ imull(left, right);
+        __ j(OVERFLOW, deopt);
+      } else {
+        __ imulq(left, right);
+      }
+      if (deopt != NULL || is_truncating()) {
+        __ movsxd(left, left);
+      }
       break;
     }
     case Token::kBIT_AND: {
@@ -3312,8 +3440,6 @@
       break;
     }
     case Token::kTRUNCDIV: {
-      Label not_32bit, done;
-
       Register temp = locs()->temp(0).reg();
       ASSERT(left == RAX);
       ASSERT((right != RDX) && (right != RAX));
@@ -3324,43 +3450,20 @@
         __ testq(right, right);
         __ j(ZERO, deopt);
       }
-      // Check if both operands fit into 32bits as idiv with 64bit operands
-      // requires twice as many cycles and has much higher latency.
-      // We are checking this before untagging them to avoid corner case
-      // dividing INT_MAX by -1 that raises exception because quotient is
-      // too large for 32bit register.
-      __ movsxd(temp, left);
-      __ cmpq(temp, left);
-      __ j(NOT_EQUAL, &not_32bit);
-      __ movsxd(temp, right);
-      __ cmpq(temp, right);
-      __ j(NOT_EQUAL, &not_32bit);
-
       // Both operands are 31bit smis. Divide using 32bit idiv.
       __ SmiUntag(left);
       __ SmiUntag(right);
       __ cdq();
       __ idivl(right);
-      __ movsxd(result, result);
-      __ jmp(&done);
-
-      // Divide using 64bit idiv.
-      __ Bind(&not_32bit);
-      __ SmiUntag(left);
-      __ SmiUntag(right);
-      __ cqo();         // Sign extend RAX -> RDX:RAX.
-      __ idivq(right);  //  RAX: quotient, RDX: remainder.
       // Check the corner case of dividing the 'MIN_SMI' with -1, in which
       // case we cannot tag the result.
-      __ CompareImmediate(result, Immediate(0x4000000000000000));
+      __ cmpl(result, Immediate(0x40000000));
       __ j(EQUAL, deopt);
-      __ Bind(&done);
+      __ movsxd(result, result);
       __ SmiTag(result);
       break;
     }
     case Token::kMOD: {
-      Label not_32bit, div_done;
-
       Register temp = locs()->temp(0).reg();
       ASSERT(left == RDX);
       ASSERT((right != RDX) && (right != RAX));
@@ -3371,17 +3474,6 @@
         __ testq(right, right);
         __ j(ZERO, deopt);
       }
-      // Check if both operands fit into 32bits as idiv with 64bit operands
-      // requires twice as many cycles and has much higher latency.
-      // We are checking this before untagging them to avoid corner case
-      // dividing INT_MAX by -1 that raises exception because quotient is
-      // too large for 32bit register.
-      __ movsxd(temp, left);
-      __ cmpq(temp, left);
-      __ j(NOT_EQUAL, &not_32bit);
-      __ movsxd(temp, right);
-      __ cmpq(temp, right);
-      __ j(NOT_EQUAL, &not_32bit);
       // Both operands are 31bit smis. Divide using 32bit idiv.
       __ SmiUntag(left);
       __ SmiUntag(right);
@@ -3389,16 +3481,7 @@
       __ cdq();
       __ idivl(right);
       __ movsxd(result, result);
-      __ jmp(&div_done);
 
-      // Divide using 64bit idiv.
-      __ Bind(&not_32bit);
-      __ SmiUntag(left);
-      __ SmiUntag(right);
-      __ movq(RAX, RDX);
-      __ cqo();         // Sign extend RAX -> RDX:RAX.
-      __ idivq(right);  //  RAX: quotient, RDX: remainder.
-      __ Bind(&div_done);
       //  res = left % right;
       //  if (res < 0) {
       //    if (right < 0) {
@@ -3436,7 +3519,10 @@
         __ j(LESS, deopt);
       }
       __ SmiUntag(right);
-      // sarq operation masks the count to 6 bits.
+      // The sarq operation masks the count to 6 bits, but any shift between 31
+      // and 63 gives the same result because 32 bit Smis are stored sign
+      // extended in the registers.  We check for 63 in order to take the branch
+      // more predictably.
       const intptr_t kCountLimit = 0x3F;
       if (!RangeUtils::OnlyLessThanOrEqualTo(right_range(), kCountLimit)) {
         __ CompareImmediate(right, Immediate(kCountLimit));
@@ -3649,41 +3735,52 @@
                                        GetDeoptId(), ICData::kDeoptUnboxInteger)
                                  : NULL;
   ASSERT(value == locs()->out(0).reg());
+  Label done_and_no_need_to_check_range;
+
+  ASSERT(locs()->out(0).reg() == value);
 
   if (value_cid == kSmiCid) {
+    __ AssertSmiInRange(value);
     __ SmiUntag(value);
+    return;
   } else if (value_cid == kMintCid) {
     __ movq(value, FieldAddress(value, Mint::value_offset()));
   } else if (!CanDeoptimize()) {
-    // Type information is not conclusive, but range analysis found
-    // the value to be in int64 range. Therefore it must be a smi
-    // or mint value.
-    ASSERT(is_truncating());
     Label done;
     __ SmiUntag(value);
     __ j(NOT_CARRY, &done, Assembler::kNearJump);
-    __ movq(value, Address(value, TIMES_2, Mint::value_offset()));
+    // Multiply by two in addressing mode because we erroneously
+    // untagged a pointer by dividing it by two.
+    Address value_field(value, TIMES_2, Mint::value_offset());
+    if (is_truncating()) {
+      __ movl(value, value_field);
+      __ movsxd(value, value);
+    } else {
+      __ movq(value, value_field);
+    }
     __ Bind(&done);
     return;
   } else {
-    Label done;
-    // Optimistically untag value.
-    __ SmiUntagOrCheckClass(value, kMintCid, &done);
+    __ SmiUntagOrCheckClass(value, kMintCid, &done_and_no_need_to_check_range);
     __ j(NOT_EQUAL, deopt);
-    // Undo untagging by multiplying value with 2.
+    // Multiply by two in addressing mode because we erroneously
+    // untagged a pointer by dividing it by two.
     __ movq(value, Address(value, TIMES_2, Mint::value_offset()));
-    __ Bind(&done);
   }
 
-  // TODO(vegorov): as it is implemented right now truncating unboxing would
-  // leave "garbage" in the higher word.
+  // We get here for the Mint cases, which might be out of range for an
+  // unboxed int32 output.
+
+  // TODO(vegorov): Truncating unboxing leaves garbage in the higher word.
+  // Is this the best semantics?
   if (!is_truncating() && (deopt != NULL)) {
     ASSERT(representation() == kUnboxedInt32);
-    Register temp = locs()->temp(0).reg();
+    const Register temp = locs()->temp(0).reg();
     __ movsxd(temp, value);
     __ cmpq(temp, value);
     __ j(NOT_EQUAL, deopt);
   }
+  __ Bind(&done_and_no_need_to_check_range);
 }
 
 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Zone* zone,
@@ -3691,27 +3788,61 @@
   ASSERT((from_representation() == kUnboxedInt32) ||
          (from_representation() == kUnboxedUint32));
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
+  const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
   LocationSummary* summary = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
+      LocationSummary(zone, kNumInputs, kNumTemps,
+                      ValueFitsSmi() ? LocationSummary::kNoCall
+                                     : LocationSummary::kCallOnSlowPath);
+  const bool needs_writable_input =
+      ValueFitsSmi() || (from_representation() == kUnboxedUint32);
+  summary->set_in(0, needs_writable_input ? Location::RequiresRegister()
+                                          : Location::WritableRegister());
+  if (!ValueFitsSmi()) {
+    summary->set_temp(0, Location::RequiresRegister());
+  }
+  summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput()
+                                     : Location::RequiresRegister());
   return summary;
 }
 
 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register value = locs()->in(0).reg();
   const Register out = locs()->out(0).reg();
-  ASSERT(value != out);
+  Label done;
 
-  ASSERT(kSmiTagSize == 1);
   if (from_representation() == kUnboxedInt32) {
-    __ movsxd(out, value);
+    __ MoveRegister(out, value);
+    ASSERT(kSmiTagMask == 1 && kSmiTag == 0);
+    __ addl(out, out);
+    __ movsxd(out, out);  // Does not affect flags.
   } else {
-    ASSERT(from_representation() == kUnboxedUint32);
+    // Unsigned.
     __ movl(out, value);
+    __ SmiTag(out);
   }
-  __ SmiTag(out);
+
+  if (!ValueFitsSmi()) {
+    if (from_representation() == kUnboxedInt32) {
+      __ j(NO_OVERFLOW, &done);
+    } else {
+      ASSERT(value != out);
+      __ TestImmediate(value, Immediate(0xc0000000ll));
+      __ j(ZERO, &done);
+    }
+    // Allocate a mint.
+    // Value input is a writable register and we have to inform the compiler of
+    // the type so it can be preserved untagged on the slow path
+    locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32);
+    BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), out,
+                                    locs()->temp(0).reg());
+    if (from_representation() == kUnboxedInt32) {
+      __ movsxd(value, value);
+    } else {
+      __ movl(value, value);
+    }
+    __ movq(FieldAddress(out, Mint::value_offset()), value);
+    __ Bind(&done);
+  }
 }
 
 LocationSummary* BoxInt64Instr::MakeLocationSummary(Zone* zone,
@@ -3733,15 +3864,20 @@
 void BoxInt64Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register out = locs()->out(0).reg();
   const Register value = locs()->in(0).reg();
-  __ MoveRegister(out, value);
-  __ SmiTag(out);
+  __ leaq(out, Address(value, value, TIMES_1, 0));
   if (!ValueFitsSmi()) {
     const Register temp = locs()->temp(0).reg();
     Label done;
-    __ j(NO_OVERFLOW, &done);
+    __ movq(temp, value);
+    __ sarq(temp, Immediate(30));
+    __ addq(temp, Immediate(1));
+    __ cmpq(temp, Immediate(2));
+    __ j(BELOW, &done);
+
     BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), out,
                                     temp);
     __ movq(FieldAddress(out, Mint::value_offset()), value);
+
     __ Bind(&done);
   }
 }
@@ -4303,8 +4439,9 @@
   switch (op_kind()) {
     case Token::kNEGATE: {
       Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp);
+      __ cmpq(value, Immediate(-0x80000000ll));
+      __ j(EQUAL, deopt);
       __ negq(value);
-      __ j(OVERFLOW, deopt);
       break;
     }
     case Token::kBIT_NOT:
@@ -4453,6 +4590,7 @@
 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register value = locs()->in(0).reg();
   FpuRegister result = locs()->out(0).fpu_reg();
+  __ AssertSmiInRange(value);
   __ SmiUntag(value);
   __ cvtsi2sdq(result, value);
 }
@@ -4482,14 +4620,15 @@
   ASSERT(result != value_obj);
   ASSERT(result != temp);
   __ movsd(value_double, FieldAddress(value_obj, Double::value_offset()));
-  __ cvttsd2siq(result, value_double);
+  __ cvttsd2sil(result, value_double);
   // Overflow is signalled with minint.
   Label do_call, done;
   // Check for overflow and that it fits into Smi.
-  __ movq(temp, result);
-  __ shlq(temp, Immediate(1));
+  __ movl(temp, result);
+  __ shll(temp, Immediate(1));
   __ j(OVERFLOW, &do_call, Assembler::kNearJump);
-  __ SmiTag(result);
+  ASSERT(kSmiTagShift == 1 && kSmiTag == 0);
+  __ movsxd(result, temp);
   __ jmp(&done);
   __ Bind(&do_call);
   __ pushq(value_obj);
@@ -4525,14 +4664,15 @@
   XmmRegister value = locs()->in(0).fpu_reg();
   Register temp = locs()->temp(0).reg();
 
-  __ cvttsd2siq(result, value);
+  __ cvttsd2sil(result, value);
   // Overflow is signalled with minint.
   Label do_call, done;
   // Check for overflow and that it fits into Smi.
-  __ movq(temp, result);
-  __ shlq(temp, Immediate(1));
+  __ movl(temp, result);
+  __ shll(temp, Immediate(1));
   __ j(OVERFLOW, deopt);
-  __ SmiTag(result);
+  ASSERT(kSmiTagShift == 1 && kSmiTag == 0);
+  __ movsxd(result, temp);
 }
 
 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary(Zone* zone,
@@ -4831,6 +4971,7 @@
   // Both inputs must be writable because they will be untagged.
   summary->set_in(0, Location::RegisterLocation(RAX));
   summary->set_in(1, Location::WritableRegister());
+  // Output is a pair of registers.
   summary->set_out(0, Location::Pair(Location::RegisterLocation(RAX),
                                      Location::RegisterLocation(RDX)));
   return summary;
@@ -4845,50 +4986,26 @@
   PairLocation* pair = locs()->out(0).AsPairLocation();
   Register result1 = pair->At(0).reg();
   Register result2 = pair->At(1).reg();
-  Label not_32bit, done;
-  Register temp = RDX;
-  ASSERT(left == RAX);
-  ASSERT((right != RDX) && (right != RAX));
-  ASSERT(result1 == RAX);
-  ASSERT(result2 == RDX);
   if (RangeUtils::CanBeZero(divisor_range())) {
     // Handle divide by zero in runtime.
     __ testq(right, right);
     __ j(ZERO, deopt);
   }
-  // Check if both operands fit into 32bits as idiv with 64bit operands
-  // requires twice as many cycles and has much higher latency.
-  // We are checking this before untagging them to avoid corner case
-  // dividing INT_MAX by -1 that raises exception because quotient is
-  // too large for 32bit register.
-  __ movsxd(temp, left);
-  __ cmpq(temp, left);
-  __ j(NOT_EQUAL, &not_32bit);
-  __ movsxd(temp, right);
-  __ cmpq(temp, right);
-  __ j(NOT_EQUAL, &not_32bit);
-
+  ASSERT(left == RAX);
+  ASSERT((right != RDX) && (right != RAX));
+  ASSERT(result1 == RAX);
+  ASSERT(result2 == RDX);
   // Both operands are 31bit smis. Divide using 32bit idiv.
   __ SmiUntag(left);
   __ SmiUntag(right);
   __ cdq();
   __ idivl(right);
-  __ movsxd(RAX, RAX);
-  __ movsxd(RDX, RDX);
-  __ jmp(&done);
-
-  // Divide using 64bit idiv.
-  __ Bind(&not_32bit);
-  __ SmiUntag(left);
-  __ SmiUntag(right);
-  __ cqo();         // Sign extend RAX -> RDX:RAX.
-  __ idivq(right);  //  RAX: quotient, RDX: remainder.
   // Check the corner case of dividing the 'MIN_SMI' with -1, in which
   // case we cannot tag the result.
-  __ CompareImmediate(RAX, Immediate(0x4000000000000000));
+  __ cmpl(RAX, Immediate(0x40000000));
   __ j(EQUAL, deopt);
-  __ Bind(&done);
-
+  __ movsxd(RAX, RAX);
+  __ movsxd(RDX, RDX);
   // Modulo correction (RDX).
   //  res = left % right;
   //  if (res < 0) {
@@ -4898,16 +5015,16 @@
   //      res = res + right;
   //    }
   //  }
-  Label all_done;
+  Label done;
   __ cmpq(RDX, Immediate(0));
-  __ j(GREATER_EQUAL, &all_done, Assembler::kNearJump);
+  __ j(GREATER_EQUAL, &done, Assembler::kNearJump);
   // Result is negative, adjust it.
   if ((divisor_range() == NULL) || divisor_range()->Overlaps(-1, 1)) {
     Label subtract;
     __ cmpq(right, Immediate(0));
     __ j(LESS, &subtract, Assembler::kNearJump);
     __ addq(RDX, right);
-    __ jmp(&all_done, Assembler::kNearJump);
+    __ jmp(&done, Assembler::kNearJump);
     __ Bind(&subtract);
     __ subq(RDX, right);
   } else if (divisor_range()->IsPositive()) {
@@ -4917,7 +5034,7 @@
     // Right is negative.
     __ subq(RDX, right);
   }
-  __ Bind(&all_done);
+  __ Bind(&done);
 
   __ SmiTag(RAX);
   __ SmiTag(RDX);
@@ -5259,6 +5376,7 @@
     // Code for a variable shift amount.
     // Deoptimize if shift count is > 63 or negative.
     // Sarq and shlq instructions mask the count to 6 bits.
+    __ AssertSmiInRange(RCX);
     __ SmiUntag(RCX);
     if (!IsShiftCountInRange()) {
       __ cmpq(RCX, Immediate(kMintShiftCountLimit));
@@ -5291,15 +5409,15 @@
 }
 
 CompileType BinaryUint32OpInstr::ComputeType() const {
-  return CompileType::FromCid(kSmiCid);
+  return CompileType::Int();
 }
 
 CompileType ShiftUint32OpInstr::ComputeType() const {
-  return CompileType::FromCid(kSmiCid);
+  return CompileType::Int();
 }
 
 CompileType UnaryUint32OpInstr::ComputeType() const {
-  return CompileType::FromCid(kSmiCid);
+  return CompileType::Int();
 }
 
 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Zone* zone,
@@ -5414,6 +5532,7 @@
   Label zero;
 
   // TODO(johnmccutchan): Use range information to avoid these checks.
+  __ AssertSmiInRange(shifter);
   __ SmiUntag(shifter);
   __ cmpq(shifter, Immediate(0));
   // If shift value is < 0, deoptimize.
@@ -5438,7 +5557,7 @@
 
   __ Bind(&zero);
   // Shift was greater than 31 bits, just return zero.
-  __ xorq(left, left);
+  __ xorl(left, left);
 
   // Exit path.
   __ Bind(&done);
@@ -5479,8 +5598,8 @@
     const Register out = locs()->out(0).reg();
     // Representations are bitwise equivalent but we want to normalize
     // upperbits for safety reasons.
-    // TODO(vegorov) if we ensure that we never use upperbits we could
-    // avoid this.
+    // TODO(vegorov) if we ensure that we never leave garbage in the upper bits
+    // we could avoid this.
     __ movl(out, value);
   } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) {
     // Representations are bitwise equivalent.
diff --git a/runtime/vm/compiler/backend/range_analysis_test.cc b/runtime/vm/compiler/backend/range_analysis_test.cc
index 081c7e8..175b42b 100644
--- a/runtime/vm/compiler/backend/range_analysis_test.cc
+++ b/runtime/vm/compiler/backend/range_analysis_test.cc
@@ -66,17 +66,10 @@
                 RangeBoundary::PositiveInfinity());
   TEST_RANGE_OP(Range::Shl, -1, 1, 63, 63, RangeBoundary(kMinInt64),
                 RangeBoundary::PositiveInfinity());
-  if (kBitsPerWord == 64) {
-    TEST_RANGE_OP_SMI(Range::Shl, -1, 1, 62, 62, RangeBoundary(kSmiMin),
-                      RangeBoundary(kSmiMax));
-    TEST_RANGE_OP_SMI(Range::Shl, -1, 1, 30, 30, RangeBoundary(-(1 << 30)),
-                      RangeBoundary(1 << 30));
-  } else {
-    TEST_RANGE_OP_SMI(Range::Shl, -1, 1, 30, 30, RangeBoundary(kSmiMin),
-                      RangeBoundary(kSmiMax));
-    TEST_RANGE_OP_SMI(Range::Shl, -1, 1, 62, 62, RangeBoundary(kSmiMin),
-                      RangeBoundary(kSmiMax));
-  }
+  TEST_RANGE_OP_SMI(Range::Shl, -1, 1, 30, 30, RangeBoundary(kSmiMin),
+                    RangeBoundary(kSmiMax));
+  TEST_RANGE_OP_SMI(Range::Shl, -1, 1, 62, 62, RangeBoundary(kSmiMin),
+                    RangeBoundary(kSmiMax));
   TEST_RANGE_OP(Range::Shl, 0, 100, 0, 64, RangeBoundary(0),
                 RangeBoundary::PositiveInfinity());
   TEST_RANGE_OP(Range::Shl, -100, 0, 0, 64, RangeBoundary::NegativeInfinity(),
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index 30e0407..faae4bd 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -1558,10 +1558,10 @@
 }
 
 void CallSpecializer::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) {
-// TODO(zerny): Use kUnboxedUint32 once it is fully supported/optimized.
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
+  // Note that on ARM64 the result can always be packed into a Smi, so this
+  // is never triggered.
+  // TODO(zerny): Use kUnboxedUint32 once it is fully supported/optimized.
   if (!instr->can_pack_into_smi()) instr->set_representation(kUnboxedInt64);
-#endif
 }
 
 static bool CidTestResultsContains(const ZoneGrowableArray<intptr_t>& results,
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 6e9ffcbd..2776ee8 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -195,7 +195,7 @@
       if (builder_->ReadTag() == kSomething) {
         if (detect_function_literal_initializer &&
             builder_->PeekTag() == kFunctionExpression) {
-          AlternativeReadingScope alt(builder_->reader_);
+          AlternativeReadingScope alt(&builder_->reader_);
           Tag tag = builder_->ReadTag();
           ASSERT(tag == kFunctionExpression);
           builder_->ReadPosition();  // read position.
@@ -422,10 +422,10 @@
     case kClassIndex:
       // Read class index.
       for (intptr_t i = 0; i < procedure_count_; ++i) {
-        builder_->reader_->ReadUInt32();
+        builder_->reader_.ReadUInt32();
       }
-      builder_->reader_->ReadUInt32();
-      builder_->reader_->ReadUInt32();
+      builder_->reader_.ReadUInt32();
+      builder_->reader_.ReadUInt32();
       if (++next_read_ == field) return;
     case kEnd:
       return;
@@ -510,15 +510,15 @@
     case kLibraryIndex:
       // Read library index.
       for (intptr_t i = 0; i < class_count_; ++i) {
-        builder_->reader_->ReadUInt32();
+        builder_->reader_.ReadUInt32();
       }
-      builder_->reader_->ReadUInt32();
-      builder_->reader_->ReadUInt32();
+      builder_->reader_.ReadUInt32();
+      builder_->reader_.ReadUInt32();
       for (intptr_t i = 0; i < procedure_count_; ++i) {
-        builder_->reader_->ReadUInt32();
+        builder_->reader_.ReadUInt32();
       }
-      builder_->reader_->ReadUInt32();
-      builder_->reader_->ReadUInt32();
+      builder_->reader_.ReadUInt32();
+      builder_->reader_.ReadUInt32();
       if (++next_read_ == field) return;
     case kEnd:
       return;
@@ -693,7 +693,7 @@
     return false;
   }
 
-  AlternativeReadingScope alt(builder_->reader_, &H.metadata_payloads(),
+  AlternativeReadingScope alt(&builder_->reader_, &H.metadata_payloads(),
                               md_offset - MetadataPayloadOffset);
 
   *target_name = builder_->ReadCanonicalNameReference();
@@ -771,7 +771,7 @@
     return false;
   }
 
-  AlternativeReadingScope alt(builder_->reader_, &H.metadata_payloads(),
+  AlternativeReadingScope alt(&builder_->reader_, &H.metadata_payloads(),
                               md_offset - MetadataPayloadOffset);
 
   const int kDynamicUsesBit = 1 << 0;
@@ -801,7 +801,7 @@
     return InferredTypeMetadata(kDynamicCid, true);
   }
 
-  AlternativeReadingScope alt(builder_->reader_, &H.metadata_payloads(),
+  AlternativeReadingScope alt(&builder_->reader_, &H.metadata_payloads(),
                               md_offset - MetadataPayloadOffset);
 
   const NameIndex kernel_name = builder_->ReadCanonicalNameReference();
@@ -967,7 +967,7 @@
                   TypedData::Handle(Z, class_field.KernelData());
               ASSERT(!kernel_data.IsNull());
               intptr_t field_offset = class_field.kernel_offset();
-              AlternativeReadingScope alt(builder_->reader_, &kernel_data,
+              AlternativeReadingScope alt(&builder_->reader_, &kernel_data,
                                           field_offset);
               FieldHelper field_helper(builder_);
               field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
@@ -1169,7 +1169,7 @@
         TypedData& kernel_data = TypedData::Handle(Z, class_field.KernelData());
         ASSERT(!kernel_data.IsNull());
         intptr_t field_offset = class_field.kernel_offset();
-        AlternativeReadingScope alt(builder_->reader_, &kernel_data,
+        AlternativeReadingScope alt(&builder_->reader_, &kernel_data,
                                     field_offset);
         FieldHelper field_helper(builder_);
         field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
@@ -1251,9 +1251,9 @@
   function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kBody);
 
   if (builder_->ReadTag() == kSomething) {
-    PositionScope scope(builder_->reader_);
+    PositionScope scope(&builder_->reader_);
     VisitStatement();  // Read body
-    first_body_token_position_ = builder_->reader_->min_position();
+    first_body_token_position_ = builder_->reader_.min_position();
   }
 
   // Ensure that :await_jump_var, :await_ctx_var, :async_op and
@@ -1529,7 +1529,7 @@
       return;
     }
     case kLet: {
-      PositionScope scope(builder_->reader_);
+      PositionScope scope(&builder_->reader_);
       intptr_t offset =
           builder_->ReaderOffset() - 1;  // -1 to include tag byte.
 
@@ -1538,8 +1538,8 @@
       VisitVariableDeclaration();  // read variable declaration.
       VisitExpression();           // read expression.
 
-      ExitScope(builder_->reader_->min_position(),
-                builder_->reader_->max_position());
+      ExitScope(builder_->reader_.min_position(),
+                builder_->reader_.max_position());
       return;
     }
     case kBigIntLiteral:
@@ -1616,7 +1616,7 @@
       VisitExpression();  // read expression.
       return;
     case kBlock: {
-      PositionScope scope(builder_->reader_);
+      PositionScope scope(&builder_->reader_);
       intptr_t offset =
           builder_->ReaderOffset() - 1;  // -1 to include tag byte.
 
@@ -1628,15 +1628,15 @@
         VisitStatement();  // read ith statement.
       }
 
-      ExitScope(builder_->reader_->min_position(),
-                builder_->reader_->max_position());
+      ExitScope(builder_->reader_.min_position(),
+                builder_->reader_.max_position());
       return;
     }
     case kEmptyStatement:
       return;
     case kAssertBlock:
       if (I->asserts()) {
-        PositionScope scope(builder_->reader_);
+        PositionScope scope(&builder_->reader_);
         intptr_t offset =
             builder_->ReaderOffset() - 1;  // -1 to include tag byte.
 
@@ -1648,8 +1648,8 @@
           VisitStatement();  // read ith statement.
         }
 
-        ExitScope(builder_->reader_->min_position(),
-                  builder_->reader_->max_position());
+        ExitScope(builder_->reader_.min_position(),
+                  builder_->reader_.max_position());
       } else {
         builder_->SkipStatementList();
       }
@@ -1695,7 +1695,7 @@
       --depth_.loop_;
       return;
     case kForStatement: {
-      PositionScope scope(builder_->reader_);
+      PositionScope scope(&builder_->reader_);
 
       intptr_t offset =
           builder_->ReaderOffset() - 1;  // -1 to include tag byte.
@@ -1720,13 +1720,13 @@
       }
       VisitStatement();  // read body.
 
-      ExitScope(position, builder_->reader_->max_position());
+      ExitScope(position, builder_->reader_.max_position());
       --depth_.loop_;
       return;
     }
     case kForInStatement:
     case kAsyncForInStatement: {
-      PositionScope scope(builder_->reader_);
+      PositionScope scope(&builder_->reader_);
 
       intptr_t start_offset =
           builder_->ReaderOffset() - 1;  // -1 to include tag byte.
@@ -1747,17 +1747,17 @@
       EnterScope(start_offset);
 
       {
-        AlternativeReadingScope alt(builder_->reader_, offset);
+        AlternativeReadingScope alt(&builder_->reader_, offset);
         VisitVariableDeclaration();  // read variable.
       }
       VisitStatement();  // read body.
 
       if (!body_position.IsReal()) {
-        body_position = builder_->reader_->min_position();
+        body_position = builder_->reader_.min_position();
       }
       // TODO(jensj): From kernel_binary.cc
       // forinstmt->variable_->set_end_position(forinstmt->position_);
-      ExitScope(body_position, builder_->reader_->max_position());
+      ExitScope(body_position, builder_->reader_.max_position());
       --depth_.loop_;
       --depth_.for_in_;
       return;
@@ -1820,7 +1820,7 @@
       intptr_t catch_count =
           builder_->ReadListLength();  // read number of catches.
       for (intptr_t i = 0; i < catch_count; ++i) {
-        PositionScope scope(builder_->reader_);
+        PositionScope scope(&builder_->reader_);
         intptr_t offset = builder_->ReaderOffset();  // Catch has no tag.
 
         EnterScope(offset);
@@ -1837,8 +1837,8 @@
         }
         VisitStatement();  // read body.
 
-        ExitScope(builder_->reader_->min_position(),
-                  builder_->reader_->max_position());
+        ExitScope(builder_->reader_.min_position(),
+                  builder_->reader_.max_position());
       }
       --depth_.catch_;
       return;
@@ -1918,7 +1918,7 @@
 }
 
 void StreamingScopeBuilder::VisitVariableDeclaration() {
-  PositionScope scope(builder_->reader_);
+  PositionScope scope(&builder_->reader_);
 
   intptr_t kernel_offset_no_tag = builder_->ReaderOffset();
   VariableDeclarationHelper helper(builder_);
@@ -1939,7 +1939,7 @@
 
   // Go to next token position so it ends *after* the last potentially
   // debuggable position in the initializer.
-  TokenPosition end_position = builder_->reader_->max_position();
+  TokenPosition end_position = builder_->reader_.max_position();
   if (end_position.IsReal()) {
     end_position.Next();
   }
@@ -2100,7 +2100,7 @@
 
   int num_type_params = 0;
   {
-    AlternativeReadingScope _(builder_->reader_);
+    AlternativeReadingScope _(&builder_->reader_);
     num_type_params = builder_->ReadListLength();
   }
   // Adding this scope here informs the type translator the type parameters of
@@ -3823,7 +3823,7 @@
   ASSERT(!kernel_data.IsNull());
 
   // Temporarily go to the variable declaration, read the name.
-  AlternativeReadingScope alt(reader_, &kernel_data, kernel_offset);
+  AlternativeReadingScope alt(&reader_, &kernel_data, kernel_offset);
   VariableDeclarationHelper helper(this);
   helper.ReadUntilIncluding(VariableDeclarationHelper::kNameIndex);
   return helper.name_index_;
@@ -3934,7 +3934,7 @@
     ZoneGrowableArray<const Instance*>* default_values =
         new ZoneGrowableArray<const Instance*>(Z, optional_parameter_count);
 
-    AlternativeReadingScope alt(reader_);
+    AlternativeReadingScope alt(&reader_);
     FunctionNodeHelper function_node_helper(this);
     function_node_helper.ReadUntilExcluding(
         FunctionNodeHelper::kPositionalParameters);
@@ -4031,7 +4031,7 @@
   // Start by getting the position of the constructors initializer.
   intptr_t initializers_offset = -1;
   {
-    AlternativeReadingScope alt(reader_);
+    AlternativeReadingScope alt(&reader_);
     SkipFunctionNode();  // read constructors function node.
     initializers_offset = ReaderOffset();
   }
@@ -4044,7 +4044,7 @@
   // (i.e. has a single initializer being of type kRedirectingInitializer).
   bool is_redirecting_constructor = false;
   {
-    AlternativeReadingScope alt(reader_, initializers_offset);
+    AlternativeReadingScope alt(&reader_, initializers_offset);
     intptr_t list_length = ReadListLength();  // read initializers list length.
     bool no_field_initializers = true;
     for (intptr_t i = 0; i < list_length; ++i) {
@@ -4067,7 +4067,7 @@
         TypedData& kernel_data = TypedData::Handle(Z, class_field.KernelData());
         ASSERT(!kernel_data.IsNull());
         intptr_t field_offset = class_field.kernel_offset();
-        AlternativeReadingScope alt(reader_, &kernel_data, field_offset);
+        AlternativeReadingScope alt(&reader_, &kernel_data, field_offset);
         FieldHelper field_helper(this);
         field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
         Tag initializer_tag = ReadTag();  // read first part of initializer.
@@ -4088,7 +4088,7 @@
   //     A(this.x) : super(expr), y = (expr);
   //   }
   {
-    AlternativeReadingScope alt(reader_, initializers_offset);
+    AlternativeReadingScope alt(&reader_, initializers_offset);
     intptr_t list_length = ReadListLength();  // read initializers list length.
     for (intptr_t i = 0; i < list_length; ++i) {
       Tag tag = ReadTag();
@@ -4308,7 +4308,7 @@
     if (!target.NeedsArgumentTypeChecks(I)) {
       // Tearoffs of static methods needs to perform arguments checks since
       // static methods they forward to don't do it themselves.
-      AlternativeReadingScope _(reader_);
+      AlternativeReadingScope _(&reader_);
       body += BuildArgumentTypeChecks();
     } else {
       // Check if parent function was annotated with no-dynamic-invocations.
@@ -4318,7 +4318,7 @@
       if (!attrs.has_dynamic_invocations) {
         // If it was then we might need to build some checks in the
         // tear-off.
-        AlternativeReadingScope _(reader_);
+        AlternativeReadingScope _(&reader_);
         body +=
             BuildArgumentTypeChecks(kTypeChecksForNoDynamicInvocationsTearOff);
       }
@@ -4426,7 +4426,7 @@
   function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
 
   if (function.NeedsArgumentTypeChecks(I)) {
-    AlternativeReadingScope _(reader_);
+    AlternativeReadingScope _(&reader_);
     body += BuildArgumentTypeChecks();
   }
 
@@ -4885,7 +4885,7 @@
       FunctionNodeHelper::kPositionalParameters);
   intptr_t first_parameter_offset = -1;
   {
-    AlternativeReadingScope alt(reader_);
+    AlternativeReadingScope alt(&reader_);
     intptr_t list_length = ReadListLength();  // read number of positionals.
     if (list_length > 0) {
       first_parameter_offset = ReaderOffset() + data_program_offset_;
@@ -4928,7 +4928,7 @@
   // If we run in checked mode or strong mode, we have to check the type of the
   // passed arguments.
   if (dart_function.NeedsArgumentTypeChecks(I)) {
-    AlternativeReadingScope _(reader_);
+    AlternativeReadingScope _(&reader_);
     SetOffset(type_parameters_offset);
     body += BuildArgumentTypeChecks();
   }
@@ -5119,7 +5119,7 @@
   switch (function.kind()) {
     case RawFunction::kImplicitClosureFunction:
     case RawFunction::kRegularFunction: {
-      AlternativeReadingScope alt(reader_);
+      AlternativeReadingScope alt(&reader_);
       ReadUntilFunctionNode(parsed_function());  // read until function node.
     }
     default: {}
@@ -5356,45 +5356,45 @@
 }
 
 intptr_t StreamingFlowGraphBuilder::ReaderOffset() {
-  return reader_->offset();
+  return reader_.offset();
 }
 
 void StreamingFlowGraphBuilder::SetOffset(intptr_t offset) {
-  reader_->set_offset(offset);
+  reader_.set_offset(offset);
 }
 
 void StreamingFlowGraphBuilder::SkipBytes(intptr_t bytes) {
-  reader_->set_offset(ReaderOffset() + bytes);
+  reader_.set_offset(ReaderOffset() + bytes);
 }
 
 bool StreamingFlowGraphBuilder::ReadBool() {
-  return reader_->ReadBool();
+  return reader_.ReadBool();
 }
 
 uint8_t StreamingFlowGraphBuilder::ReadByte() {
-  return reader_->ReadByte();
+  return reader_.ReadByte();
 }
 
 uint32_t StreamingFlowGraphBuilder::ReadUInt() {
-  return reader_->ReadUInt();
+  return reader_.ReadUInt();
 }
 
 uint32_t StreamingFlowGraphBuilder::ReadUInt32() {
-  return reader_->ReadUInt32();
+  return reader_.ReadUInt32();
 }
 
 uint32_t StreamingFlowGraphBuilder::PeekUInt() {
-  AlternativeReadingScope alt(reader_);
-  return reader_->ReadUInt();
+  AlternativeReadingScope alt(&reader_);
+  return reader_.ReadUInt();
 }
 
 uint32_t StreamingFlowGraphBuilder::PeekListLength() {
-  AlternativeReadingScope alt(reader_);
-  return reader_->ReadListLength();
+  AlternativeReadingScope alt(&reader_);
+  return reader_.ReadListLength();
 }
 
 intptr_t StreamingFlowGraphBuilder::ReadListLength() {
-  return reader_->ReadListLength();
+  return reader_.ReadListLength();
 }
 
 StringIndex StreamingFlowGraphBuilder::ReadStringReference() {
@@ -5402,7 +5402,7 @@
 }
 
 NameIndex StreamingFlowGraphBuilder::ReadCanonicalNameReference() {
-  return reader_->ReadCanonicalNameReference();
+  return reader_.ReadCanonicalNameReference();
 }
 
 StringIndex StreamingFlowGraphBuilder::ReadNameAsStringIndex() {
@@ -6077,7 +6077,7 @@
 }
 
 TokenPosition StreamingFlowGraphBuilder::ReadPosition(bool record) {
-  TokenPosition position = reader_->ReadPosition();
+  TokenPosition position = reader_.ReadPosition();
   if (record) {
     record_token_position(position);
   }
@@ -6099,11 +6099,11 @@
 }
 
 Tag StreamingFlowGraphBuilder::ReadTag(uint8_t* payload) {
-  return reader_->ReadTag(payload);
+  return reader_.ReadTag(payload);
 }
 
 Tag StreamingFlowGraphBuilder::PeekTag(uint8_t* payload) {
-  return reader_->PeekTag(payload);
+  return reader_.PeekTag(payload);
 }
 
 void StreamingFlowGraphBuilder::loop_depth_inc() {
@@ -6209,7 +6209,7 @@
 
 Tag StreamingFlowGraphBuilder::PeekArgumentsFirstPositionalTag() {
   // read parts of arguments, then go back to before doing so.
-  AlternativeReadingScope alt(reader_);
+  AlternativeReadingScope alt(&reader_);
   ReadUInt();  // read number of arguments.
 
   SkipListOfDartTypes();  // Read list of types.
@@ -6227,7 +6227,7 @@
 const TypeArguments& StreamingFlowGraphBuilder::PeekArgumentsInstantiatedType(
     const Class& klass) {
   // read parts of arguments, then go back to before doing so.
-  AlternativeReadingScope alt(reader_);
+  AlternativeReadingScope alt(&reader_);
   ReadUInt();                               // read argument count.
   intptr_t list_length = ReadListLength();  // read types list length.
   return T.BuildInstantiatedTypeArguments(klass, list_length);  // read types.
@@ -6498,7 +6498,7 @@
     intptr_t target_context_depth) {
   // TranslateFinallyFinalizers can move the readers offset.
   // Save the current position and restore it afterwards.
-  AlternativeReadingScope alt(reader_);
+  AlternativeReadingScope alt(&reader_);
   return flow_graph_builder_->TranslateFinallyFinalizers(outer_finally,
                                                          target_context_depth);
 }
@@ -6649,7 +6649,7 @@
   SkipListOfDartTypes();  // read list of types.
 
   {
-    AlternativeReadingScope _(reader_);
+    AlternativeReadingScope _(&reader_);
     if (positional_count == NULL) positional_count = &dummy;
     *positional_count = ReadListLength();  // read length of expression list
   }
@@ -7322,7 +7322,7 @@
   intptr_t type_args_len = 0;
   LocalVariable* type_arguments_temp = NULL;
   if (I->reify_generic_functions()) {
-    AlternativeReadingScope alt(reader_);
+    AlternativeReadingScope alt(&reader_);
     SkipExpression();                         // skip receiver
     SkipName();                               // skip method name
     ReadUInt();                               // read argument count.
@@ -7465,7 +7465,7 @@
   Fragment instructions;
   intptr_t type_args_len = 0;
   if (I->reify_generic_functions()) {
-    AlternativeReadingScope alt(reader_);
+    AlternativeReadingScope alt(&reader_);
     SkipExpression();                         // skip receiver
     ReadCanonicalNameReference();             // skip target reference
     ReadUInt();                               // read argument count.
@@ -7531,7 +7531,7 @@
 
   intptr_t type_args_len = 0;
   if (I->reify_generic_functions()) {
-    AlternativeReadingScope alt(reader_);
+    AlternativeReadingScope alt(&reader_);
     SkipName();                        // skip method name
     ReadUInt();                        // read argument count.
     type_args_len = ReadListLength();  // read types list length.
@@ -7546,7 +7546,7 @@
   intptr_t argument_count;
   Array& argument_names = Array::Handle(Z);
   {
-    AlternativeReadingScope alt(reader_);
+    AlternativeReadingScope alt(&reader_);
     argument_count = ReadUInt();
     SkipListOfDartTypes();
 
@@ -7635,7 +7635,7 @@
     Fragment instructions;
 
     if (I->reify_generic_functions()) {
-      AlternativeReadingScope alt(reader_);
+      AlternativeReadingScope alt(&reader_);
       ReadUInt();                               // read argument count.
       intptr_t list_length = ReadListLength();  // read types list length.
       if (list_length > 0) {
@@ -7727,7 +7727,7 @@
     instructions += TranslateInstantiatedTypeArguments(type_arguments);
     instructions += PushArgument();
   } else if (!special_case_identical && I->reify_generic_functions()) {
-    AlternativeReadingScope alt(reader_);
+    AlternativeReadingScope alt(&reader_);
     ReadUInt();                               // read argument count.
     intptr_t list_length = ReadListLength();  // read types list length.
     if (list_length > 0) {
@@ -9710,7 +9710,7 @@
   // Step a) Create array of [TypeParameter] objects (without bound).
   type_parameters = TypeArguments::New(type_parameter_count);
   {
-    AlternativeReadingScope alt(reader_);
+    AlternativeReadingScope alt(&reader_);
     for (intptr_t i = 0; i < type_parameter_count; i++) {
       TypeParameterHelper helper(this);
       helper.Finish();
@@ -9987,55 +9987,55 @@
 }
 
 intptr_t StreamingFlowGraphBuilder::SourceTableSize() {
-  AlternativeReadingScope alt(reader_);
-  intptr_t library_count = reader_->ReadFromIndexNoReset(
-      reader_->size(), LibraryCountFieldCountFromEnd, 1, 0);
-  intptr_t source_table_offset = reader_->ReadFromIndexNoReset(
-      reader_->size(),
+  AlternativeReadingScope alt(&reader_);
+  intptr_t library_count = reader_.ReadFromIndexNoReset(
+      reader_.size(), LibraryCountFieldCountFromEnd, 1, 0);
+  intptr_t source_table_offset = reader_.ReadFromIndexNoReset(
+      reader_.size(),
       LibraryCountFieldCountFromEnd + 1 + library_count + 1 +
           SourceTableFieldCountFromFirstLibraryOffset,
       1, 0);
   SetOffset(source_table_offset);  // read source table offset.
-  return reader_->ReadUInt32();    // read source table size.
+  return reader_.ReadUInt32();     // read source table size.
 }
 
 intptr_t StreamingFlowGraphBuilder::GetOffsetForSourceInfo(intptr_t index) {
-  AlternativeReadingScope alt(reader_);
-  intptr_t library_count = reader_->ReadFromIndexNoReset(
-      reader_->size(), LibraryCountFieldCountFromEnd, 1, 0);
-  intptr_t source_table_offset = reader_->ReadFromIndexNoReset(
-      reader_->size(),
+  AlternativeReadingScope alt(&reader_);
+  intptr_t library_count = reader_.ReadFromIndexNoReset(
+      reader_.size(), LibraryCountFieldCountFromEnd, 1, 0);
+  intptr_t source_table_offset = reader_.ReadFromIndexNoReset(
+      reader_.size(),
       LibraryCountFieldCountFromEnd + 1 + library_count + 1 +
           SourceTableFieldCountFromFirstLibraryOffset,
       1, 0);
-  intptr_t next_field_offset = reader_->ReadUInt32();
+  intptr_t next_field_offset = reader_.ReadUInt32();
   SetOffset(source_table_offset);
-  intptr_t size = reader_->ReadUInt32();  // read source table size.
+  intptr_t size = reader_.ReadUInt32();  // read source table size.
 
-  return reader_->ReadFromIndexNoReset(next_field_offset, 0, size, index);
+  return reader_.ReadFromIndexNoReset(next_field_offset, 0, size, index);
 }
 
 String& StreamingFlowGraphBuilder::SourceTableUriFor(intptr_t index) {
-  AlternativeReadingScope alt(reader_);
+  AlternativeReadingScope alt(&reader_);
   SetOffset(GetOffsetForSourceInfo(index));
   intptr_t size = ReadUInt();  // read uri List<byte> size.
-  return H.DartString(reader_->CopyDataIntoZone(Z, ReaderOffset(), size), size,
+  return H.DartString(reader_.CopyDataIntoZone(Z, ReaderOffset(), size), size,
                       Heap::kOld);
 }
 
 String& StreamingFlowGraphBuilder::GetSourceFor(intptr_t index) {
-  AlternativeReadingScope alt(reader_);
+  AlternativeReadingScope alt(&reader_);
   SetOffset(GetOffsetForSourceInfo(index));
   SkipBytes(ReadUInt());       // skip uri.
   intptr_t size = ReadUInt();  // read source List<byte> size.
-  return H.DartString(reader_->CopyDataIntoZone(Z, ReaderOffset(), size), size,
+  return H.DartString(reader_.CopyDataIntoZone(Z, ReaderOffset(), size), size,
                       Heap::kOld);
 }
 
 RawTypedData* StreamingFlowGraphBuilder::GetLineStartsFor(intptr_t index) {
   // Line starts are delta encoded. So get the max delta first so that we
   // can store them as tighly as possible.
-  AlternativeReadingScope alt(reader_);
+  AlternativeReadingScope alt(&reader_);
   SetOffset(GetOffsetForSourceInfo(index));
   SkipBytes(ReadUInt());                         // skip uri.
   SkipBytes(ReadUInt());                         // skip source.
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 36c1833..6881cc6 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -1010,7 +1010,7 @@
       : flow_graph_builder_(flow_graph_builder),
         translation_helper_(flow_graph_builder->translation_helper_),
         zone_(flow_graph_builder->zone_),
-        reader_(new Reader(data)),
+        reader_(data),
         script_(Script::Handle(zone_, parsed_function()->function().script())),
         constant_evaluator_(this),
         type_translator_(this, /* finalize= */ true),
@@ -1032,7 +1032,7 @@
       : flow_graph_builder_(NULL),
         translation_helper_(*translation_helper),
         zone_(zone),
-        reader_(new Reader(data_buffer, buffer_length)),
+        reader_(data_buffer, buffer_length),
         script_(Script::Handle(zone_)),
         constant_evaluator_(this),
         type_translator_(this, /* finalize= */ true),
@@ -1054,7 +1054,7 @@
       : flow_graph_builder_(NULL),
         translation_helper_(*translation_helper),
         zone_(zone),
-        reader_(new Reader(data)),
+        reader_(data),
         script_(script),
         constant_evaluator_(this),
         type_translator_(this, /* finalize= */ true),
@@ -1068,7 +1068,7 @@
         procedure_attributes_metadata_helper_(this),
         metadata_scanned_(false) {}
 
-  ~StreamingFlowGraphBuilder() { delete reader_; }
+  ~StreamingFlowGraphBuilder() {}
 
   FlowGraph* BuildGraph(intptr_t kernel_offset);
 
@@ -1174,7 +1174,7 @@
   void record_yield_position(TokenPosition position);
   Tag ReadTag(uint8_t* payload = NULL);
   Tag PeekTag(uint8_t* payload = NULL);
-  uint8_t ReadFlags() { return reader_->ReadFlags(); }
+  uint8_t ReadFlags() { return reader_.ReadFlags(); }
 
   void loop_depth_inc();
   void loop_depth_dec();
@@ -1436,7 +1436,7 @@
   FlowGraphBuilder* flow_graph_builder_;
   TranslationHelper& translation_helper_;
   Zone* zone_;
-  Reader* reader_;
+  Reader reader_;
   const Script& script_;
   StreamingConstantEvaluator constant_evaluator_;
   StreamingDartTypeTranslator type_translator_;
diff --git a/runtime/vm/compiler/intrinsifier_arm64.cc b/runtime/vm/compiler/intrinsifier_arm64.cc
index 4da90f0..3625729 100644
--- a/runtime/vm/compiler/intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/intrinsifier_arm64.cc
@@ -265,8 +265,9 @@
 void Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);  // Checks two smis.
-  __ adds(R0, R0, Operand(R1));                     // Adds.
+  __ addsw(R0, R0, Operand(R1));                    // Adds.
   __ b(&fall_through, VS);                          // Fall-through on overflow.
+  __ sxtw(R0, R0);  // Sign extend - flags not affected.
   __ ret();
   __ Bind(&fall_through);
 }
@@ -278,8 +279,9 @@
 void Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
-  __ subs(R0, R0, Operand(R1));  // Subtract.
-  __ b(&fall_through, VS);       // Fall-through on overflow.
+  __ subsw(R0, R0, Operand(R1));  // Subtract.
+  __ b(&fall_through, VS);        // Fall-through on overflow.
+  __ sxtw(R0, R0);                // Sign extend - flags not affected.
   __ ret();
   __ Bind(&fall_through);
 }
@@ -287,8 +289,9 @@
 void Intrinsifier::Integer_sub(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
-  __ subs(R0, R1, Operand(R0));  // Subtract.
-  __ b(&fall_through, VS);       // Fall-through on overflow.
+  __ subsw(R0, R1, Operand(R0));  // Subtract.
+  __ b(&fall_through, VS);        // Fall-through on overflow.
+  __ sxtw(R0, R0);                // Sign extend - flags not affected.
   __ ret();
   __ Bind(&fall_through);
 }
@@ -299,9 +302,9 @@
   TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
   __ SmiUntag(R0);  // Untags R6. We only want result shifted by one.
 
-  __ mul(TMP, R0, R1);
-  __ smulh(TMP2, R0, R1);
-  // TMP: result bits 64..127.
+  __ smull(TMP, R0, R1);
+  __ AsrImmediate(TMP2, TMP, 31);
+  // TMP: result bits 31..63.
   __ cmp(TMP2, Operand(TMP, ASR, 63));
   __ b(&fall_through, NE);
   __ mov(R0, TMP);
@@ -417,7 +420,7 @@
 
   // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
   // cannot tag the result.
-  __ CompareImmediate(R0, 0x4000000000000000);
+  __ CompareImmediate(R0, 0x40000000);
   __ b(&fall_through, EQ);
   __ SmiTag(R0);  // Not equal. Okay to tag and return.
   __ ret();       // Return.
@@ -428,8 +431,9 @@
   Label fall_through;
   __ ldr(R0, Address(SP, +0 * kWordSize));  // Grab first argument.
   __ BranchIfNotSmi(R0, &fall_through);
-  __ negs(R0, R0);
+  __ negsw(R0, R0);
   __ b(&fall_through, VS);
+  __ sxtw(R0, R0);  // Sign extend - flags not affected.
   __ ret();
   __ Bind(&fall_through);
 }
@@ -488,9 +492,9 @@
   // Check if count too large for handling it inlined.
   __ SmiUntag(TMP, right);  // SmiUntag right into TMP.
   // Overflow test (preserve left, right, and TMP);
-  __ lslv(temp, left, TMP);
-  __ asrv(TMP2, temp, TMP);
-  __ CompareRegisters(left, TMP2);
+  __ lslvw(temp, left, TMP);
+  __ asrvw(TMP2, temp, TMP);
+  __ cmpw(left, Operand(TMP2));
   __ b(&fall_through, NE);  // Overflow.
   // Shift for result now we know there is no overflow.
   __ lslv(result, left, TMP);
@@ -563,6 +567,7 @@
 
   __ CompareClassId(R0, kDoubleCid);
   __ b(&fall_through, EQ);
+  __ AssertSmiInRange(R1);
   __ LoadObject(R0, Bool::False());  // Smi == Mint -> false.
   __ ret();
 
@@ -573,6 +578,7 @@
   __ b(&fall_through, NE);
   // Receiver is Mint, return false if right is Smi.
   __ BranchIfNotSmi(R0, &fall_through);
+  __ AssertSmiInRange(R0);
   __ LoadObject(R0, Bool::False());
   __ ret();
   // TODO(srdjan): Implement Mint == Mint comparison.
@@ -1495,11 +1501,12 @@
   __ fcmpd(V0, V0);
   __ b(&fall_through, VS);
 
-  __ fcvtzds(R0, V0);
+  __ fcvtzdsx(R0, V0);
   // Overflow is signaled with minint.
   // Check for overflow and that it fits into Smi.
-  __ CompareImmediate(R0, 0xC000000000000000);
-  __ b(&fall_through, MI);
+  __ AsrImmediate(TMP, R0, 30);
+  __ cmp(TMP, Operand(R0, ASR, 63));
+  __ b(&fall_through, NE);
   __ SmiTag(R0);
   __ ret();
   __ Bind(&fall_through);
@@ -1516,10 +1523,10 @@
   __ fcmpd(V0, V0);
   __ b(&double_hash, VS);
 
-  // Convert double value to signed 64-bit int in R0 and back to a
+  // Convert double value to signed 32-bit int in R0 and back to a
   // double value in V1.
-  __ fcvtzds(R0, V0);
-  __ scvtfdx(V1, R0);
+  __ fcvtzdsw(R0, V0);
+  __ scvtfdw(V1, R0);
 
   // Tag the int as a Smi, making sure that it fits; this checks for
   // overflow in the conversion from double to int. Conversion
@@ -1527,8 +1534,9 @@
   // INT64_MAX or INT64_MIN (saturation).
   Label fall_through;
   ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
-  __ adds(R0, R0, Operand(R0));
+  __ addsw(R0, R0, Operand(R0));
   __ b(&fall_through, VS);
+  __ sxtw(R0, R0);  // Sign extend - flags not affected.
 
   // Compare the two double values. If they are equal, we return the
   // Smi tagged result immediately as the hash code.
diff --git a/runtime/vm/compiler/intrinsifier_x64.cc b/runtime/vm/compiler/intrinsifier_x64.cc
index 1e2574c..c8ddf76 100644
--- a/runtime/vm/compiler/intrinsifier_x64.cc
+++ b/runtime/vm/compiler/intrinsifier_x64.cc
@@ -269,8 +269,10 @@
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX contains right argument.
-  __ addq(RAX, Address(RSP, +2 * kWordSize));
+  __ AssertSmiInRange(RAX);
+  __ addl(RAX, Address(RSP, +2 * kWordSize));
   __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ movsxd(RAX, RAX);
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
@@ -284,8 +286,10 @@
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX contains right argument, which is the actual minuend of subtraction.
-  __ subq(RAX, Address(RSP, +2 * kWordSize));
+  __ AssertSmiInRange(RAX);
+  __ subl(RAX, Address(RSP, +2 * kWordSize));
   __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ movsxd(RAX, RAX);
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
@@ -295,10 +299,13 @@
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX contains right argument, which is the actual subtrahend of subtraction.
+  __ AssertSmiInRange(RAX);
   __ movq(RCX, RAX);
   __ movq(RAX, Address(RSP, +2 * kWordSize));
-  __ subq(RAX, RCX);
+  __ AssertSmiInRange(RAX);
+  __ subl(RAX, RCX);
   __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ movsxd(RAX, RAX);
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
@@ -308,10 +315,12 @@
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX is the right argument.
+  __ AssertSmiInRange(RAX);
   ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
   __ SmiUntag(RAX);
-  __ imulq(RAX, Address(RSP, +2 * kWordSize));
+  __ imull(RAX, Address(RSP, +2 * kWordSize));
   __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ movsxd(RAX, RAX);
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
@@ -333,7 +342,9 @@
 //   RAX: Untagged fallthrough result (remainder to be adjusted), or
 //   RAX: Tagged return result (remainder).
 static void EmitRemainderOperation(Assembler* assembler) {
-  Label return_zero, try_modulo, not_32bit, done;
+  Label return_zero, try_modulo, not_32bit;
+  __ AssertSmiInRange(RAX);
+  __ AssertSmiInRange(RCX);
   // Check for quick zero results.
   __ cmpq(RAX, Immediate(0));
   __ j(EQUAL, &return_zero, Assembler::kNearJump);
@@ -355,33 +366,12 @@
 
   __ Bind(&try_modulo);
 
-  // Check if both operands fit into 32bits as idiv with 64bit operands
-  // requires twice as many cycles and has much higher latency. We are checking
-  // this before untagging them to avoid corner case dividing INT_MAX by -1 that
-  // raises exception because quotient is too large for 32bit register.
-  __ movsxd(RBX, RAX);
-  __ cmpq(RBX, RAX);
-  __ j(NOT_EQUAL, &not_32bit, Assembler::kNearJump);
-  __ movsxd(RBX, RCX);
-  __ cmpq(RBX, RCX);
-  __ j(NOT_EQUAL, &not_32bit, Assembler::kNearJump);
-
   // Both operands are 31bit smis. Divide using 32bit idiv.
   __ SmiUntag(RAX);
   __ SmiUntag(RCX);
   __ cdq();
   __ idivl(RCX);
   __ movsxd(RAX, RDX);
-  __ jmp(&done, Assembler::kNearJump);
-
-  // Divide using 64bit idiv.
-  __ Bind(&not_32bit);
-  __ SmiUntag(RAX);
-  __ SmiUntag(RCX);
-  __ cqo();
-  __ idivq(RCX);
-  __ movq(RAX, RDX);
-  __ Bind(&done);
 }
 
 // Implementation:
@@ -396,7 +386,9 @@
 void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
   Label fall_through, negative_result;
   TestBothArgumentsSmis(assembler, &fall_through);
+  __ AssertSmiInRange(RAX);
   __ movq(RCX, Address(RSP, +2 * kWordSize));
+  __ AssertSmiInRange(RCX);
   // RAX: Tagged left (dividend).
   // RCX: Tagged right (divisor).
   __ cmpq(RCX, Immediate(0));
@@ -430,21 +422,17 @@
   Label fall_through, not_32bit;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX: right argument (divisor)
+  __ AssertSmiInRange(RAX);
   __ cmpq(RAX, Immediate(0));
   __ j(EQUAL, &fall_through, Assembler::kNearJump);
   __ movq(RCX, RAX);
   __ movq(RAX, Address(RSP, +2 * kWordSize));  // Left argument (dividend).
+  __ AssertSmiInRange(RAX);
 
-  // Check if both operands fit into 32bits as idiv with 64bit operands
-  // requires twice as many cycles and has much higher latency. We are checking
-  // this before untagging them to avoid corner case dividing INT_MAX by -1 that
-  // raises exception because quotient is too large for 32bit register.
-  __ movsxd(RBX, RAX);
-  __ cmpq(RBX, RAX);
-  __ j(NOT_EQUAL, &not_32bit);
-  __ movsxd(RBX, RCX);
-  __ cmpq(RBX, RCX);
-  __ j(NOT_EQUAL, &not_32bit);
+  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
+  // cannot tag the result.
+  __ cmpq(RAX, Immediate(-0x80000000ll));
+  __ j(EQUAL, &fall_through);
 
   // Both operands are 31bit smis. Divide using 32bit idiv.
   __ SmiUntag(RAX);
@@ -454,21 +442,6 @@
   __ movsxd(RAX, RAX);
   __ SmiTag(RAX);  // Result is guaranteed to fit into a smi.
   __ ret();
-
-  // Divide using 64bit idiv.
-  __ Bind(&not_32bit);
-  __ SmiUntag(RAX);
-  __ SmiUntag(RCX);
-  __ pushq(RDX);  // Preserve RDX in case of 'fall_through'.
-  __ cqo();
-  __ idivq(RCX);
-  __ popq(RDX);
-  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
-  // cannot tag the result.
-  __ cmpq(RAX, Immediate(0x4000000000000000));
-  __ j(EQUAL, &fall_through);
-  __ SmiTag(RAX);
-  __ ret();
   __ Bind(&fall_through);
 }
 
@@ -477,8 +450,10 @@
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ testq(RAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);  // Non-smi value.
+  __ AssertSmiInRange(RAX);
+  __ cmpq(RAX, Immediate(-0x80000000ll));
+  __ j(EQUAL, &fall_through, Assembler::kNearJump);
   __ negq(RAX);
-  __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
@@ -487,6 +462,7 @@
 void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
+  __ AssertSmiInRange(RAX);
   // RAX is the right argument.
   __ andq(RAX, Address(RSP, +2 * kWordSize));
   // Result is in RAX.
@@ -502,6 +478,7 @@
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX is the right argument.
+  __ AssertSmiInRange(RAX);
   __ orq(RAX, Address(RSP, +2 * kWordSize));
   // Result is in RAX.
   __ ret();
@@ -517,6 +494,7 @@
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX is the right argument.
   __ xorq(RAX, Address(RSP, +2 * kWordSize));
+  __ AssertSmiInRange(RAX);
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
@@ -532,28 +510,32 @@
   Label fall_through, overflow;
   TestBothArgumentsSmis(assembler, &fall_through);
   // Shift value is in RAX. Compare with tagged Smi.
+  __ AssertSmiInRange(RAX);
   __ cmpq(RAX, Immediate(Smi::RawValue(Smi::kBits)));
   __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
 
   __ SmiUntag(RAX);
   __ movq(RCX, RAX);                           // Shift amount must be in RCX.
   __ movq(RAX, Address(RSP, +2 * kWordSize));  // Value.
+  __ AssertSmiInRange(RAX);
 
   // Overflow test - all the shifted-out bits must be same as the sign bit.
   __ movq(RDI, RAX);
-  __ shlq(RAX, RCX);
-  __ sarq(RAX, RCX);
+  __ shll(RAX, RCX);
+  __ sarl(RAX, RCX);
+  __ movsxd(RAX, RAX);
   __ cmpq(RAX, RDI);
   __ j(NOT_EQUAL, &overflow, Assembler::kNearJump);
 
-  __ shlq(RAX, RCX);  // Shift for result now we know there is no overflow.
+  __ shlq(RDI, RCX);  // Shift for result now we know there is no overflow.
+  __ movq(RAX, RDI);
 
   // RAX is a correctly tagged Smi.
   __ ret();
 
   __ Bind(&overflow);
-  // Mint is rarely used on x64 (only for integers requiring 64 bit instead of
-  // 63 bits as represented by Smi).
+  // Mint is used on x64 for integers requiring 64 bit instead of 31 bits as
+  // represented by Smi.
   __ Bind(&fall_through);
 }
 
@@ -561,6 +543,7 @@
   Label fall_through, true_label;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX contains the right argument.
+  __ AssertSmiInRange(RAX);
   __ cmpq(Address(RSP, +2 * kWordSize), RAX);
   __ j(true_condition, &true_label, Assembler::kNearJump);
   __ LoadObject(RAX, Bool::False());
@@ -606,6 +589,9 @@
   __ orq(RAX, RCX);
   __ testq(RAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
+  // Or-ing them together should still leave them both as compressible smis.
+  __ AssertSmiInRange(RAX);
+  __ AssertSmiInRange(RCX);
   // Both arguments are smi, '===' is good enough.
   __ LoadObject(RAX, Bool::False());
   __ ret();
@@ -623,9 +609,21 @@
   // Left (receiver) is Smi, return false if right is not Double.
   // Note that an instance of Mint or Bigint never contains a value that can be
   // represented by Smi.
+  __ AssertSmiInRange(RAX);
   __ movq(RAX, Address(RSP, +kArgumentOffset * kWordSize));
   __ CompareClassId(RAX, kDoubleCid);
   __ j(EQUAL, &fall_through);
+#if defined(DEBUG)
+  Label ok;
+  __ CompareClassId(RAX, kMintCid);
+  __ j(NOT_EQUAL, &ok);
+  __ movq(RAX, FieldAddress(RAX, Mint::value_offset()));
+  __ sarq(RCX, Immediate(1));
+  __ cmpq(RAX, RCX);
+  __ j(NOT_EQUAL, &ok);
+  __ Stop("Smi wrapped in a Mint");
+  __ Bind(&ok);
+#endif
   __ LoadObject(RAX, Bool::False());
   __ ret();
 
@@ -637,6 +635,7 @@
   __ movq(RAX, Address(RSP, +kArgumentOffset * kWordSize));
   __ testq(RAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &fall_through);
+  __ AssertSmiInRange(RAX);
   // Smi == Mint -> false.
   __ LoadObject(RAX, Bool::False());
   __ ret();
@@ -666,6 +665,7 @@
   __ Bind(&shift_count_ok);
   __ movq(RCX, RAX);                           // Shift amount must be in RCX.
   __ movq(RAX, Address(RSP, +2 * kWordSize));  // Value.
+  __ AssertSmiInRange(RAX);
   __ SmiUntag(RAX);                            // Value.
   __ sarq(RAX, RCX);
   __ SmiTag(RAX);
@@ -676,6 +676,7 @@
 // Argument is Smi (receiver).
 void Intrinsifier::Smi_bitNegate(Assembler* assembler) {
   __ movq(RAX, Address(RSP, +1 * kWordSize));  // Index.
+  __ AssertSmiInRange(RAX);
   __ notq(RAX);
   __ andq(RAX, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
   __ ret();
@@ -684,6 +685,7 @@
 void Intrinsifier::Smi_bitLength(Assembler* assembler) {
   ASSERT(kSmiTagShift == 1);
   __ movq(RAX, Address(RSP, +1 * kWordSize));  // Index.
+  __ AssertSmiInRange(RAX);
   // XOR with sign bit to complement bits if value is negative.
   __ movq(RCX, RAX);
   __ sarq(RCX, Immediate(63));  // All 0 or all 1.
@@ -709,6 +711,7 @@
   __ subq(R8, Immediate(2));  // x_used > 0, Smi. R8 = x_used - 1, round up.
   __ sarq(R8, Immediate(2));  // R8 + 1 = number of digit pairs to read.
   __ movq(RCX, Address(RSP, 2 * kWordSize));  // n is Smi
+  __ AssertSmiInRange(RCX);
   __ SmiUntag(RCX);
   __ movq(RBX, Address(RSP, 1 * kWordSize));  // r_digits
   __ movq(RSI, RCX);
@@ -744,6 +747,7 @@
 
   __ movq(RDI, Address(RSP, 4 * kWordSize));  // x_digits
   __ movq(RCX, Address(RSP, 2 * kWordSize));  // n is Smi
+  __ AssertSmiInRange(RCX);
   __ SmiUntag(RCX);
   __ movq(RBX, Address(RSP, 1 * kWordSize));  // r_digits
   __ movq(RDX, RCX);
@@ -1231,6 +1235,7 @@
   __ LoadObject(RAX, Bool::True());
   __ ret();
   __ Bind(&is_smi);
+  __ AssertSmiInRange(RAX);
   __ SmiUntag(RAX);
   __ cvtsi2sdq(XMM1, RAX);
   __ jmp(&double_op);
@@ -1291,6 +1296,7 @@
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&is_smi);
+  __ AssertSmiInRange(RAX);
   __ SmiUntag(RAX);
   __ cvtsi2sdq(XMM1, RAX);
   __ jmp(&double_op);
@@ -1320,6 +1326,7 @@
   __ testq(RAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &fall_through);
   // Is Smi.
+  __ AssertSmiInRange(RAX);
   __ SmiUntag(RAX);
   __ cvtsi2sdq(XMM1, RAX);
   __ movq(RAX, Address(RSP, +2 * kWordSize));
@@ -1342,6 +1349,7 @@
   __ testq(RAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &fall_through);
   // Is Smi.
+  __ AssertSmiInRange(RAX);
   __ SmiUntag(RAX);
   __ cvtsi2sdq(XMM0, RAX);
   const Class& double_class =
@@ -1412,14 +1420,15 @@
 void Intrinsifier::DoubleToInteger(Assembler* assembler) {
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
-  __ cvttsd2siq(RAX, XMM0);
+  __ cvttsd2sil(RAX, XMM0);
   // Overflow is signalled with minint.
   Label fall_through;
   // Check for overflow and that it fits into Smi.
   __ movq(RCX, RAX);
-  __ shlq(RCX, Immediate(1));
+  __ shll(RCX, Immediate(1));
   __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
-  __ SmiTag(RAX);
+  ASSERT(kSmiTagShift == 1 && kSmiTag == 0);
+  __ movsxd(RAX, RCX);
   __ ret();
   __ Bind(&fall_through);
 }
@@ -1431,16 +1440,17 @@
   // back to a double in XMM1.
   __ movq(RCX, Address(RSP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(RCX, Double::value_offset()));
-  __ cvttsd2siq(RAX, XMM0);
-  __ cvtsi2sdq(XMM1, RAX);
+  __ cvttsd2sil(RAX, XMM0);
+  __ cvtsi2sdl(XMM1, RAX);
 
   // Tag the int as a Smi, making sure that it fits; this checks for
   // overflow and NaN in the conversion from double to int. Conversion
-  // overflow from cvttsd2si is signalled with an INT64_MIN value.
+  // overflow from cvttsd2sil is signalled with an INT32_MIN value.
   Label fall_through;
   ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
-  __ addq(RAX, RAX);
+  __ addl(RAX, RAX);
   __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
+  __ movsxd(RAX, RAX);
 
   // Compare the two double values. If they are equal, we return the
   // Smi tagged result immediately as the hash code.
@@ -1478,6 +1488,7 @@
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&is_smi);
+  __ AssertSmiInRange(RAX);
   __ SmiUntag(RAX);
   __ cvtsi2sdq(XMM1, RAX);
   __ jmp(&double_op);
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 829e3d9..a34d996 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -707,14 +707,14 @@
 
 enum Extend {
   kNoExtend = -1,
-  UXTB = 0,
-  UXTH = 1,
-  UXTW = 2,
-  UXTX = 3,
-  SXTB = 4,
-  SXTH = 5,
-  SXTW = 6,
-  SXTX = 7,
+  UXTB = 0,  // Zero extend byte.
+  UXTH = 1,  // Zero extend halfword (16 bits).
+  UXTW = 2,  // Zero extend word (32 bits).
+  UXTX = 3,  // Zero extend doubleword (64 bits).
+  SXTB = 4,  // Sign extend byte.
+  SXTH = 5,  // Sign extend halfword (16 bits).
+  SXTW = 6,  // Sign extend word (32 bits).
+  SXTX = 7,  // Sign extend doubleword (64 bits).
   kMaxExtend = 8,
 };
 
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index b7a56b9..eff8af8 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1586,16 +1586,6 @@
   return false;
 }
 
-DART_EXPORT void Dart_InterruptIsolate(Dart_Isolate isolate) {
-  if (isolate == NULL) {
-    FATAL1("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
-  }
-  // TODO(16615): Validate isolate parameter.
-  TransitionNativeToVM transition(Thread::Current());
-  Isolate* iso = reinterpret_cast<Isolate*>(isolate);
-  iso->SendInternalLibMessage(Isolate::kInterruptMsg, iso->pause_capability());
-}
-
 DART_EXPORT bool Dart_IsolateMakeRunnable(Dart_Isolate isolate) {
   CHECK_NO_ISOLATE(Isolate::Current());
   API_TIMELINE_DURATION(Thread::Current());
@@ -1693,21 +1683,6 @@
   return Api::Success();
 }
 
-DART_EXPORT Dart_Handle Dart_HandleMessages() {
-  Thread* T = Thread::Current();
-  Isolate* I = T->isolate();
-  CHECK_API_SCOPE(T);
-  CHECK_CALLBACK_STATE(T);
-  API_TIMELINE_BEGIN_END_BASIC(T);
-  TransitionNativeToVM transition(T);
-  if (I->message_handler()->HandleAllMessages() != MessageHandler::kOK) {
-    Dart_Handle error = Api::NewHandle(T, T->sticky_error());
-    T->clear_sticky_error();
-    return error;
-  }
-  return Api::Success();
-}
-
 DART_EXPORT Dart_Handle Dart_WaitForEvent(int64_t timeout_millis) {
   Thread* T = Thread::Current();
   Isolate* I = T->isolate();
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index 4fa43f2..c15516d 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -21,9 +21,8 @@
 #undef OVERFLOW  // From math.h conflicts in constants_ia32.h
 
 namespace dart {
-// Smi value range is from -(2^N) to (2^N)-1.
-// N=30 (32-bit build) or N=62 (64-bit build).
-const intptr_t kSmiBits = kBitsPerWord - 2;
+// Smi value range is from -(2^N) to (2^N)-1.  N=30
+const intptr_t kSmiBits = 30;
 const intptr_t kSmiMax = (static_cast<intptr_t>(1) << kSmiBits) - 1;
 const intptr_t kSmiMin = -(static_cast<intptr_t>(1) << kSmiBits);
 
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 1c45698..4fe67e6 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -956,6 +956,11 @@
 #undef REUSABLE_HANDLE_INITIALIZERS
 
 Isolate::~Isolate() {
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  // TODO(32796): Re-enable assertion.
+  // RELEASE_ASSERT(reload_context_ == NULL);
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+
   delete background_compiler_;
   background_compiler_ = NULL;
 
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index cd42d41..de94a29 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -463,6 +463,7 @@
 }
 
 IsolateReloadContext::~IsolateReloadContext() {
+  ASSERT(zone_ == Thread::Current()->zone());
   ASSERT(saved_class_table_ == NULL);
 }
 
@@ -605,6 +606,7 @@
       if (retval.status != Dart_KernelCompilationStatus_Ok) {
         TIR_Print("---- LOAD FAILED, ABORTING RELOAD\n");
         const String& error_str = String::Handle(String::New(retval.error));
+        free(retval.error);
         const ApiError& error = ApiError::Handle(ApiError::New(error_str));
         AddReasonForCancelling(new Aborted(zone_, error));
         ReportReasonsForCancelling();
@@ -1356,10 +1358,7 @@
   // used for morphing. It is therefore important that morphing takes
   // place prior to any heap walking.
   // So please keep this code at the top of Commit().
-  if (HasInstanceMorphers()) {
-    // Perform shape shifting of instances if necessary.
-    MorphInstances();
-  } else {
+  if (!MorphInstances()) {
     free(saved_class_table_);
     saved_class_table_ = NULL;
   }
@@ -1586,9 +1585,12 @@
   intptr_t count_;
 };
 
-void IsolateReloadContext::MorphInstances() {
+bool IsolateReloadContext::MorphInstances() {
   TIMELINE_SCOPE(MorphInstances);
-  ASSERT(HasInstanceMorphers());
+  if (!HasInstanceMorphers()) {
+    return false;
+  }
+
   if (FLAG_trace_reload) {
     LogBlock blocker;
     TIR_Print("MorphInstance: \n");
@@ -1606,7 +1608,9 @@
 
   // Return if no objects are located.
   intptr_t count = locator.count();
-  if (count == 0) return;
+  if (count == 0) {
+    return false;
+  }
 
   TIR_Print("Found %" Pd " object%s subject to morphing.\n", count,
             (count > 1) ? "s" : "");
@@ -1640,6 +1644,7 @@
   free(saved_class_table_);
   saved_class_table_ = NULL;
   Become::ElementsForwardIdentity(before, after);
+  return true;
 }
 
 void IsolateReloadContext::RunNewFieldInitializers() {
diff --git a/runtime/vm/isolate_reload.h b/runtime/vm/isolate_reload.h
index 107e081..715802e 100644
--- a/runtime/vm/isolate_reload.h
+++ b/runtime/vm/isolate_reload.h
@@ -239,8 +239,9 @@
 
   void CheckpointLibraries();
 
-  // Transforms the heap based on instance_morphers_.
-  void MorphInstances();
+  // Transforms the heap based on instance_morphers_. Return whether there was
+  // any morphing.
+  bool MorphInstances();
 
   void RunNewFieldInitializers();
 
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index 08abecb5..f65c9e4 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -741,7 +741,7 @@
       "  return identical(oldType, newType).toString();\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("true", SimpleInvokeStr(lib, "main"));
 }
@@ -772,7 +772,7 @@
       "  return identical(oldType, newType).toString();\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("true", SimpleInvokeStr(lib, "main"));
 }
@@ -805,7 +805,7 @@
       "  return (oldType == newType).toString();\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("true", SimpleInvokeStr(lib, "main"));
 }
@@ -965,11 +965,11 @@
       "  return bar();\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_EQ(107, SimpleInvoke(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
   EXPECT_EQ(105, SimpleInvoke(lib, "main"));
 }
@@ -1110,7 +1110,7 @@
   EXPECT_VALID(lib);
 
   // Identity reload.
-  TestCase::SetReloadTestScript(kScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kScript));
 
   EXPECT_EQ(8, SimpleInvoke(lib, "main"));
 }
@@ -1208,11 +1208,11 @@
       "  return new C().test();\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("instance", SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
   EXPECT_STREQ("instance", SimpleInvokeStr(lib, "main"));
 }
@@ -1247,11 +1247,11 @@
       "  return new C().test();\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
   EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
 }
@@ -1296,11 +1296,11 @@
       "  }\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("okay", SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
   EXPECT_STREQ("okay", SimpleInvokeStr(lib, "main"));
 }
@@ -1345,11 +1345,11 @@
       "  }\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
   EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 }
@@ -1391,11 +1391,11 @@
       "  }\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
   EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 }
@@ -1437,11 +1437,11 @@
       "  }\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
   EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
 }
@@ -1484,7 +1484,7 @@
       "  return new C().test();\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_EQ(11, SimpleInvoke(lib, "main"));
 }
@@ -1519,11 +1519,11 @@
       "  return '${f1()} ${f2()} ${f1 == f2} ${identical(f1, f2)}';\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("new new true false", SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
 }
 
@@ -1554,11 +1554,15 @@
       "}\n";
 
   TestCase::SetReloadTestScript(kReloadScript);
-
   Dart_Handle error_handle = SimpleInvokeError(lib, "main");
 
   const char* error;
-  if (TestCase::UsingDartFrontend()) {
+  if (TestCase::UsingStrongMode()) {
+    error =
+        "file:///test-lib:8:12: Error: Too few positional"
+        " arguments to function: 1 required, 0 given.\n"
+        "  return f1();";
+  } else if (TestCase::UsingDartFrontend()) {
     error =
         "NoSuchMethodError: Closure call with mismatched arguments: function "
         "'C.foo'\n"
@@ -1617,9 +1621,10 @@
       "NoSuchMethodError: No static method 'foo' declared in class 'C'.",
       SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
 }
+
 TEST_CASE(IsolateReload_TearOff_Class_Identity) {
   const char* kScript =
       "import 'file:///test:isolate_reload_helper';\n"
@@ -1650,11 +1655,11 @@
       "  return '${f1()} ${f2()} ${f1 == f2} ${identical(f1, f2)}';\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("new new true true", SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
 }
 
@@ -1684,11 +1689,11 @@
       "  return '${f1()} ${f2()} ${f1 == f2} ${identical(f1, f2)}';\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("new new true true", SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
 }
 
@@ -1746,147 +1751,15 @@
       "         '${set.remove(c.foo)}';\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ("new new true true true new true true true",
                SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
 }
 
-// TODO(bkonyi): This test has been modified since it was written and no longer
-// tests functionality that it did originally. It needs to be either re-written
-// or removed.
-TEST_CASE(IsolateReload_DanglingGetter_Instance) {
-  const char* kScript =
-      "import 'file:///test:isolate_reload_helper';\n"
-      "class C {\n"
-      "  var x = 3;\n"
-      "  var y = 4;\n"
-      "}\n"
-      "invoke(f) {\n"
-      "  try {\n"
-      "    return f();\n"
-      "  } catch (e) {\n"
-      "    return e.toString().split('\\n').first;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  var c = new C();\n"
-      "  var f = c.y;\n"
-      "  var r1 = invoke(f);\n"
-      "  reloadTest();\n"
-      "  var r2 = invoke(f);\n"
-      "  return '$r1 $r2';\n"
-      "}\n";
-
-  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
-  EXPECT_VALID(lib);
-
-  const char* kReloadScript =
-      "import 'file:///test:isolate_reload_helper';\n"
-      "class C {\n"
-      "  var x = 3;\n"
-      "}\n"
-      "invoke(f) {\n"
-      "  try {\n"
-      "    return f();\n"
-      "  } catch (e) {\n"
-      "    return e.toString().split('\\n').first;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  var c = new C();\n"
-      "  var f = c.y;\n"
-      "  var r1 = invoke(f);\n"
-      "  reloadTest();\n"
-      "  var r2 = invoke(f);\n"
-      "  return '$r1 $r2';\n"
-      "}\n";
-
-  TestCase::SetReloadTestScript(kReloadScript);
-
-  EXPECT_STREQ(
-      "NoSuchMethodError: Class 'int' has no instance method 'call'. "
-      "NoSuchMethodError: Class 'int' has no instance method 'call'.",
-      SimpleInvokeStr(lib, "main"));
-
-  lib = TestCase::GetReloadLibrary();
-  if (TestCase::UsingDartFrontend() && TestCase::UsingStrongMode()) {
-    EXPECT_NULL(lib);
-  } else {
-    EXPECT_NON_NULL(lib);
-  }
-}
-
-// TODO(bkonyi): This test has been modified since it was written and no longer
-// tests functionality that it did originally. It needs to be either re-written
-// or removed.
-TEST_CASE(IsolateReload_DanglingGetter_Class) {
-  const char* kScript =
-      "import 'file:///test:isolate_reload_helper';\n"
-      "class C {\n"
-      "  static var x;\n"
-      "  static var y;\n"
-      "}\n"
-      "invoke(f) {\n"
-      "  try {\n"
-      "    return f();\n"
-      "  } catch (e) {\n"
-      "    return e.toString().split('\\n').first;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  C.x = 3;\n"
-      "  C.y = 4;\n"
-      "  var f = C.y;\n"
-      "  var r1 = invoke(f);\n"
-      "  reloadTest();\n"
-      "  var r2 = invoke(f);\n"
-      "  return '$r1 $r2';\n"
-      "}\n";
-
-  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
-  EXPECT_VALID(lib);
-
-  const char* kReloadScript =
-      "import 'file:///test:isolate_reload_helper';\n"
-      "class C {\n"
-      "  static var x;\n"
-      "}\n"
-      "invoke(f) {\n"
-      "  try {\n"
-      "    return f();\n"
-      "  } catch (e) {\n"
-      "    return e.toString().split('\\n').first;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  C.x = 3;\n"
-      "  C.y = 4;\n"
-      "  var f = C.y;\n"
-      "  var r1 = invoke(f);\n"
-      "  reloadTest();\n"
-      "  var r2 = invoke(f);\n"
-      "  return '$r1 $r2';\n"
-      "}\n";
-
-  TestCase::SetReloadTestScript(kReloadScript);
-
-  EXPECT_STREQ(
-      "NoSuchMethodError: Class 'int' has no instance method 'call'. "
-      "NoSuchMethodError: Class 'int' has no instance method 'call'.",
-      SimpleInvokeStr(lib, "main"));
-
-  lib = TestCase::GetReloadLibrary();
-  if (TestCase::UsingDartFrontend() && TestCase::UsingStrongMode()) {
-    EXPECT_NULL(lib);
-  } else {
-    EXPECT_NON_NULL(lib);
-  }
-}
-
 TEST_CASE(IsolateReload_TearOff_AddArguments) {
   const char* kScript =
       "import 'file:///test:isolate_reload_helper';\n"
@@ -1933,14 +1806,14 @@
       "  return '$r1 $r2';\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ(
       "1 NoSuchMethodError: Class 'C' has no instance method "
       "'foo' with matching arguments.",
       SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
 }
 
@@ -1988,14 +1861,14 @@
       "  return '$r1 $r2';\n"
       "}\n";
 
-  TestCase::SetReloadTestScript(kReloadScript);
+  EXPECT_VALID(TestCase::SetReloadTestScript(kReloadScript));
 
   EXPECT_STREQ(
       "1 NoSuchMethodError: Closure call with mismatched arguments: "
       "function 'C.foo'",
       SimpleInvokeStr(lib, "main"));
 
-  lib = TestCase::GetReloadLibrary();
+  lib = Dart_RootLibrary();
   EXPECT_NON_NULL(lib);
 }
 
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 559d178..bf28e59 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -19,7 +19,7 @@
 // Keep in sync with package:kernel/lib/binary/tag.dart.
 
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
-static const uint32_t kBinaryFormatVersion = 3;
+static const uint32_t kBinaryFormatVersion = 4;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
@@ -160,7 +160,7 @@
 static const int HeaderSize = 8;  // 'magic', 'formatVersion'.
 static const int MetadataPayloadOffset = HeaderSize;  // Right after header.
 
-class Reader {
+class Reader : public ValueObject {
  public:
   Reader(const uint8_t* buffer, intptr_t size)
       : thread_(NULL),
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 5d2a12c..a8a9a1f 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -306,6 +306,13 @@
   return files;
 }
 
+static void ReleaseFilesPairs(const Dart_CObject& files) {
+  for (intptr_t i = 0; i < files.value.as_array.length; i++) {
+    delete files.value.as_array.values[i];
+  }
+  delete[] files.value.as_array.values;
+}
+
 static void PassThroughFinalizer(void* isolate_callback_data,
                                  Dart_WeakPersistentHandle handle,
                                  void* peer) {}
@@ -405,13 +412,7 @@
     Dart_CObject message;
     message.type = Dart_CObject_kArray;
 
-    Dart_CObject files;
-    if (source_files_count != 0) {
-      files = BuildFilesPairs(source_files_count, source_files);
-    } else {
-      files.type = Dart_CObject_kArray;
-      files.value.as_array.length = 0;
-    }
+    Dart_CObject files = BuildFilesPairs(source_files_count, source_files);
 
     Dart_CObject suppress_warnings;
     suppress_warnings.type = Dart_CObject_kBool;
@@ -436,6 +437,8 @@
     // Send the message.
     Dart_PostCObject(kernel_port, &message);
 
+    ReleaseFilesPairs(files);
+
     // Wait for reply to arrive.
     MonitorLocker ml(monitor_);
     while (result_.status == Dart_KernelCompilationStatus_Unknown) {
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index b7fabf3..4b83212 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -40,7 +40,7 @@
         builder_(builder) {}
 
   bool IsSimple(intptr_t kernel_offset) {
-    AlternativeReadingScope alt(builder_->reader_, kernel_offset);
+    AlternativeReadingScope alt(&builder_->reader_, kernel_offset);
     uint8_t payload = 0;
     Tag tag = builder_->ReadTag(&payload);  // read tag.
     switch (tag) {
@@ -726,8 +726,8 @@
 
   library_kernel_data_ =
       TypedData::New(kTypedDataUint8ArrayCid, library_size, Heap::kOld);
-  builder_.reader_->CopyDataToVMHeap(library_kernel_data_,
-                                     library_kernel_offset_, library_size);
+  builder_.reader_.CopyDataToVMHeap(library_kernel_data_,
+                                    library_kernel_offset_, library_size);
   library.set_kernel_data(library_kernel_data_);
   library.set_kernel_offset(library_kernel_offset_);
 
@@ -825,7 +825,7 @@
     field_helper.ReadUntilExcluding(FieldHelper::kEnd);
     {
       // GenerateFieldAccessors reads (some of) the initializer.
-      AlternativeReadingScope alt(builder_.reader_, field_initializer_offset);
+      AlternativeReadingScope alt(&builder_.reader_, field_initializer_offset);
       GenerateFieldAccessors(toplevel_class, field, &field_helper);
     }
     if (FLAG_enable_mirrors && field_helper.annotation_count_ > 0) {
@@ -1159,7 +1159,8 @@
       field_helper.ReadUntilExcluding(FieldHelper::kEnd);
       {
         // GenerateFieldAccessors reads (some of) the initializer.
-        AlternativeReadingScope alt(builder_.reader_, field_initializer_offset);
+        AlternativeReadingScope alt(&builder_.reader_,
+                                    field_initializer_offset);
         GenerateFieldAccessors(klass, field, &field_helper);
       }
       if (FLAG_enable_mirrors && field_helper.annotation_count_ > 0) {
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index d18fa6c..ed47893 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -120,7 +120,7 @@
   DISALLOW_COPY_AND_ASSIGN(ClassIndex);
 };
 
-class KernelLoader {
+class KernelLoader : public ValueObject {
  public:
   explicit KernelLoader(Program* program);
   static Object& LoadEntireProgram(Program* program,
@@ -303,11 +303,6 @@
   GrowableArray<const Field*> fields_;
 };
 
-class ClassLoader {
- public:
-  void LoadClassMembers();
-};
-
 }  // namespace kernel
 }  // namespace dart
 
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index eb14377..1a1ca67 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -290,18 +290,6 @@
   return HandleMessages(&ml, true, false);
 }
 
-MessageHandler::MessageStatus MessageHandler::HandleAllMessages() {
-  // We can only call HandleAllMessages when this handler is not
-  // assigned to a thread pool.
-  MonitorLocker ml(&monitor_);
-  ASSERT(pool_ == NULL);
-  ASSERT(!delete_me_);
-#if defined(DEBUG)
-  CheckAccess();
-#endif
-  return HandleMessages(&ml, true, true);
-}
-
 MessageHandler::MessageStatus MessageHandler::PauseAndHandleAllMessages(
     int64_t timeout_millis) {
   MonitorLocker ml(&monitor_);
diff --git a/runtime/vm/message_handler.h b/runtime/vm/message_handler.h
index a7d9f96..247bff0 100644
--- a/runtime/vm/message_handler.h
+++ b/runtime/vm/message_handler.h
@@ -61,13 +61,6 @@
   // Returns true on success.
   MessageStatus HandleNextMessage();
 
-  // Handles all messages for this message handler.  Should only
-  // be used when not running the handler on the thread pool (via Run
-  // or RunBlocking).
-  //
-  // Returns true on success.
-  MessageStatus HandleAllMessages();
-
   // Handles any OOB messages for this message handler.  Can be used
   // even if the message handler is running on the thread pool.
   //
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 463013e..68574b2 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -7827,7 +7827,16 @@
   virtual uword ComputeCanonicalTableHash() const;
 
   static const intptr_t kBytesPerElement = kWordSize;
-  static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
+  // The length field is a Smi so that sets one limit on the max Array length.
+  // But we also need to be able to represent the length in bytes in an
+  // intptr_t, which is a different limit.  Either may be smaller.  We can't
+  // use Utils::Minimum here because it is not a const expression.
+  static const intptr_t kElementLimitDueToIntptrMax = static_cast<intptr_t>(
+      (kIntptrMax - sizeof(RawArray) - kObjectAlignment + kBytesPerElement) /
+      kBytesPerElement);
+  static const intptr_t kMaxElements = kSmiMax < kElementLimitDueToIntptrMax
+                                           ? kSmiMax
+                                           : kElementLimitDueToIntptrMax;
   static const intptr_t kMaxNewSpaceElements =
       (Heap::kNewAllocatableSize - sizeof(RawArray)) / kBytesPerElement;
 
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index f7ffc17..17eadb0 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -308,16 +308,10 @@
   EXPECT(Smi::IsValid(-15));
   EXPECT(Smi::IsValid(0xFFu));
 // Upper two bits must be either 00 or 11.
-#if defined(ARCH_IS_64_BIT)
-  EXPECT(!Smi::IsValid(kMaxInt64));
-  EXPECT(Smi::IsValid(0x3FFFFFFFFFFFFFFF));
-  EXPECT(Smi::IsValid(-1));
-#else
   EXPECT(!Smi::IsValid(kMaxInt32));
   EXPECT(Smi::IsValid(0x3FFFFFFF));
   EXPECT(Smi::IsValid(-1));
   EXPECT(!Smi::IsValid(0xFFFFFFFFu));
-#endif
 
   EXPECT_EQ(5, smi.AsInt64Value());
   EXPECT_EQ(5.0, smi.AsDoubleValue());
@@ -445,9 +439,6 @@
 }
 
 ISOLATE_UNIT_TEST_CASE(Mint) {
-// On 64-bit architectures a Smi is stored in a 64 bit word. A Midint cannot
-// be allocated if it does fit into a Smi.
-#if !defined(ARCH_IS_64_BIT)
   {
     Mint& med = Mint::Handle();
     EXPECT(med.IsNull());
@@ -517,7 +508,6 @@
   EXPECT_EQ(mint1.value(), mint_value);
   EXPECT_EQ(mint2.value(), mint_value);
   EXPECT_EQ(mint1.raw(), mint2.raw());
-#endif
 }
 
 ISOLATE_UNIT_TEST_CASE(Double) {
@@ -2747,22 +2737,6 @@
   EXPECT(Smi::Cast(result).Value() == kSmiTestValue);
 }
 
-#if defined(ARCH_IS_64_BIT)
-// Test for Embedded Smi object in the instructions.
-ISOLATE_UNIT_TEST_CASE(EmbedSmiIn64BitCode) {
-  extern void GenerateEmbedSmiInCode(Assembler * assembler, intptr_t value);
-  const intptr_t kSmiTestValue = DART_INT64_C(5) << 32;
-  Assembler _assembler_;
-  GenerateEmbedSmiInCode(&_assembler_, kSmiTestValue);
-  const Function& function =
-      Function::Handle(CreateFunction("Test_EmbedSmiIn64BitCode"));
-  const Code& code = Code::Handle(Code::FinalizeCode(function, &_assembler_));
-  function.AttachCode(code);
-  const Object& result =
-      Object::Handle(DartEntry::InvokeFunction(function, Array::empty_array()));
-  EXPECT(Smi::Cast(result).Value() == kSmiTestValue);
-}
-#endif  // ARCH_IS_64_BIT
 
 ISOLATE_UNIT_TEST_CASE(ExceptionHandlers) {
   const int kNumEntries = 4;
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
index 4d99e0f..3d23411 100644
--- a/runtime/vm/regexp.cc
+++ b/runtime/vm/regexp.cc
@@ -3023,10 +3023,19 @@
                               Trace* current_trace,
                               PreloadState* state) {
   if (state->eats_at_least_ == PreloadState::kEatsAtLeastNotYetInitialized) {
-    // Save some time by looking at most one machine word ahead.
-    state->eats_at_least_ =
-        EatsAtLeast(compiler->one_byte() ? 4 : 2, kRecursionBudget,
-                    current_trace->at_start() == Trace::FALSE_VALUE);
+    // On ARM64, only read 16 bits ahead for now.  This ensures that boxing is
+    // trivial even with the new smaller Smis.  See
+    // https://github.com/dart-lang/sdk/issues/29951 and
+    // LoadCodeUnitsInstr::EmitNativeCode.
+#if defined(TARGET_ARCH_ARM64)
+    const int kMaxBytesLoaded = 2;
+#else
+    const int kMaxBytesLoaded = 4;
+#endif
+    const int kMaxTwoByteCharactersLoaded = kMaxBytesLoaded / 2;
+    state->eats_at_least_ = EatsAtLeast(
+        compiler->one_byte() ? kMaxBytesLoaded : kMaxTwoByteCharactersLoaded,
+        kRecursionBudget, current_trace->at_start() == Trace::FALSE_VALUE);
   }
   state->preload_characters_ =
       CalculatePreloadCharacters(compiler, state->eats_at_least_);
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 616a253..9b99bed 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1819,7 +1819,6 @@
   // Handle interrupts:
   //  - store buffer overflow
   //  - OOB message (vm-service or dart:isolate)
-  //  - Dart_InterruptIsolate
   const Error& error = Error::Handle(thread->HandleInterrupts());
   if (!error.IsNull()) {
     Exceptions::PropagateError(error);
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index c115b7c..9318cfd 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -3199,13 +3199,21 @@
       set_vregisterd(vd, 1, 0);
     } else if (instr->Bits(16, 5) == 24) {
       // Format(instr, "fcvtzds'sf 'rd, 'vn");
+      const intptr_t max = instr->Bit(31) == 1 ? INT64_MAX : INT32_MAX;
+      const intptr_t min = instr->Bit(31) == 1 ? INT64_MIN : INT32_MIN;
       const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
-      if (vn_val >= static_cast<double>(INT64_MAX)) {
-        set_register(instr, rd, INT64_MAX, instr->RdMode());
-      } else if (vn_val <= static_cast<double>(INT64_MIN)) {
-        set_register(instr, rd, INT64_MIN, instr->RdMode());
+      int64_t result;
+      if (vn_val >= static_cast<double>(max)) {
+        result = max;
+      } else if (vn_val <= static_cast<double>(min)) {
+        result = min;
       } else {
-        set_register(instr, rd, static_cast<int64_t>(vn_val), instr->RdMode());
+        result = static_cast<int64_t>(vn_val);
+      }
+      if (instr->Bit(31) == 1) {
+        set_register(instr, rd, result, instr->RdMode());
+      } else {
+        set_register(instr, rd, result & 0xffffffffll, instr->RdMode());
       }
     } else {
       UnimplementedInstruction(instr);
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index bd7be22..a4c6ea9 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -636,11 +636,11 @@
 // __builtin_s{add,sub,mul}_overflow() intrinsics here and below.
 // Note that they may clobber the output location even when there is overflow:
 // https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
-DART_FORCE_INLINE static bool SignedAddWithOverflow(intptr_t lhs,
-                                                    intptr_t rhs,
+DART_FORCE_INLINE static bool SignedAddWithOverflow(int32_t lhs,
+                                                    int32_t rhs,
                                                     intptr_t* out) {
   intptr_t res = 1;
-#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
+#if defined(HOST_ARCH_IA32)
   asm volatile(
       "add %2, %1\n"
       "jo 1f;\n"
@@ -650,12 +650,25 @@
       : "+r"(res), "+r"(lhs)
       : "r"(rhs), "r"(out)
       : "cc");
+#elif defined(HOST_ARCH_X64)
+  int64_t tmp;
+  asm volatile(
+      "addl %[rhs], %[lhs]\n"
+      "jo 1f;\n"
+      "xor %[res], %[res]\n"
+      "movslq %[lhs], %[tmp]\n"
+      "mov %[tmp], 0(%[out])\n"
+      "1: "
+      : [res] "+r"(res), [lhs] "+r"(lhs), [tmp] "=&r"(tmp)
+      : [rhs] "r"(rhs), [out] "r"(out)
+      : "cc");
 #elif defined(HOST_ARCH_ARM) || defined(HOST_ARCH_ARM64)
   asm volatile(
-      "adds %1, %1, %2;\n"
+      "adds %w1, %w1, %w2;\n"
       "bvs 1f;\n"
+      "sxtw %x1, %w1;\n"
       "mov %0, #0;\n"
-      "str %1, [%3, #0]\n"
+      "str %x1, [%3, #0]\n"
       "1:"
       : "+r"(res), "+r"(lhs)
       : "r"(rhs), "r"(out)
@@ -666,11 +679,11 @@
   return (res != 0);
 }
 
-DART_FORCE_INLINE static bool SignedSubWithOverflow(intptr_t lhs,
-                                                    intptr_t rhs,
+DART_FORCE_INLINE static bool SignedSubWithOverflow(int32_t lhs,
+                                                    int32_t rhs,
                                                     intptr_t* out) {
   intptr_t res = 1;
-#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
+#if defined(HOST_ARCH_IA32)
   asm volatile(
       "sub %2, %1\n"
       "jo 1f;\n"
@@ -680,12 +693,25 @@
       : "+r"(res), "+r"(lhs)
       : "r"(rhs), "r"(out)
       : "cc");
+#elif defined(HOST_ARCH_X64)
+  int64_t tmp;
+  asm volatile(
+      "subl %[rhs], %[lhs]\n"
+      "jo 1f;\n"
+      "xor %[res], %[res]\n"
+      "movslq %[lhs], %[tmp]\n"
+      "mov %[tmp], 0(%[out])\n"
+      "1: "
+      : [res] "+r"(res), [lhs] "+r"(lhs), [tmp] "=&r"(tmp)
+      : [rhs] "r"(rhs), [out] "r"(out)
+      : "cc");
 #elif defined(HOST_ARCH_ARM) || defined(HOST_ARCH_ARM64)
   asm volatile(
-      "subs %1, %1, %2;\n"
+      "subs %w1, %w1, %w2;\n"
       "bvs 1f;\n"
+      "sxtw %x1, %w1;\n"
       "mov %0, #0;\n"
-      "str %1, [%3, #0]\n"
+      "str %x1, [%3, #0]\n"
       "1:"
       : "+r"(res), "+r"(lhs)
       : "r"(rhs), "r"(out)
@@ -696,11 +722,11 @@
   return (res != 0);
 }
 
-DART_FORCE_INLINE static bool SignedMulWithOverflow(intptr_t lhs,
-                                                    intptr_t rhs,
+DART_FORCE_INLINE static bool SignedMulWithOverflow(int32_t lhs,
+                                                    int32_t rhs,
                                                     intptr_t* out) {
   intptr_t res = 1;
-#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
+#if defined(HOST_ARCH_IA32)
   asm volatile(
       "imul %2, %1\n"
       "jo 1f;\n"
@@ -710,6 +736,18 @@
       : "+r"(res), "+r"(lhs)
       : "r"(rhs), "r"(out)
       : "cc");
+#elif defined(HOST_ARCH_X64)
+  int64_t tmp;
+  asm volatile(
+      "imull %[rhs], %[lhs]\n"
+      "jo 1f;\n"
+      "xor %[res], %[res]\n"
+      "movslq %[lhs], %[tmp]\n"
+      "mov %[tmp], 0(%[out])\n"
+      "1: "
+      : [res] "+r"(res), [lhs] "+r"(lhs), [tmp] "=&r"(tmp)
+      : [rhs] "r"(rhs), [out] "r"(out)
+      : "cc");
 #elif defined(HOST_ARCH_ARM)
   asm volatile(
       "smull %1, ip, %1, %2;\n"
@@ -724,12 +762,12 @@
 #elif defined(HOST_ARCH_ARM64)
   int64_t prod_lo = 0;
   asm volatile(
-      "mul %1, %2, %3\n"
-      "smulh %2, %2, %3\n"
-      "cmp %2, %1, ASR #63;\n"
+      "smull %x1, %w2, %w3\n"
+      "asr %x2, %x1, #63\n"
+      "cmp %x2, %x1, ASR #31;\n"
       "bne 1f;\n"
       "mov %0, #0;\n"
-      "str %1, [%4, #0]\n"
+      "str %x1, [%4, #0]\n"
       "1:"
       : "=r"(res), "+r"(prod_lo), "+r"(lhs)
       : "r"(rhs), "r"(out)
@@ -1971,11 +2009,7 @@
     if (rhs != 0) {
       const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]);
       const intptr_t res = (lhs >> kSmiTagSize) / (rhs >> kSmiTagSize);
-#if defined(ARCH_IS_64_BIT)
-      const intptr_t untaggable = 0x4000000000000000LL;
-#else
       const intptr_t untaggable = 0x40000000L;
-#endif  // defined(ARCH_IS_64_BIT)
       if (res != untaggable) {
         *reinterpret_cast<intptr_t*>(&FP[rA]) = res << kSmiTagSize;
         pc++;
@@ -2001,11 +2035,12 @@
   {
     BYTECODE(Shl, A_B_C);
     const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]) >> kSmiTagSize;
-    if (static_cast<uintptr_t>(rhs) < kBitsPerWord) {
-      const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]);
-      const intptr_t res = lhs << rhs;
+    const int kBitsPerInt32 = 32;
+    if (static_cast<uintptr_t>(rhs) < kBitsPerInt32) {
+      const int32_t lhs = reinterpret_cast<intptr_t>(FP[rB]);
+      const int32_t res = lhs << rhs;
       if (lhs == (res >> rhs)) {
-        *reinterpret_cast<intptr_t*>(&FP[rA]) = res;
+        *reinterpret_cast<intptr_t*>(&FP[rA]) = static_cast<intptr_t>(res);
         pc++;
       }
     }
@@ -2016,8 +2051,7 @@
     BYTECODE(Shr, A_B_C);
     const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]) >> kSmiTagSize;
     if (rhs >= 0) {
-      const intptr_t shift_amount =
-          (rhs >= kBitsPerWord) ? (kBitsPerWord - 1) : rhs;
+      const intptr_t shift_amount = (rhs >= 32) ? (32 - 1) : rhs;
       const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]) >> kSmiTagSize;
       *reinterpret_cast<intptr_t*>(&FP[rA]) = (lhs >> shift_amount)
                                               << kSmiTagSize;
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index cff0584..c7241ba 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -253,10 +253,6 @@
 // here covers most of the 64-bit range. On 32-bit platforms the smi
 // range covers most of the 32-bit range and values outside that
 // range are also represented as mints.
-#if defined(ARCH_IS_64_BIT)
-  EXPECT_EQ(Dart_CObject_kInt64, mint_cobject->type);
-  EXPECT_EQ(value, mint_cobject->value.as_int64);
-#else
   if (kMinInt32 < value && value < kMaxInt32) {
     EXPECT_EQ(Dart_CObject_kInt32, mint_cobject->type);
     EXPECT_EQ(value, mint_cobject->value.as_int32);
@@ -264,7 +260,6 @@
     EXPECT_EQ(Dart_CObject_kInt64, mint_cobject->type);
     EXPECT_EQ(value, mint_cobject->value.as_int64);
   }
-#endif
 }
 
 TEST_CASE(SerializeMints) {
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index e23bb90..f56ed03 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -1333,14 +1333,18 @@
   __ ldr(R1, Address(SP, +1 * kWordSize));  // Left.
   __ orr(TMP, R0, Operand(R1));
   __ BranchIfNotSmi(TMP, not_smi_or_overflow);
+  __ AssertSmiInRange(R0);
+  __ AssertSmiInRange(R1);
   switch (kind) {
     case Token::kADD: {
-      __ adds(R0, R1, Operand(R0));   // Adds.
+      __ addsw(R0, R1, Operand(R0));  // Adds.
+      __ sxtw(R0, R0);
       __ b(not_smi_or_overflow, VS);  // Branch if overflow.
       break;
     }
     case Token::kSUB: {
-      __ subs(R0, R1, Operand(R0));   // Subtract.
+      __ subsw(R0, R1, Operand(R0));  // Subtract.
+      __ sxtw(R0, R0);
       __ b(not_smi_or_overflow, VS);  // Branch if overflow.
       break;
     }
@@ -1382,6 +1386,8 @@
     __ StoreToOffset(R1, R6, count_offset);
   }
 
+  __ AssertSmiInRange(R0, Assembler::kValueCanBeHeapPointer);
+
   __ ret();
 }
 
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 5183d28..a160513 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1270,13 +1270,15 @@
   __ j(NOT_ZERO, not_smi_or_overflow);
   switch (kind) {
     case Token::kADD: {
-      __ addq(RAX, RCX);
+      __ addl(RAX, RCX);
       __ j(OVERFLOW, not_smi_or_overflow);
+      __ movsxd(RAX, RAX);
       break;
     }
     case Token::kSUB: {
-      __ subq(RAX, RCX);
+      __ subl(RAX, RCX);
       __ j(OVERFLOW, not_smi_or_overflow);
+      __ movsxd(RAX, RAX);
       break;
     }
     case Token::kEQ: {
diff --git a/runtime/vm/token_position.h b/runtime/vm/token_position.h
index c28f9a4..eadb562 100644
--- a/runtime/vm/token_position.h
+++ b/runtime/vm/token_position.h
@@ -18,7 +18,7 @@
 // ClassifyingTokenPositions N -> -1 - N
 //
 // Synthetically created AstNodes are given real source positions but encoded
-// as negative numbers from [kSmiMin32, -1 - N]. For example:
+// as negative numbers from [kSmiMin, -1 - N]. For example:
 //
 // A source position of 0 in a synthetic AstNode would be encoded as -2 - N.
 // A source position of 1 in a synthetic AstNode would be encoded as -3 - N.
@@ -86,7 +86,7 @@
 #undef DECLARE_VALUES
   static const intptr_t kMinSourcePos = 0;
   static const TokenPosition kMinSource;
-  static const intptr_t kMaxSourcePos = kSmiMax32 - kMaxSentinelDescriptors - 2;
+  static const intptr_t kMaxSourcePos = kSmiMax - kMaxSentinelDescriptors - 2;
   static const TokenPosition kMaxSource;
 
   // Decode from a snapshot.
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index a8fcbc1..84b4dbb 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -196,7 +196,10 @@
 }
 
 static void ReloadTest(Dart_NativeArguments native_args) {
-  DART_CHECK_VALID(TestCase::TriggerReload());
+  Dart_Handle result = TestCase::TriggerReload();
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
 }
 
 static Dart_NativeFunction IsolateReloadTestNativeResolver(
@@ -266,7 +269,10 @@
       sourcefiles_count, sourcefiles, incrementally);
 
   if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
-    return OS::SCreate(zone, "Compilation failed %s", compilation_result.error);
+    char* result =
+        OS::SCreate(zone, "Compilation failed %s", compilation_result.error);
+    free(compilation_result.error);
+    return result;
   }
   const uint8_t* kernel_file = compilation_result.kernel;
   intptr_t kernel_length = compilation_result.kernel_size;
@@ -500,11 +506,19 @@
 
 #ifndef PRODUCT
 
-void TestCase::SetReloadTestScript(const char* script) {
+Dart_Handle TestCase::SetReloadTestScript(const char* script) {
   if (FLAG_use_dart_frontend) {
     Dart_SourceFile* sourcefiles = NULL;
     intptr_t num_files = BuildSourceFilesArray(&sourcefiles, script);
-    KernelIsolate::UpdateInMemorySources(num_files, sourcefiles);
+    Dart_KernelCompilationResult compilation_result =
+        KernelIsolate::UpdateInMemorySources(num_files, sourcefiles);
+    delete[] sourcefiles;
+    if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
+      Dart_Handle result = Dart_NewApiError(compilation_result.error);
+      free(compilation_result.error);
+      return result;
+    }
+    return Api::Success();
   } else {
     if (script_reload_key == kUnsetThreadLocalKey) {
       script_reload_key = OSThread::CreateThreadLocal();
@@ -514,15 +528,17 @@
     // Store the new script in TLS.
     OSThread::SetThreadLocal(script_reload_key,
                              reinterpret_cast<uword>(script));
+    return Api::Success();
   }
 }
 
 Dart_Handle TestCase::TriggerReload() {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
   JSONStream js;
   bool success = false;
   {
-    TransitionNativeToVM transition(Thread::Current());
+    TransitionNativeToVM transition(thread);
     success = isolate->ReloadSources(&js,
                                      false,  // force_reload
                                      NULL, NULL,
@@ -530,82 +546,48 @@
     OS::PrintErr("RELOAD REPORT:\n%s\n", js.ToCString());
   }
 
+  Dart_Handle result = Dart_Null();
   if (success) {
-    return Dart_FinalizeLoading(false);
+    result = Dart_FinalizeLoading(false);
+  }
+
+  if (Dart_IsError(result)) {
+    // Keep load error.
+  } else if (isolate->reload_context()->reload_aborted()) {
+    result = Api::NewHandle(thread, isolate->reload_context()->error());
   } else {
-    return Dart_Null();
+    result = Dart_RootLibrary();
   }
-}
 
-Dart_Handle TestCase::GetReloadLibrary() {
-  Isolate* isolate = Isolate::Current();
-
-  if (isolate->reload_context() != NULL &&
-      isolate->reload_context()->reload_aborted()) {
-    return Dart_Null();
+  TransitionNativeToVM transition(thread);
+  if (isolate->reload_context() != NULL) {
+    isolate->DeleteReloadContext();
   }
-  return Dart_RootLibrary();
-}
 
-Dart_Handle TestCase::GetReloadErrorOrRootLibrary() {
-  Isolate* isolate = Isolate::Current();
-
-  if (isolate->reload_context() != NULL &&
-      isolate->reload_context()->reload_aborted()) {
-    // Return a handle to the error.
-    return Api::NewHandle(Thread::Current(),
-                          isolate->reload_context()->error());
-  }
-  return Dart_RootLibrary();
+  return result;
 }
 
 Dart_Handle TestCase::ReloadTestScript(const char* script) {
   if (FLAG_use_dart_frontend) {
     Dart_SourceFile* sourcefiles = NULL;
     intptr_t num_files = BuildSourceFilesArray(&sourcefiles, script);
-    KernelIsolate::UpdateInMemorySources(num_files, sourcefiles);
+    Dart_KernelCompilationResult compilation_result =
+        KernelIsolate::UpdateInMemorySources(num_files, sourcefiles);
     delete[] sourcefiles;
+    if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
+      Dart_Handle result = Dart_NewApiError(compilation_result.error);
+      free(compilation_result.error);
+      return result;
+    }
   } else {
     SetReloadTestScript(script);
   }
 
-  Dart_Handle result = TriggerReload();
-  if (Dart_IsError(result)) {
-    return result;
-  }
-
-  result = GetReloadErrorOrRootLibrary();
-
-  {
-    Thread* thread = Thread::Current();
-    TransitionNativeToVM transition(thread);
-    Isolate* isolate = thread->isolate();
-    if (isolate->reload_context() != NULL) {
-      isolate->DeleteReloadContext();
-    }
-  }
-
-  return result;
+  return TriggerReload();
 }
 
 Dart_Handle TestCase::ReloadTestKernel(const void* kernel) {
-  Dart_Handle result = TriggerReload();
-  if (Dart_IsError(result)) {
-    return result;
-  }
-
-  result = GetReloadErrorOrRootLibrary();
-
-  {
-    Thread* thread = Thread::Current();
-    TransitionNativeToVM transition(thread);
-    Isolate* isolate = thread->isolate();
-    if (isolate->reload_context() != NULL) {
-      isolate->DeleteReloadContext();
-    }
-  }
-
-  return result;
+  return TriggerReload();
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index e8b1fc7..5aa1d6a 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -355,15 +355,11 @@
   virtual void Run();
 
   // Sets |script| to be the source used at next reload.
-  static void SetReloadTestScript(const char* script);
+  static Dart_Handle SetReloadTestScript(const char* script);
 
   // Initiates the reload.
   static Dart_Handle TriggerReload();
 
-  // Returns the root library if the last reload was successful, otherwise
-  // returns Dart_Null().
-  static Dart_Handle GetReloadLibrary();
-
   // Helper function which reloads the current isolate using |script|.
   static Dart_Handle ReloadTestScript(const char* script);
   static Dart_Handle ReloadTestKernel(const void* kernel);
@@ -383,11 +379,6 @@
                                     const char* name,
                                     void* data = NULL);
 
-  // Gets the result of a reload. This touches state in IsolateReloadContext
-  // that is zone allocated and should not be used if a reload is triggered
-  // using reloadTest() from package:isolate_reload_helper.
-  static Dart_Handle GetReloadErrorOrRootLibrary();
-
   RunEntry* const run_;
 };
 
diff --git a/sdk/lib/_internal/js_runtime/lib/convert_patch.dart b/sdk/lib/_internal/js_runtime/lib/convert_patch.dart
index 771a73a..2d234a4 100644
--- a/sdk/lib/_internal/js_runtime/lib/convert_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/convert_patch.dart
@@ -6,7 +6,7 @@
 
 import 'dart:_js_helper' show argumentErrorValue, patch;
 import 'dart:_foreign_helper' show JS;
-import 'dart:_interceptors' show JSExtendableArray;
+import 'dart:_interceptors' show JSArray, JSExtendableArray;
 import 'dart:_internal' show MappedIterable, ListIterable;
 import 'dart:collection' show LinkedHashMap, MapBase;
 import 'dart:_native_typed_data' show NativeUint8List;
@@ -274,7 +274,7 @@
     assert(!_isUpgraded);
     List keys = _data;
     if (keys == null) {
-      keys = _data = _getPropertyNames(_original);
+      keys = _data = new JSArray<String>.typed(_getPropertyNames(_original));
     }
     return JS('JSExtendableArray', '#', keys);
   }
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index e3fe5422a..80a3910 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -986,9 +986,12 @@
     return null;
   }
 
-  // This is to avoid stack overflows due to very large argument arrays in
-  // apply().  It fixes http://dartbug.com/6919
-  static String _fromCharCodeApply(List<int> array) {
+  /// Version of `String.fromCharCode.apply` that chunks the conversion to avoid
+  /// stack overflows due to very large argument arrays.
+  ///
+  /// [array] is pre-validated as a JSArray of int values but is not typed as
+  /// <int> so it can be called with any JSArray.
+  static String _fromCharCodeApply(List array) {
     const kMaxApply = 500;
     int end = array.length;
     if (end <= kMaxApply) {
diff --git a/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
index ddf159e..a588b08 100644
--- a/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
@@ -104,7 +104,7 @@
   }
 
   Match firstMatch(String string) {
-    List<String> m = JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp,
+    List m = JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp,
         checkString(string));
     if (m == null) return null;
     return new _MatchImplementation(this, m);
@@ -163,7 +163,9 @@
   final Pattern pattern;
   // Contains a JS RegExp match object.
   // It is an Array of String values with extra 'index' and 'input' properties.
-  final List<String> _match;
+  // We didn't force it to be JSArray<String>, so it is JSArray<dynamic>, but
+  // containing String or `undefined` values.
+  final JSArray _match;
 
   _MatchImplementation(this.pattern, this._match) {
     assert(JS('var', '#.input', _match) is String);
@@ -180,8 +182,12 @@
       JS('returns:int;depends:none;effects:none;gvn:true', '#[0].length',
           _match);
 
-  String group(int index) => _match[index];
+  // The JS below changes the static type to avoid an implicit cast.
+  // TODO(sra): Find a nicer way to do this, e.g. unsafeCast.
+  String group(int index) => JS('String|Null', '#', _match[index]);
+
   String operator [](int index) => group(index);
+
   int get groupCount => _match.length - 1;
 
   List<String> groups(List<int> groups) {
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index bcd1f22..8de4156 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -148,10 +148,12 @@
  */
 abstract class Future<T> {
   /// A `Future<Null>` completed with `null`.
-  static final _Future<Null> _nullFuture = new _Future<Null>.value(null);
+  static final _Future<Null> _nullFuture =
+      new _Future<Null>.zoneValue(null, Zone.root);
 
   /// A `Future<bool>` completed with `false`.
-  static final _Future<bool> _falseFuture = new _Future<bool>.value(false);
+  static final _Future<bool> _falseFuture =
+      new _Future<bool>.zoneValue(false, Zone.root);
 
   /**
    * Creates a future containing the result of calling [computation]
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 6eeaa08..2b56f9d 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -184,7 +184,7 @@
    * Until the future is completed, the field may hold the zone that
    * listener callbacks used to create this future should be run in.
    */
-  final Zone _zone = Zone.current;
+  final Zone _zone;
 
   /**
    * Either the result, a list of listeners or another future.
@@ -204,20 +204,24 @@
   var _resultOrListeners;
 
   // This constructor is used by async/await.
-  _Future();
+  _Future() : _zone = Zone.current;
 
-  _Future.immediate(FutureOr<T> result) {
+  _Future.immediate(FutureOr<T> result) : _zone = Zone.current {
     _asyncComplete(result);
   }
 
-  _Future.immediateError(var error, [StackTrace stackTrace]) {
+  /** Creates a future with the value and the specified zone. */
+  _Future.zoneValue(T value, this._zone) {
+    _setValue(value);
+  }
+
+  _Future.immediateError(var error, [StackTrace stackTrace])
+      : _zone = Zone.current {
     _asyncCompleteError(error, stackTrace);
   }
 
   /** Creates a future that is already completed with the value. */
-  _Future.value(T value) {
-    _setValue(value);
-  }
+  _Future.value(T value) : this.zoneValue(value, Zone.current);
 
   bool get _mayComplete => _state == _stateIncomplete;
   bool get _isPendingComplete => _state == _statePendingComplete;
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 29afb71..4f9f8a9 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -1273,9 +1273,6 @@
    * If an error occurs, or if this stream ends without finding a match and
    * with no [orElse] function provided,
    * the returned future is completed with an error.
-   *
-   * The [defaultValue] parameter is deprecated, and [orElse] should be used
-   * instead.
    */
   Future<T> firstWhere(bool test(T element), {T orElse()}) {
     _Future<T> future = new _Future();
@@ -1314,9 +1311,6 @@
    * instead of the first.
    * That means that a non-error result cannot be provided before this stream
    * is done.
-   *
-   * The [defaultValue] parameter is deprecated, and [orElse] should be used
-   * instead.
    */
   Future<T> lastWhere(bool test(T element), {T orElse()}) {
     _Future<T> future = new _Future();
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index fa49808..951d027 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -388,7 +388,7 @@
    * the current's zone behavior. All specification entries that are `null`
    * inherit the behavior from the parent zone (`this`).
    *
-   * The new zone inherits the stored values (accessed through [[]])
+   * The new zone inherits the stored values (accessed through [operator []])
    * of this zone and updates them with values from [zoneValues], which either
    * adds new values or overrides existing ones.
    *
diff --git a/sdk/lib/collection/hash_map.dart b/sdk/lib/collection/hash_map.dart
index 233f644..84655dc 100644
--- a/sdk/lib/collection/hash_map.dart
+++ b/sdk/lib/collection/hash_map.dart
@@ -48,7 +48,7 @@
    * for keys in order to place them in the hash table. If it is omitted, the
    * key's own [Object.hashCode] is used.
    *
-   * If using methods like [[]], [remove] and [containsKey] together
+   * If using methods like [operator []], [remove] and [containsKey] together
    * with a custom equality and hashcode, an extra `isValidKey` function
    * can be supplied. This function is called before calling [equals] or
    * [hashCode] with an argument that may not be a [K] instance, and if the
diff --git a/sdk/lib/collection/linked_hash_map.dart b/sdk/lib/collection/linked_hash_map.dart
index 22fe5eb..b4c2bf4 100644
--- a/sdk/lib/collection/linked_hash_map.dart
+++ b/sdk/lib/collection/linked_hash_map.dart
@@ -35,7 +35,7 @@
    * for keys in order to place them in the hash table. If it is omitted, the
    * key's own [Object.hashCode] is used.
    *
-   * If using methods like [[]], [remove] and [containsKey] together
+   * If using methods like [operator []], [remove] and [containsKey] together
    * with a custom equality and hashcode, an extra `isValidKey` function
    * can be supplied. This function is called before calling [equals] or
    * [hashCode] with an argument that may not be a [K] instance, and if the
diff --git a/sdk/lib/collection/splay_tree.dart b/sdk/lib/collection/splay_tree.dart
index b3eb7cb..fad3ce8 100644
--- a/sdk/lib/collection/splay_tree.dart
+++ b/sdk/lib/collection/splay_tree.dart
@@ -273,7 +273,7 @@
  * Non-comparable objects (including `null`) will not work as keys
  * in that case.
  *
- * To allow calling [[]], [remove] or [containsKey] with objects
+ * To allow calling [operator []], [remove] or [containsKey] with objects
  * that are not supported by the `compare` function, an extra `isValidKey`
  * predicate function can be supplied. This function is tested before
  * using the `compare` function on an argument value that may not be a [K]
diff --git a/sdk/lib/core/comparable.dart b/sdk/lib/core/comparable.dart
index 7a22948..bbb334f 100644
--- a/sdk/lib/core/comparable.dart
+++ b/sdk/lib/core/comparable.dart
@@ -33,10 +33,10 @@
  * and to provide separate [Comparator]s instead.
  *
  * It is recommended that the order of a [Comparable] agrees
- * with its operator [==] equality (`a.compareTo(b) == 0` iff `a == b`),
+ * with its operator [operator ==] equality (`a.compareTo(b) == 0` iff `a == b`),
  * but this is not a requirement.
  * For example, [double] and [DateTime] have `compareTo` methods
- * that do not agree with operator [==].
+ * that do not agree with operator [operator ==].
  * For doubles the [compareTo] method is more precise than the equality,
  * and for [DateTime] it is less precise.
  *
diff --git a/sdk/lib/core/object.dart b/sdk/lib/core/object.dart
index fda5662..0338f48 100644
--- a/sdk/lib/core/object.dart
+++ b/sdk/lib/core/object.dart
@@ -12,7 +12,7 @@
  *
  * When you define a class, you should override [toString]
  * to return a string describing an instance of that class.
- * You might also need to define [hashCode] and [==], as described in the
+ * You might also need to define [hashCode] and [operator ==], as described in the
  * [Implementing map
  * keys](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#implementing-map-keys)
  * section of the [library
@@ -62,18 +62,18 @@
    * The hash code for this object.
    *
    * A hash code is a single integer which represents the state of the object
-   * that affects [==] comparisons.
+   * that affects [operator ==] comparisons.
    *
    * All objects have hash codes.
    * The default hash code represents only the identity of the object,
-   * the same way as the default [==] implementation only considers objects
+   * the same way as the default [operator ==] implementation only considers objects
    * equal if they are identical (see [identityHashCode]).
    *
-   * If [==] is overridden to use the object state instead,
+   * If [operator ==] is overridden to use the object state instead,
    * the hash code must also be changed to represent that state.
    *
    * Hash codes must be the same for objects that are equal to each other
-   * according to [==].
+   * according to [operator ==].
    * The hash code of an object should only change if the object changes
    * in a way that affects equality.
    * There are no further requirements for the hash codes.
@@ -86,7 +86,7 @@
    * data structures like [HashSet] or [HashMap].
    *
    * If a subclass overrides [hashCode], it should override the
-   * [==] operator as well to maintain consistency.
+   * [operator ==] operator as well to maintain consistency.
    */
   external int get hashCode;
 
diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart
index 8d95d2d..e7c36be 100644
--- a/sdk/lib/core/set.dart
+++ b/sdk/lib/core/set.dart
@@ -40,7 +40,7 @@
    * Creates an empty [Set].
    *
    * The created [Set] is a plain [LinkedHashSet].
-   * As such, it considers elements that are equal (using [==]) to be
+   * As such, it considers elements that are equal (using [operator ==]) to be
    * indistinguishable, and requires them to have a compatible
    * [Object.hashCode] implementation.
    *
@@ -70,7 +70,7 @@
    *         new Set<SubType>.from(superSet.where((e) => e is SubType));
    *
    * The created [Set] is a [LinkedHashSet]. As such, it considers elements that
-   * are equal (using [==]) to be indistinguishable, and requires them to
+   * are equal (using [operator ==]) to be indistinguishable, and requires them to
    * have a compatible [Object.hashCode] implementation.
    *
    * The set is equivalent to one created by
@@ -82,7 +82,7 @@
    * Creates a [Set] from [elements].
    *
    * The created [Set] is a [LinkedHashSet]. As such, it considers elements that
-   * are equal (using [==]) to be indistinguishable, and requires them to
+   * are equal (using [operator ==]) to be indistinguishable, and requires them to
    * have a compatible [Object.hashCode] implementation.
    *
    * The set is equivalent to one created by
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index ce66b2d..f81fdf6 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -193,7 +193,7 @@
   /**
    * Returns a hash code derived from the code units of the string.
    *
-   * This is compatible with [==]. Strings with the same sequence
+   * This is compatible with [operator ==]. Strings with the same sequence
    * of code units have the same hash code.
    */
   int get hashCode;
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index cba877e..19dc744 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -70,6 +70,7 @@
 import 'dart:_interceptors'
     show
         Interceptor,
+        JavaScriptFunction,
         JSExtendableArray,
         JSUInt31,
         findInterceptorConstructorForType,
@@ -26938,7 +26939,7 @@
     // Messages posted to ports are initially paused, allowing listeners to be
     // setup, start() needs to be explicitly invoked to begin handling messages.
     if (type == 'message') {
-      start();
+      _start();
     }
 
     super.addEventListener(type, listener, useCapture);
@@ -26986,9 +26987,10 @@
   @DocsEditable()
   void _postMessage_2(message) native;
 
+  @JSName('start')
   @DomName('MessagePort.start')
   @DocsEditable()
-  void start() native;
+  void _start() native;
 
   /// Stream of `message` events handled by this [MessagePort].
   @DomName('MessagePort.onmessage')
@@ -28080,6 +28082,20 @@
         NavigatorOnLine,
         NavigatorAutomationInformation,
         NavigatorID {
+  @DomName('Navigator.getGamepads')
+  List<Gamepad> getGamepads() {
+    var gamepadList = _getGamepads();
+
+    // If no prototype we need one for the world to hookup to the proper Dart class.
+    var jsProto = JS('', '#.prototype', gamepadList);
+    if (jsProto == null) {
+      JS('', '#.prototype = Object.create(null)', gamepadList);
+    }
+
+    applyExtension('GamepadList', gamepadList);
+    return gamepadList;
+  }
+
   @DomName('Navigator.language')
   String get language =>
       JS('String', '#.language || #.userLanguage', this, this);
@@ -28293,12 +28309,13 @@
   @Experimental() // untriaged
   Future getBattery() native;
 
+  @JSName('getGamepads')
   @DomName('Navigator.getGamepads')
   @DocsEditable()
   @Experimental() // untriaged
   @Returns('_GamepadList|Null')
   @Creates('_GamepadList')
-  List<Gamepad> getGamepads() native;
+  List<Gamepad> _getGamepads() native;
 
   @DomName('Navigator.getInstalledRelatedApps')
   @DocsEditable()
@@ -50876,7 +50893,8 @@
     JS('=Object', '#.extends = #', opts, extendsTagName);
   }
 
-  return JS('=Object', '#.registerElement(#, #)', document, tag, opts);
+  return JS(
+      'JavaScriptFunction', '#.registerElement(#, #)', document, tag, opts);
 }
 
 //// Called by Element.created to do validation & initialization.
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index a8c5ade..08eb54c 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -931,7 +931,7 @@
 LayoutTests/fast/text/sub-pixel/text-scaling-webfont_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/window-find_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/text/zero-width-characters_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/text/zero-width-characters_t01: RuntimeError, Pass # Please triage this failure
 LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/transforms/hit-test-large-scale_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/url/anchor_t01: RuntimeError # Please triage this failure
@@ -1254,6 +1254,7 @@
 LayoutTests/fast/canvas/webgl/index-validation-verifies-too-many-indices_t01: RuntimeError, Pass # Please triage this flake
 LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError, Pass # Please triage this flake
 LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError, Pass # Please triage this flake
+LayoutTests/fast/css/font-face-unicode-range-load_t01: Pass, Slow
 LayoutTests/fast/multicol/newmulticol/balance_t04: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # Please triage this failure
@@ -7035,7 +7036,6 @@
 Language/Classes/Getters/same_name_method_t07: MissingCompileTimeError
 Language/Classes/Superinterfaces/more_than_once_t01: MissingCompileTimeError
 Language/Classes/Superinterfaces/superclass_as_superinterface_t01: MissingCompileTimeError
-Language/Classes/definition_t16: Crash
 Language/Classes/definition_t24: MissingCompileTimeError
 Language/Classes/same_name_instance_and_static_members_t01: MissingCompileTimeError
 Language/Classes/same_name_instance_and_static_members_t02: MissingCompileTimeError
@@ -7058,34 +7058,15 @@
 Language/Expressions/Constants/logical_expression_t04: MissingCompileTimeError
 Language/Expressions/Function_Invocation/Unqualified_Invocation/instance_context_invocation_t04: Crash
 Language/Expressions/Instance_Creation/Const/exception_t01: MissingCompileTimeError
-Language/Expressions/Maps/syntax_t08: Crash
 Language/Expressions/Method_Invocation/Ordinary_Invocation/evaluation_t08: RuntimeError
 Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t02: Crash
 Language/Expressions/Method_Invocation/Super_Invocation/evaluation_t05: RuntimeError
 Language/Expressions/Method_Invocation/Super_Invocation/invocation_t02: Crash
 Language/Expressions/Null/instance_of_class_null_t01: RuntimeError
-Language/Expressions/Strings/String_Interpolation/syntax_t08: Crash
-Language/Expressions/Strings/multi_line_t11: Crash # Investiage: source-data from FE causes us to crash
-Language/Expressions/Strings/multi_line_t12: Crash
-Language/Expressions/Strings/multi_line_t13: Crash
-Language/Expressions/Strings/multi_line_t15: Crash
-Language/Expressions/Strings/multi_line_t16: Crash
-Language/Expressions/Strings/multi_line_t17: Crash
-Language/Expressions/Strings/multi_line_t18: Crash
-Language/Expressions/Strings/multi_line_t19: Crash
-Language/Expressions/Strings/multi_line_t20: Crash
-Language/Expressions/Strings/multi_line_t21: Crash
-Language/Expressions/Strings/multi_line_t22: Crash
-Language/Expressions/Strings/multi_line_t23: Crash
-Language/Expressions/Strings/multi_line_t24: Crash
-Language/Expressions/Strings/multi_line_t25: Crash
-Language/Expressions/Strings/multi_line_t28: Crash
-Language/Expressions/Strings/multi_line_t29: Crash
-Language/Expressions/Strings/multi_line_t32: Crash
-Language/Expressions/Strings/multi_line_t33: Crash
 Language/Expressions/This/placement_t04: Crash
 Language/Functions/External_Functions/not_connected_to_a_body_t01: RuntimeError
-Language/Functions/syntax_t09: Crash
+Language/Functions/Formal_Parameters/Optional_Formals/default_value_t01: MissingCompileTimeError
+Language/Functions/Formal_Parameters/Optional_Formals/default_value_t02: MissingCompileTimeError
 Language/Libraries_and_Scripts/Imports/same_name_t10: RuntimeError
 Language/Libraries_and_Scripts/Scripts/top_level_main_t01: CompileTimeError
 Language/Metadata/before_class_t01: RuntimeError
@@ -7178,7 +7159,6 @@
 Language/Classes/Instance_Methods/Operators/allowed_names_t20: Crash
 Language/Classes/Instance_Methods/Operators/allowed_names_t21: Crash
 Language/Classes/Instance_Methods/Operators/allowed_names_t22: Crash
-Language/Classes/definition_t16: Crash
 Language/Classes/member_definition_t04: Crash
 Language/Classes/member_definition_t06: Crash
 Language/Classes/member_definition_t07: Crash
@@ -7189,31 +7169,11 @@
 Language/Classes/member_definition_t12: Crash
 Language/Expressions/Constants/depending_on_itself_t03: Crash
 Language/Expressions/Function_Invocation/Unqualified_Invocation/instance_context_invocation_t04: Crash
-Language/Expressions/Maps/syntax_t08: Crash
 Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t02: Crash
 Language/Expressions/Method_Invocation/Super_Invocation/evaluation_t05: Crash
 Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t03: Crash
 Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t04: Crash
 Language/Expressions/Method_Invocation/Super_Invocation/invocation_t02: Crash
-Language/Expressions/Strings/String_Interpolation/syntax_t08: Crash
-Language/Expressions/Strings/multi_line_t11: Crash
-Language/Expressions/Strings/multi_line_t12: Crash
-Language/Expressions/Strings/multi_line_t13: Crash
-Language/Expressions/Strings/multi_line_t15: Crash
-Language/Expressions/Strings/multi_line_t16: Crash
-Language/Expressions/Strings/multi_line_t17: Crash
-Language/Expressions/Strings/multi_line_t18: Crash
-Language/Expressions/Strings/multi_line_t19: Crash
-Language/Expressions/Strings/multi_line_t20: Crash
-Language/Expressions/Strings/multi_line_t21: Crash
-Language/Expressions/Strings/multi_line_t22: Crash
-Language/Expressions/Strings/multi_line_t23: Crash
-Language/Expressions/Strings/multi_line_t24: Crash
-Language/Expressions/Strings/multi_line_t25: Crash
-Language/Expressions/Strings/multi_line_t28: Crash
-Language/Expressions/Strings/multi_line_t29: Crash
-Language/Expressions/Strings/multi_line_t32: Crash
-Language/Expressions/Strings/multi_line_t33: Crash
 Language/Expressions/This/placement_t04: Crash
 Language/Functions/setter_modifier_t01: Crash
 Language/Functions/setter_modifier_t02: Crash
@@ -7221,7 +7181,6 @@
 Language/Functions/setter_modifier_t04: Crash
 Language/Functions/setter_modifier_t05: Crash
 Language/Functions/setter_modifier_t06: Crash
-Language/Functions/syntax_t09: Crash
 Language/Statements/For/syntax_t13: Crash
 Language/Statements/For/syntax_t20: Crash
 LibTest/core/Invocation/namedArguments_A01_t01: Crash
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index 3668431..9973899 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -4,6 +4,8 @@
 
 [ $compiler == fasta ]
 Language/Classes/definition_t24: MissingCompileTimeError
+Language/Functions/Formal_Parameters/Optional_Formals/default_value_t01: MissingCompileTimeError
+Language/Functions/Formal_Parameters/Optional_Formals/default_value_t02: MissingCompileTimeError
 Language/Types/Type_Void/syntax_t08: MissingCompileTimeError
 Language/Types/Type_Void/syntax_t09: MissingCompileTimeError
 LayoutTests/*: Skip # TODO(ahe): Make dart:html available.
@@ -768,7 +770,6 @@
 Language/Expressions/Strings/static_type_t09: CompileTimeError
 Language/Expressions/This/placement_t04: MissingCompileTimeError
 Language/Expressions/This/static_type_t01: CompileTimeError
-Language/Expressions/Throw/syntax_t02: MissingCompileTimeError
 Language/Expressions/Throw/throw_various_types_t01: CompileTimeError
 Language/Expressions/Type_Cast/evaluation_t04: CompileTimeError
 Language/Expressions/Type_Cast/evaluation_t05: CompileTimeError
@@ -1697,7 +1698,6 @@
 Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t06: MissingCompileTimeError
 Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t07: MissingCompileTimeError
 Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t08: MissingCompileTimeError
-Language/Expressions/Throw/syntax_t02: MissingCompileTimeError
 Language/Libraries_and_Scripts/Exports/reexport_t01: MissingCompileTimeError
 Language/Libraries_and_Scripts/Exports/reexport_t02: MissingCompileTimeError
 Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: CompileTimeError
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 8a3884a..a4449ec 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -188,9 +188,6 @@
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19 issue 673, These tests take too much memory (300 MB) for our 1 GB test machine co19 issue 673. http://code.google.com/p/co19/issues/detail?id=673
 LibTest/core/List/List_class_A01_t02: Skip # co19 issue 673, These tests take too much memory (300 MB) for our 1 GB test machine co19 issue 673. http://code.google.com/p/co19/issues/detail?id=673
 
-[ $arch != arm64 && $arch != simarm64 && $arch != simdbc && $arch != simdbc64 && $arch != x64 && ($runtime == dart_precompiled || $runtime == vm) ]
-LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
-
 [ $arch == ia32 && $mode == release && $runtime == vm && $system == linux ]
 service/dev_fs_spawn_test: Pass, Fail # Issue 28411
 
@@ -382,6 +379,9 @@
 LibTest/typed_data/Uint64List/Uint64List.view_A01_t02: CompileTimeError # Large integer literal
 WebPlatformTest/*: SkipByDesign # dart:html not supported on VM.
 
+[ $runtime == dart_precompiled || $runtime == vm ]
+LibTest/core/int/operator_left_shift_A01_t02: Fail # Can't represent 1 << 2147483647 without running out of memory.
+
 [ $runtime == flutter || $hot_reload || $hot_reload_rollback ]
 Language/Expressions/Assignment/prefix_object_t02: Skip # Requires deferred libraries
 Language/Expressions/Constants/constant_constructor_t03: Skip # Requires deferred libraries
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 7a80c04..6378421 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -199,7 +199,6 @@
 Language/Expressions/Strings/String_Interpolation/double_quote_t02: CompileTimeError
 Language/Expressions/Strings/String_Interpolation/single_quote_t02: CompileTimeError
 Language/Expressions/This/placement_t04: MissingCompileTimeError
-Language/Expressions/Throw/syntax_t02: MissingCompileTimeError
 Language/Expressions/Type_Cast/evaluation_t10: MissingCompileTimeError
 Language/Expressions/Type_Test/evaluation_t10: MissingCompileTimeError
 Language/Expressions/Unary_Expressions/syntax_t10: CompileTimeError
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart
index 0700011..4529ffb 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart
@@ -10,6 +10,7 @@
 const table =
 /*ast.null*/
 /*kernel.OutputUnit(1, {lib})*/
+/*strong.OutputUnit(1, {lib})*/
     const <int, FF>{1: f1, 2: f2};
 
 /*element: f1:OutputUnit(1, {lib})*/
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index 35df582..fad8d47 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -442,7 +442,7 @@
 /// file and any supporting libraries.
 Future checkTests(Directory dataDir, ComputeMemberDataFunction computeFromAst,
     ComputeMemberDataFunction computeFromKernel,
-    {bool testStrongMode: false,
+    {bool testStrongMode: true,
     List<String> skipForAst: const <String>[],
     List<String> skipForKernel: const <String>[],
     List<String> skipForStrong: const <String>[],
@@ -477,6 +477,7 @@
     if (shouldContinue) continued = true;
     List<String> testOptions = options.toList();
     bool strongModeOnlyTest = false;
+    bool trustTypeAnnotations = false;
     if (name.endsWith('_ea.dart')) {
       testOptions.add(Flags.enableAsserts);
     } else if (name.endsWith('_strong.dart')) {
@@ -486,6 +487,8 @@
       }
     } else if (name.endsWith('_checked.dart')) {
       testOptions.add(Flags.enableCheckedMode);
+    } else if (name.endsWith('_trust.dart')) {
+      trustTypeAnnotations = true;
     }
 
     print('----------------------------------------------------------------');
@@ -537,11 +540,15 @@
       print('--skipped for ast-----------------------------------------------');
     } else {
       print('--from ast------------------------------------------------------');
+      List<String> options = [Flags.useOldFrontend]..addAll(testOptions);
+      if (trustTypeAnnotations) {
+        options.add(Flags.trustTypeAnnotations);
+      }
       MemberAnnotations<IdValue> annotations = expectedMaps[astMarker];
       CompiledData compiledData1 = await computeData(
           entryPoint, memorySourceFiles, computeFromAst,
           computeClassData: computeClassDataFromAst,
-          options: [Flags.useOldFrontend]..addAll(testOptions),
+          options: options,
           verbose: verbose,
           forUserLibrariesOnly: forUserLibrariesOnly,
           globalIds: annotations.globalData.keys);
@@ -555,11 +562,15 @@
       print('--skipped for kernel--------------------------------------------');
     } else {
       print('--from kernel---------------------------------------------------');
+      List<String> options = []..addAll(testOptions);
+      if (trustTypeAnnotations) {
+        options.add(Flags.trustTypeAnnotations);
+      }
       MemberAnnotations<IdValue> annotations = expectedMaps[kernelMarker];
       CompiledData compiledData2 = await computeData(
           entryPoint, memorySourceFiles, computeFromKernel,
           computeClassData: computeClassDataFromKernel,
-          options: testOptions,
+          options: options,
           verbose: verbose,
           forUserLibrariesOnly: forUserLibrariesOnly,
           globalIds: annotations.globalData.keys);
@@ -575,16 +586,17 @@
         print('--skipped for kernel (strong mode)----------------------------');
       } else {
         print('--from kernel (strong mode)-----------------------------------');
+        List<String> options = [Flags.strongMode]..addAll(testOptions);
         MemberAnnotations<IdValue> annotations = expectedMaps[strongMarker];
         CompiledData compiledData2 = await computeData(
             entryPoint, memorySourceFiles, computeFromKernel,
             computeClassData: computeClassDataFromKernel,
-            options: [Flags.strongMode]..addAll(testOptions),
+            options: options,
             verbose: verbose,
             forUserLibrariesOnly: forUserLibrariesOnly,
             globalIds: annotations.globalData.keys);
         if (await checkCode(
-            kernelName, entity.uri, code, annotations, compiledData2,
+            strongName, entity.uri, code, annotations, compiledData2,
             filterActualData: filterActualData,
             fatalErrors: !testAfterFailures)) {
           hasFailures = true;
@@ -708,7 +720,7 @@
   } else if (id is ElementId) {
     String memberName = id.memberName;
     bool isSetter = false;
-    if (memberName != '[]=' && memberName.endsWith('=')) {
+    if (memberName != '[]=' && memberName != '==' && memberName.endsWith('=')) {
       isSetter = true;
       memberName = memberName.substring(0, memberName.length - 1);
     }
diff --git a/tests/compiler/dart2js/equivalence/show_helper.dart b/tests/compiler/dart2js/equivalence/show_helper.dart
index 9bdae9a..bbf0b1d 100644
--- a/tests/compiler/dart2js/equivalence/show_helper.dart
+++ b/tests/compiler/dart2js/equivalence/show_helper.dart
@@ -20,6 +20,10 @@
   argParser.addFlag('all', negatable: false, defaultsTo: false);
   argParser.addFlag('use-kernel', negatable: false, defaultsTo: false);
   argParser.addFlag('strong', negatable: false, defaultsTo: false);
+  argParser.addFlag('omit-implicit-checks',
+      negatable: false, defaultsTo: false);
+  argParser.addFlag('trust-type-annotations',
+      negatable: false, defaultsTo: false);
   return argParser;
 }
 
@@ -34,6 +38,8 @@
   bool verbose = argResults['verbose'];
   bool strongMode = argResults['strong'];
   bool useKernel = argResults['use-kernel'] || strongMode;
+  bool omitImplicitChecks = argResults['omit-implicit-checks'];
+  bool trustTypeAnnotations = argResults['trust-type-annotations'];
 
   String file = argResults.rest.first;
   Uri entryPoint = Uri.base.resolve(nativeToUriPath(file));
@@ -53,6 +59,12 @@
   if (strongMode) {
     options.add(Flags.strongMode);
   }
+  if (trustTypeAnnotations) {
+    options.add(Flags.trustTypeAnnotations);
+  }
+  if (omitImplicitChecks) {
+    options.add(Flags.omitImplicitChecks);
+  }
   CompiledData data = await computeData(
       entryPoint, const {}, useKernel ? computeKernelData : computeAstData,
       computeClassData:
diff --git a/tests/compiler/dart2js/inference/data/await.dart b/tests/compiler/dart2js/inference/data/await.dart
index 724648a..03099d8 100644
--- a/tests/compiler/dart2js/inference/data/await.dart
+++ b/tests/compiler/dart2js/inference/data/await.dart
@@ -16,7 +16,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 /*element: _method1:[null]*/
-_method1(/*[null|subclass=Object]*/ o) {}
+_method1(
+    /*ast.[null|subclass=Object]*/
+    /*kernel.[null|subclass=Object]*/
+    /*strong.[null|subclass=JSInt]*/
+    o) {}
 
 /*element: awaitOfFuture:[exact=_Future]*/
 awaitOfFuture() async {
@@ -30,7 +34,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 /*element: _method2:[null]*/
-_method2(/*[null|subclass=Object]*/ o) {}
+_method2(
+    /*ast.[null|subclass=Object]*/
+    /*kernel.[null|subclass=Object]*/
+    /*strong.[null|subclass=JSInt]*/
+    o) {}
 
 /*element: awaitOfInt:[exact=_Future]*/
 awaitOfInt() async {
@@ -47,7 +55,11 @@
     /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ o) {}
 
 /*element: _method4:[null]*/
-_method4(/*[null|subclass=Object]*/ o) {}
+_method4(
+    /*ast.[null|subclass=Object]*/
+    /*kernel.[null|subclass=Object]*/
+    /*strong.[null|subclass=JSInt]*/
+    o) {}
 
 /*element: awaitForOfStream:[exact=_Future]*/
 awaitForOfStream() async {
diff --git a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
index 1fece67..96ea43a 100644
--- a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
+++ b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
@@ -56,7 +56,7 @@
     methods. /*invoke: [exact=JSExtendableArray]*/ add(
         /*[null]*/ (int /*[null|subclass=Object]*/ x) {
       res = x;
-      sum = x + i;
+      sum = x /*strong.invoke: [null|subclass=JSInt]*/ + i;
     });
   }
   methods /*[exact=JSExtendableArray]*/ [0](499);
@@ -64,8 +64,15 @@
   probe2methods(methods);
 }
 
-/*element: probe2res:[null|subclass=Object]*/
-probe2res(/*[null|subclass=Object]*/ x) => x;
+/*ast.element: probe2res:[null|subclass=Object]*/
+/*kernel.element: probe2res:[null|subclass=Object]*/
+/*strong.element: probe2res:[null|subclass=JSInt]*/
+probe2res(
+        /*ast.[null|subclass=Object]*/
+        /*kernel.[null|subclass=Object]*/
+        /*strong.[null|subclass=JSInt]*/
+        x) =>
+    x;
 
 /*element: probe2methods:[exact=JSExtendableArray]*/
 probe2methods(/*[exact=JSExtendableArray]*/ x) => x;
diff --git a/tests/compiler/dart2js/inference/data/deferred_load_get.dart b/tests/compiler/dart2js/inference/data/deferred_load_get.dart
index 44b2121..a4b0fb6 100644
--- a/tests/compiler/dart2js/inference/data/deferred_load_get.dart
+++ b/tests/compiler/dart2js/inference/data/deferred_load_get.dart
@@ -6,7 +6,7 @@
 
 // Synthetic getter added by kernel.
 /*kernel.element: __loadLibrary_expect:[null|subclass=Object]*/
-/*strong.element: __loadLibrary_expect:[null|subclass=Object]*/
+/*strong.element: __loadLibrary_expect:[null|exact=_Future]*/
 
 /*element: main:[null]*/
 main() {
diff --git a/tests/compiler/dart2js/inference/data/expose_this_closure.dart b/tests/compiler/dart2js/inference/data/expose_this_closure.dart
index bffdc67..b60e4c9 100644
--- a/tests/compiler/dart2js/inference/data/expose_this_closure.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this_closure.dart
@@ -58,7 +58,11 @@
 
 abstract class SuperClass1 {
   /*element: SuperClass1.:[exact=Class3]*/
-  SuperClass1(/*[null|subclass=Object]*/ o);
+  SuperClass1(
+      /*ast.[null|subclass=Object]*/
+      /*kernel.[null|subclass=Object]*/
+      /*strong.[null|subclass=JSInt]*/
+      o);
 }
 
 class Class3 extends SuperClass1 {
diff --git a/tests/compiler/dart2js/inference/data/field_type.dart b/tests/compiler/dart2js/inference/data/field_type.dart
index aeec6f6..5fe9757 100644
--- a/tests/compiler/dart2js/inference/data/field_type.dart
+++ b/tests/compiler/dart2js/inference/data/field_type.dart
@@ -608,7 +608,12 @@
             bar24();
 
   /*element: A24.+:Value([exact=JSString], value: "foo")*/
-  operator +(/*[exact=JSUInt31]*/ other) => 'foo';
+  operator +(
+          /*ast.[exact=JSUInt31]*/
+          /*kernel.[exact=JSUInt31]*/
+          /*strong.[empty]*/
+          other) =>
+      'foo';
 
   /*element: A24.bar24:[exact=JSDouble]*/
   bar24() => 42.5;
diff --git a/tests/compiler/dart2js/inference/data/for_in.dart b/tests/compiler/dart2js/inference/data/for_in.dart
index d021fbc..d71083f 100644
--- a/tests/compiler/dart2js/inference/data/for_in.dart
+++ b/tests/compiler/dart2js/inference/data/for_in.dart
@@ -8,6 +8,7 @@
   forInReturn();
   forInReturnMulti();
   forInReturnRefined();
+  forInReturnRefinedDynamic();
   testInForIn();
   operatorInForIn();
   updateInForIn();
@@ -31,7 +32,9 @@
 // Return element from a for-in loop on a list literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: forInReturn:[null|subclass=Object]*/
+/*ast.element: forInReturn:[null|subclass=Object]*/
+/*kernel.element: forInReturn:[null|subclass=Object]*/
+/*strong.element: forInReturn:[null|subclass=JSInt]*/
 forInReturn() {
   /*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
   /*current: [exact=ArrayIterator]*/
@@ -75,6 +78,25 @@
   /*current: [exact=ArrayIterator]*/
   /*moveNext: [exact=ArrayIterator]*/
   for (var a in [1, 2, 3]) {
+    // TODO(johnniwinther): We should know the type of [a] here. Even if [a] has
+    // type `dynamic`.
+    a. /*strong.[null|subclass=JSInt]*/ isEven;
+    a. /*[subclass=JSInt]*/ isEven;
+    return a;
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Sequentially refine element and return it from a for-in loop on known list
+// type with a dynamic variable.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: forInReturnRefinedDynamic:[null|subclass=JSInt]*/
+forInReturnRefinedDynamic() {
+  /*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
+  /*current: [exact=ArrayIterator]*/
+  /*moveNext: [exact=ArrayIterator]*/
+  for (dynamic a in [1, 2, 3]) {
     // TODO(johnniwinther): We should know the type of [a] here.
     a.isEven;
     a. /*[subclass=JSInt]*/ isEven;
diff --git a/tests/compiler/dart2js/inference/data/general.dart b/tests/compiler/dart2js/inference/data/general.dart
index 867e759..1ca6af3 100644
--- a/tests/compiler/dart2js/inference/data/general.dart
+++ b/tests/compiler/dart2js/inference/data/general.dart
@@ -589,7 +589,10 @@
   var a = topLevelGetter();
   // Make [a] a captured variable. This should disable receiver
   // specialization on [a].
-  (/*[null|subclass=Object]*/ () => a.toString())();
+  (/*ast.[null|subclass=Object]*/
+      /*kernel.[null|subclass=Object]*/
+      /*strong.[null|exact=JSString]*/
+      () => a.toString())();
   a - 42;
   return a;
 }
@@ -664,9 +667,13 @@
 
 class A {
   factory A() = A.generative;
+
   /*element: A.generative:[exact=A]*/
   A.generative();
-  /*element: A.==:Union([exact=JSBool], [exact=JSUInt31])*/
+
+  /*ast.element: A.==:Union([exact=JSBool], [exact=JSUInt31])*/
+  /*kernel.element: A.==:Union([exact=JSBool], [exact=JSUInt31])*/
+  /*strong.element: A.==:[exact=JSBool]*/
   operator ==(/*Union([exact=JSString], [exact=JSUInt31])*/ other) =>
       42 as dynamic;
 
diff --git a/tests/compiler/dart2js/inference/data/js_interop.dart b/tests/compiler/dart2js/inference/data/js_interop.dart
index d8cdb06..168b52e 100644
--- a/tests/compiler/dart2js/inference/data/js_interop.dart
+++ b/tests/compiler/dart2js/inference/data/js_interop.dart
@@ -20,5 +20,7 @@
       {/*[exact=JSUInt31]*/ a, /*Value([exact=JSString], value: "")*/ b});
 }
 
-/*element: anonymousClass:[null|subclass=Object]*/
+/*ast.element: anonymousClass:[null|subclass=Object]*/
+/*kernel.element: anonymousClass:[null|subclass=Object]*/
+/*strong.element: anonymousClass:[null|subclass=JavaScriptObject]*/
 anonymousClass() => new Class1(a: 1, b: '');
diff --git a/tests/compiler/dart2js/inference/data/locals_notrust.dart b/tests/compiler/dart2js/inference/data/locals_notrust.dart
new file mode 100644
index 0000000..bf14080
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/locals_notrust.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2018, 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.
+
+/*element: main:[null]*/
+main() {
+  dontTrustLocals();
+  dontTrustFunctions();
+  inferFromFunctions();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test that we don't trust the explicit type of a local, unless we are in
+// strong mode.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: _dontTrustLocals:[exact=JSBool]*/ _dontTrustLocals(
+    int Function(int) /*[null|subclass=Closure]*/ f) {
+  int c = f(0);
+  return c /*strong.invoke: [null|subclass=JSInt]*/ == 0;
+}
+
+/*element: dontTrustLocals:[null]*/
+dontTrustLocals() {
+  _dontTrustLocals(/*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ o) => o);
+  _dontTrustLocals(null);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test that we don't infer the type of a dynamic local from the type of the
+// function.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: _dontTrustFunctions:[exact=JSBool]*/
+_dontTrustFunctions(int Function(int) /*[null|subclass=Closure]*/ f) {
+  dynamic c = f(0);
+  return c == 0;
+}
+
+/*element: dontTrustFunctions:[null]*/
+dontTrustFunctions() {
+  _dontTrustFunctions(/*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ o) => o);
+  _dontTrustFunctions(null);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test that we don't infer the type of a 'var' local from the type of the
+// function, unless we are in strong mode.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: _inferFromFunctions:[exact=JSBool]*/
+_inferFromFunctions(int Function(int) /*[null|subclass=Closure]*/ f) {
+  var c = f(0);
+  return c /*strong.invoke: [null|subclass=JSInt]*/ == 0;
+}
+
+/*element: inferFromFunctions:[null]*/
+inferFromFunctions() {
+  _inferFromFunctions(/*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ o) => o);
+  _inferFromFunctions(null);
+}
diff --git a/tests/compiler/dart2js/inference/data/locals_trust.dart b/tests/compiler/dart2js/inference/data/locals_trust.dart
new file mode 100644
index 0000000..f3dc89b
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/locals_trust.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2018, 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.
+
+/*element: main:[null]*/
+main() {
+  trustLocals();
+  dontTrustFunctions();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test that we trust the explicit type of a local with
+// --trust-type-annotations.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: _trustLocals:[exact=JSBool]*/ _trustLocals(
+    int Function(int) /*[null|subclass=Closure]*/ f) {
+  int c = f(0);
+  return c /*invoke: [null|subclass=JSInt]*/ == 0;
+}
+
+/*element: trustLocals:[null]*/
+trustLocals() {
+  _trustLocals(/*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ o) => o);
+  _trustLocals(null);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test that we don't trust the type of a function even with
+// --trust-type-annotations.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: _dontTrustFunctions:[exact=JSBool]*/
+_dontTrustFunctions(int Function(int) /*[null|subclass=Closure]*/ f) {
+  dynamic c = f(0);
+  return c == 0;
+}
+
+/*element: dontTrustFunctions:[null]*/
+dontTrustFunctions() {
+  _dontTrustFunctions(/*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ o) => o);
+  _dontTrustFunctions(null);
+}
diff --git a/tests/compiler/dart2js/inference/data/map_tracer_const.dart b/tests/compiler/dart2js/inference/data/map_tracer_const.dart
index 4b2bd43..2bfe52f 100644
--- a/tests/compiler/dart2js/inference/data/map_tracer_const.dart
+++ b/tests/compiler/dart2js/inference/data/map_tracer_const.dart
@@ -2,7 +2,9 @@
 // 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.
 
-/*element: closure:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*ast.element: closure:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*kernel.element: closure:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*strong.element: closure:[exact=JSUInt31]*/
 int closure(int /*Union([exact=JSDouble], [exact=JSUInt31])*/ x) {
   return x;
 }
diff --git a/tests/compiler/dart2js/inference/data/no_such_method.dart b/tests/compiler/dart2js/inference/data/no_such_method.dart
index c4225e3..09cce06 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method.dart
@@ -52,7 +52,13 @@
 class Class3 {
   /*element: Class3.noSuchMethod:[null|subclass=Object]*/
   noSuchMethod(Invocation /*[null|subclass=Object]*/ invocation) {
-    return invocation.positionalArguments.first;
+    return invocation
+        .
+        /*strong.[null|exact=JSInvocationMirror]*/
+        positionalArguments
+        .
+        /*strong.[exact=JSUnmodifiableArray]*/
+        first;
   }
 
   /*element: Class3.method:[null|subclass=Object]*/
@@ -78,8 +84,13 @@
 
   /*element: Class4.noSuchMethod:[null]*/
   noSuchMethod(Invocation /*[null|subclass=Object]*/ invocation) {
-    this. /*update: [exact=Class4]*/ field =
-        invocation.positionalArguments.first;
+    this. /*update: [exact=Class4]*/ field = invocation
+        .
+        /*strong.[null|exact=JSInvocationMirror]*/
+        positionalArguments
+        .
+        /*strong.[exact=JSUnmodifiableArray]*/
+        first;
     return null;
   }
 
diff --git a/tests/compiler/dart2js/inference/data/parameters_trust.dart b/tests/compiler/dart2js/inference/data/parameters_trust.dart
new file mode 100644
index 0000000..a36baa9
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/parameters_trust.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2018, 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:expect/expect.dart';
+
+/*element: main:[null]*/
+main() {
+  trustParameters();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test that we trust the explicit type of a parameter with
+// --trust-type-annotations.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: _trustParameters:[exact=JSUInt31]*/
+_trustParameters(
+    int
+        /*ast.[exact=JSUInt31]*/
+        /*kernel.[exact=JSUInt31]*/
+        /*strong.Union([exact=JSString], [exact=JSUInt31])*/
+        i) {
+  return i;
+}
+
+/*element: trustParameters:[null]*/
+trustParameters() {
+  dynamic f = _trustParameters;
+  Expect.equals(0, f(0));
+  Expect.throws(/*[null|subclass=Object]*/ () => f('foo'));
+}
diff --git a/tests/compiler/dart2js/inference/show.dart b/tests/compiler/dart2js/inference/show.dart
index 05389ea..94402a7 100644
--- a/tests/compiler/dart2js/inference/show.dart
+++ b/tests/compiler/dart2js/inference/show.dart
@@ -35,5 +35,5 @@
     kernelFunction = computeMemberIrTypeMasks;
   }
   await show(results, astFunction, kernelFunction,
-      options: [stopAfterTypeInference]);
+      options: [/*stopAfterTypeInference*/]);
 }
diff --git a/tests/compiler/dart2js/inference/side_effects_test.dart b/tests/compiler/dart2js/inference/side_effects_test.dart
index e1966a4..f0189f7 100644
--- a/tests/compiler/dart2js/inference/side_effects_test.dart
+++ b/tests/compiler/dart2js/inference/side_effects_test.dart
@@ -24,7 +24,10 @@
         new Directory.fromUri(Platform.script.resolve('side_effects'));
     await checkTests(
         dataDir, computeMemberAstSideEffects, computeMemberIrSideEffects,
-        args: args, options: [stopAfterTypeInference]);
+        args: args,
+        options: [stopAfterTypeInference],
+        // TODO(johnniwinther): Run tests with strong mode.
+        testStrongMode: false);
   });
 }
 
diff --git a/tests/compiler/dart2js/inlining/inlining_test.dart b/tests/compiler/dart2js/inlining/inlining_test.dart
index d3a6f0b..c14e939 100644
--- a/tests/compiler/dart2js/inlining/inlining_test.dart
+++ b/tests/compiler/dart2js/inlining/inlining_test.dart
@@ -28,7 +28,10 @@
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
     await checkTests(
         dataDir, computeMemberAstInlinings, computeMemberIrInlinings,
-        args: args, skipForAst: ['external.dart'], skipForKernel: []);
+        args: args,
+        skipForAst: ['external.dart'],
+        // TODO(johnniwinther): Run tests with strong mode.
+        testStrongMode: false);
   });
 }
 
diff --git a/tests/compiler/dart2js/jumps/jump_test.dart b/tests/compiler/dart2js/jumps/jump_test.dart
index b18da0e..2a911b4 100644
--- a/tests/compiler/dart2js/jumps/jump_test.dart
+++ b/tests/compiler/dart2js/jumps/jump_test.dart
@@ -24,7 +24,9 @@
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
     await checkTests(dataDir, computeJumpsData, computeKernelJumpsData,
         options: [Flags.disableTypeInference, stopAfterTypeInference],
-        args: args);
+        args: args,
+        // TODO(johnniwinther): Run tests with strong mode.
+        testStrongMode: false);
   });
 }
 
diff --git a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
index 9bff47f..4cbd4b9 100644
--- a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
+++ b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
@@ -94,6 +94,13 @@
   @override
   CommonElements get commonElements => _environment.commonElements;
 
+  @override
+  DartTypes get types => _environment.types;
+
+  @override
+  InterfaceType get enclosingConstructedType =>
+      _environment.enclosingConstructedType;
+
   void reportWarning(
       ConstantExpression expression, MessageKind kind, Map arguments) {
     errors.add(new EvaluationError(kind, arguments));
@@ -106,9 +113,10 @@
     _environment.reportError(expression, kind, arguments);
   }
 
-  ConstantValue evaluateConstructor(
-      ConstructorEntity constructor, ConstantValue evaluate()) {
-    return _environment.evaluateConstructor(constructor, evaluate);
+  @override
+  ConstantValue evaluateConstructor(ConstructorEntity constructor,
+      InterfaceType type, ConstantValue evaluate()) {
+    return _environment.evaluateConstructor(constructor, type, evaluate);
   }
 
   ConstantValue evaluateField(FieldEntity field, ConstantValue evaluate()) {
diff --git a/tests/compiler/dart2js/model/forwarding_stub_test.dart b/tests/compiler/dart2js/model/forwarding_stub_test.dart
new file mode 100644
index 0000000..ed86ed3
--- /dev/null
+++ b/tests/compiler/dart2js/model/forwarding_stub_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2018, 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:async_helper/async_helper.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common_elements.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/world.dart';
+import 'package:expect/expect.dart';
+import '../memory_compiler.dart';
+
+const String source = '''
+
+class Mixin<T> {
+  void method(T t) {}
+}
+class Super {}
+class Class extends Super with Mixin<int> {}
+
+main() {
+  new Class().method(0);
+}
+''';
+
+main() {
+  asyncTest(() async {
+    CompilationResult result = await (runCompiler(
+        memorySourceFiles: {'main.dart': source}, options: [Flags.strongMode]));
+    Expect.isTrue(result.isSuccess);
+    Compiler compiler = result.compiler;
+    ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
+    ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
+    ClassEntity cls =
+        elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'Class');
+    ClassEntity mixin =
+        elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'Mixin');
+    FunctionEntity method = elementEnvironment.lookupClassMember(cls, 'method');
+    Expect.isNotNull(method);
+    Expect.equals(mixin, method.enclosingClass);
+    Expect.isFalse(method.isAbstract);
+  });
+}
diff --git a/tests/compiler/dart2js/data/one_line_dart_program.dart b/tests/compiler/dart2js/old_frontend/data/one_line_dart_program.dart
similarity index 100%
rename from tests/compiler/dart2js/data/one_line_dart_program.dart
rename to tests/compiler/dart2js/old_frontend/data/one_line_dart_program.dart
diff --git a/tests/compiler/dart2js/zero_termination_test.dart b/tests/compiler/dart2js/old_frontend/zero_termination_test.dart
similarity index 70%
rename from tests/compiler/dart2js/zero_termination_test.dart
rename to tests/compiler/dart2js/old_frontend/zero_termination_test.dart
index 4a49e8c..0165af1 100644
--- a/tests/compiler/dart2js/zero_termination_test.dart
+++ b/tests/compiler/dart2js/old_frontend/zero_termination_test.dart
@@ -16,7 +16,7 @@
 import 'package:expect/expect.dart';
 import 'package:path/path.dart' as path;
 
-import 'end_to_end/launch_helper.dart' show launchDart2Js;
+import '../end_to_end/launch_helper.dart' show launchDart2Js;
 
 Uri pathOfData = Platform.script;
 Directory tempDir;
@@ -53,30 +53,35 @@
   Expect.notEquals(0, result.exitCode);
   List<int> stdout = result.stdout;
   String stdoutString = utf8.decode(stdout);
-  Expect.isTrue(stdoutString.contains("Error"));
+  Expect.isTrue(stdoutString.contains("Error"), "stdout:\n$stdoutString");
   // Make sure the "499" from the last line is in the output.
-  Expect.isTrue(stdoutString.contains("499"));
+  Expect.isTrue(stdoutString.contains("499"), "stdout:\n$stdoutString");
 
   // Make sure that the output does not contain any 0 character.
   Expect.isFalse(stdout.contains(0));
 }
 
-Future testFile({bool useKernel}) async {
+Future testFile() async {
   String inFilePath =
       pathOfData.resolve('data/one_line_dart_program.dart').path;
-  List<String> args = [inFilePath, "--out=" + outFilePath];
-  if (!useKernel) args.add(Flags.useOldFrontend);
-
+  List<String> args = [
+    inFilePath,
+    "--out=" + outFilePath,
+    Flags.useOldFrontend
+  ];
   await cleanup();
   check(await launchDart2Js(args, noStdoutEncoding: true));
   await cleanup();
 }
 
-Future serverRunning(HttpServer server, {bool useKernel}) async {
+Future serverRunning(HttpServer server) async {
   int port = server.port;
   String inFilePath = "http://127.0.0.1:$port/data/one_line_dart_program.dart";
-  List<String> args = [inFilePath, "--out=" + outFilePath];
-  if (!useKernel) args.add(Flags.useOldFrontend);
+  List<String> args = [
+    inFilePath,
+    "--out=" + outFilePath,
+    Flags.useOldFrontend
+  ];
 
   server.listen(handleRequest);
   try {
@@ -88,22 +93,19 @@
   }
 }
 
-Future testHttp({bool useKernel}) {
+Future testHttp() {
   return HttpServer
       .bind(InternetAddress.LOOPBACK_IP_V4, 0)
-      .then((HttpServer server) => serverRunning(server, useKernel: useKernel));
+      .then((HttpServer server) => serverRunning(server));
 }
 
-runTests({bool useKernel}) async {
+runTests() async {
   tempDir = Directory.systemTemp.createTempSync('directory_test');
   outFilePath = path.join(tempDir.path, "out.js");
 
   try {
-    await testFile(useKernel: useKernel);
-    if (!useKernel) {
-      // TODO(johnniwinther): Handle this test for kernel.
-      await testHttp(useKernel: useKernel);
-    }
+    await testFile();
+    await testHttp();
   } finally {
     await tempDir.delete(recursive: true);
   }
@@ -111,9 +113,6 @@
 
 main() {
   asyncTest(() async {
-    print('--test from ast---------------------------------------------------');
-    await runTests(useKernel: false);
-    print('--test from kernel------------------------------------------------');
-    await runTests(useKernel: true);
+    await runTests();
   });
 }
diff --git a/tests/compiler/dart2js/rti/data/closure.dart b/tests/compiler/dart2js/rti/data/closure.dart
index 6baf68e..7b45cde 100644
--- a/tests/compiler/dart2js/rti/data/closure.dart
+++ b/tests/compiler/dart2js/rti/data/closure.dart
@@ -10,7 +10,8 @@
 
   /*element: A.f:*/
   f() {
-    return /**/ (int t) {};
+    // TODO(johnniwinther): Optimize local function type signature need.
+    return /*ast.*/ /*kernel.*/ /*strong.needsSignature*/ (int t) {};
   }
 }
 
diff --git a/tests/compiler/dart2js/rti/data/closure_unneeded.dart b/tests/compiler/dart2js/rti/data/closure_unneeded.dart
index 5e985bd..5ba4637 100644
--- a/tests/compiler/dart2js/rti/data/closure_unneeded.dart
+++ b/tests/compiler/dart2js/rti/data/closure_unneeded.dart
@@ -4,11 +4,14 @@
 
 import 'package:expect/expect.dart';
 
-/*class: A:*/
+/*ast.class: A:*/
+/*kernel.class: A:*/
+/*strong.class: A:needsArgs*/
 class A<T> {
   @NoInline()
   m() {
-    return /**/ (T t, String s) {};
+    // TODO(johnniwinther): Optimize local function type signature need.
+    return /*ast.*/ /*kernel.*/ /*strong.needsSignature*/ (T t, String s) {};
   }
 }
 
diff --git a/tests/compiler/dart2js/rti/data/function_subtype_local5.dart b/tests/compiler/dart2js/rti/data/function_subtype_local5.dart
index 5acd91f..521daf0 100644
--- a/tests/compiler/dart2js/rti/data/function_subtype_local5.dart
+++ b/tests/compiler/dart2js/rti/data/function_subtype_local5.dart
@@ -17,7 +17,10 @@
 /*class: C:explicit=[int Function(C.T),int Function(C.T,[String]),int Function(C.T,int),int Function(C.T,{,b:String})],needsArgs*/
 class C<T> {
   void test(String nameOfT, bool expectedResult) {
+    // TODO(johnniwinther): Optimize local function type signature need.
+    /*ast.*/ /*kernel.*/ /*strong.needsSignature*/
     int foo(bool a, [String b]) => null;
+    /*ast.*/ /*kernel.*/ /*strong.needsSignature*/
     int baz(bool a, {String b}) => null;
 
     Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
diff --git a/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart b/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
index 1f6c15e..a9fb97fe 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
@@ -8,7 +8,9 @@
 /*class: B:deps=[method],explicit=[B<A>],needsArgs*/
 class B<T> {}
 
-/*element: method:*/
+/*ast.element: method:*/
+/*kernel.element: method:*/
+/*strong.element: method:needsArgs*/
 method<T>() => new B<T>();
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_method_instantiate_strong.dart b/tests/compiler/dart2js/rti/data/generic_method_instantiate_strong.dart
deleted file mode 100644
index 8364623..0000000
--- a/tests/compiler/dart2js/rti/data/generic_method_instantiate_strong.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2018, 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.
-
-/*class: A:explicit=[B<A>]*/
-class A {}
-
-/*class: B:deps=[method],explicit=[B<A>],needsArgs*/
-class B<T> {}
-
-/*element: method:needsArgs*/
-method<T>() => new B<T>();
-
-main() {
-  method<A>() is B<A>;
-}
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is.dart b/tests/compiler/dart2js/rti/data/generic_method_is.dart
index 4adc872..5478c03 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_is.dart
@@ -2,7 +2,9 @@
 // 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.
 
-/*element: method:direct,explicit=[method.T]*/
+/*ast.element: method:direct,explicit=[method.T]*/
+/*kernel.element: method:direct,explicit=[method.T]*/
+/*strong.element: method:direct,explicit=[method.T],needsArgs*/
 method<T>(T t) => t is T;
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/list_to_set.dart b/tests/compiler/dart2js/rti/data/list_to_set.dart
index f858a43..1d86288 100644
--- a/tests/compiler/dart2js/rti/data/list_to_set.dart
+++ b/tests/compiler/dart2js/rti/data/list_to_set.dart
@@ -4,8 +4,11 @@
 
 /*ast.class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin,SubListIterable],explicit=[List],implicit=[List.E],indirect,needsArgs*/
 /*kernel.class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin],explicit=[List],implicit=[List.E],indirect,needsArgs*/
+/*strong.class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin],explicit=[List],implicit=[List.E],indirect,needsArgs*/
+
 /*ast.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
 /*kernel.class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
+/*strong.class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
 
 main() {
   var c = new Class<int>();
diff --git a/tests/compiler/dart2js/rti/emission/function_type_argument_strong.dart b/tests/compiler/dart2js/rti/emission/function_type_argument_strong.dart
new file mode 100644
index 0000000..7b56dde
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/function_type_argument_strong.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2018, 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:expect/expect.dart';
+import 'package:meta/dart2js.dart';
+
+/*class: C:checks=[],instance,typeArgument*/
+class C {
+  call(int i) {}
+}
+
+/*class: D:checks=[],instance,typeArgument*/
+class D {
+  call(double i) {}
+}
+
+@noInline
+test1(o) => o is Function(int);
+
+@noInline
+test2(o) => o is List<Function(int)>;
+
+main() {
+  Expect.isFalse(test1(new C()));
+  Expect.isFalse(test1(new D()));
+  Expect.isFalse(test2(<C>[]));
+  Expect.isFalse(test2(<D>[]));
+}
diff --git a/tests/compiler/dart2js/rti/emission/list.dart b/tests/compiler/dart2js/rti/emission/list.dart
index bfcd830..565ea00 100644
--- a/tests/compiler/dart2js/rti/emission/list.dart
+++ b/tests/compiler/dart2js/rti/emission/list.dart
@@ -4,7 +4,10 @@
 
 import 'package:meta/dart2js.dart';
 
-/*class: global#JSArray:checkedInstance,checks=[$isIterable],instance*/
+/*ast.class: global#JSArray:checkedInstance,checks=[$isIterable],instance*/
+/*kernel.class: global#JSArray:checkedInstance,checks=[$isIterable],instance*/
+/*strong.class: global#JSArray:checkedInstance,checks=[$isIterable,$isList],instance*/
+
 /*class: global#Iterable:checkedInstance*/
 
 /*class: A:checkedTypeArgument,checks=[],typeArgument*/
diff --git a/tests/compiler/dart2js/rti/emission/map_literal.dart b/tests/compiler/dart2js/rti/emission/map_literal.dart
index d666180..4df5013 100644
--- a/tests/compiler/dart2js/rti/emission/map_literal.dart
+++ b/tests/compiler/dart2js/rti/emission/map_literal.dart
@@ -2,10 +2,17 @@
 // 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.
 
-/*class: global#Map:instance*/
+/*ast.class: global#Map:instance*/
+/*kernel.class: global#Map:instance*/
+/*strong.class: global#Map:checkedInstance,checks=[],instance*/
+
 /*class: global#LinkedHashMap:*/
 /*class: global#JsLinkedHashMap:checks=[],instance*/
-/*class: global#double:checks=[],instance,typeArgument*/
+
+/*ast.class: global#double:checks=[],instance,typeArgument*/
+/*kernel.class: global#double:checks=[],instance,typeArgument*/
+/*strong.class: global#double:checkedInstance,checks=[],instance,typeArgument*/
+
 /*class: global#JSDouble:checks=[],instance*/
 
 main() {
diff --git a/tests/compiler/dart2js/rti/rti_emission_test.dart b/tests/compiler/dart2js/rti/rti_emission_test.dart
index f7b516b..5408325 100644
--- a/tests/compiler/dart2js/rti/rti_emission_test.dart
+++ b/tests/compiler/dart2js/rti/rti_emission_test.dart
@@ -27,15 +27,24 @@
     Directory dataDir =
         new Directory.fromUri(Platform.script.resolve('emission'));
     await checkTests(
-        dataDir, computeAstRtiMemberEmission, computeKernelRtiMemberEmission,
-        computeClassDataFromAst: computeAstRtiClassEmission,
-        computeClassDataFromKernel: computeKernelRtiClassEmission,
-        args: args,
-        skipForKernel: [
-          // TODO(johnniwinther): Fix this. It triggers a crash in the ssa
-          // builder.
-          'runtime_type.dart',
-        ]);
+      dataDir,
+      computeAstRtiMemberEmission,
+      computeKernelRtiMemberEmission,
+      computeClassDataFromAst: computeAstRtiClassEmission,
+      computeClassDataFromKernel: computeKernelRtiClassEmission,
+      args: args,
+      skipForStrong: [
+        // Dart 1 semantics:
+        'call.dart',
+        'call_typed.dart',
+        'call_typed_generic.dart',
+        'function_subtype_call2.dart',
+        'function_type_argument.dart',
+        'map_literal_checked.dart',
+        // TODO(johnniwinther): Optimize local function type signature need.
+        'subtype_named_args.dart',
+      ],
+    );
   });
 }
 
diff --git a/tests/compiler/dart2js/rti/rti_need_test.dart b/tests/compiler/dart2js/rti/rti_need_test.dart
index 644acd6..4768628 100644
--- a/tests/compiler/dart2js/rti/rti_need_test.dart
+++ b/tests/compiler/dart2js/rti/rti_need_test.dart
@@ -36,6 +36,12 @@
         computeClassDataFromAst: computeAstRtiClassNeed,
         computeClassDataFromKernel: computeKernelRtiClassNeed,
         options: [Flags.omitImplicitChecks], // only used in strong-mode
+        skipForStrong: [
+          'map_literal_checked.dart',
+          // TODO(johnniwinther): Optimize local function type signature need.
+          'subtype_named_args.dart',
+          'subtype_named_args1.dart',
+        ],
         args: args);
   });
 }
diff --git a/tests/compiler/dart2js_extra/32770a_test.dart b/tests/compiler/dart2js_extra/32770a_test.dart
new file mode 100644
index 0000000..24aeb60
--- /dev/null
+++ b/tests/compiler/dart2js_extra/32770a_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2018, 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.
+
+// dart2jsOptions=--strong
+
+// Regression test for issue 32770.
+
+import 'package:expect/expect.dart';
+
+dynamic f;
+dynamic g;
+
+class A {}
+
+class B extends A {}
+
+class C extends A {}
+
+class Class<T> {
+  void Function(E) method<E, F extends E>(void Function(F) callback) {
+    return (E event) {
+      g = () => callback(event as F);
+    };
+  }
+}
+
+main() {
+  f = new Class<String>().method<A, B>((o) => print(o));
+  f(new B());
+  g();
+  f(new C());
+  Expect.throws(() => g(), (_) => true);
+}
diff --git a/tests/compiler/dart2js_extra/32770b_test.dart b/tests/compiler/dart2js_extra/32770b_test.dart
new file mode 100644
index 0000000..f58bcf5
--- /dev/null
+++ b/tests/compiler/dart2js_extra/32770b_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2018, 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.
+
+// dart2jsOptions=--strong
+
+// Regression test for issue 32770.
+
+import 'package:expect/expect.dart';
+
+dynamic f;
+dynamic g;
+
+class A {}
+
+class B extends A {}
+
+class C extends A {}
+
+class Class<T> {
+  void Function(E) method<E, F extends E>(bool Function(bool) callback) {
+    return (E event) {
+      g = () => callback(event is F);
+    };
+  }
+}
+
+main() {
+  f = new Class<String>().method<A, B>((o) => o);
+  f(new B());
+  Expect.isTrue(g());
+  f(new C());
+  Expect.isFalse(g());
+}
diff --git a/tests/compiler/dart2js_extra/32770c_test.dart b/tests/compiler/dart2js_extra/32770c_test.dart
new file mode 100644
index 0000000..15ac166
--- /dev/null
+++ b/tests/compiler/dart2js_extra/32770c_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2018, 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.
+
+// dart2jsOptions=--strong
+
+// Regression test for issue 32770.
+
+import 'dart:async' show Future;
+
+A<J> futureToA<T, J>(Future<T> future, [J wrapValue(T value)]) {
+  return new A<J>(
+    (void resolveFn(J value), void rejectFn(error)) {
+      future.then((value) {
+        dynamic wrapped;
+        if (wrapValue != null) {
+          wrapped = wrapValue(value);
+        } else if (value != null) {
+          wrapped = value;
+        }
+        resolveFn(wrapped);
+      }).catchError((error) {
+        rejectFn(error);
+      });
+    },
+  );
+}
+
+class A<X> {
+  var x;
+
+  A(this.x);
+}
+
+main() {
+  print(futureToA);
+}
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is_strong.dart b/tests/compiler/dart2js_extra/eof_line_ending_test.dart
similarity index 61%
rename from tests/compiler/dart2js/rti/data/generic_method_is_strong.dart
rename to tests/compiler/dart2js_extra/eof_line_ending_test.dart
index dea3540..dafba6c 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is_strong.dart
+++ b/tests/compiler/dart2js_extra/eof_line_ending_test.dart
@@ -1,10 +1,10 @@
-// Copyright (c) 2018, 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.
-
-/*element: method:direct,explicit=[method.T],needsArgs*/
-method<T>(T t) => t is T;
-
-main() {
-  method<int>(0);
-}
+// Copyright (c) 2018, 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.

+

+// Regression test derived from language/issue_1578_test.dart with Windows

+// line encoding.

+

+main() {}

+

+]~<)$ //# 01: compile-time error

diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index 90bd0d6..b35abb8 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -213,15 +213,7 @@
 
 [ $compiler == dart2js && $fasta && $host_checked && $strong ]
 apply3_test: RuntimeError
-bigint_parse_radix_test: RuntimeError
-bigint_test: RuntimeError
 cast_test: RuntimeError
-date_time2_test: RuntimeError
-date_time3_test: RuntimeError
-date_time4_test: RuntimeError
-date_time7_test: RuntimeError
-date_time_parse_test: RuntimeError
-date_time_test: RuntimeError
 dynamic_nosuchmethod_test: RuntimeError
 error_stack_trace1_test: RuntimeError # Issue 12399
 growable_list_test: RuntimeError # Concurrent modifications test always runs
@@ -235,69 +227,14 @@
 iterable_return_type_test/01: RuntimeError # Issue 20085
 iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
 iterable_to_list_test/01: RuntimeError # Issue 26501
-json_map_test: RuntimeError
 list_concurrent_modify_test: RuntimeError # dart2js does not fully implement these
 list_test/01: RuntimeError
 list_test/none: RuntimeError
 list_unmodifiable_test: RuntimeError
 main_test: RuntimeError
 nan_infinity_test/01: RuntimeError
-reg_exp_all_matches_test: RuntimeError
-reg_exp_cache_test: RuntimeError
-reg_exp_first_match_test: RuntimeError
-reg_exp_group_test: RuntimeError
-reg_exp_groups_test: RuntimeError
-reg_exp_start_end_test: RuntimeError
-reg_exp_string_match_test: RuntimeError
-regexp/UC16_test: RuntimeError
-regexp/alternatives_test: RuntimeError
-regexp/assertion_test: RuntimeError
-regexp/bol-with-multiline_test: RuntimeError
-regexp/bol_test: RuntimeError
-regexp/capture-3_test: RuntimeError
-regexp/capture_test: RuntimeError
-regexp/character-match-out-of-order_test: RuntimeError
-regexp/default_arguments_test: RuntimeError
-regexp/dotstar_test: RuntimeError
-regexp/early-acid3-86_test: RuntimeError
-regexp/ecma-regex-examples_test: RuntimeError
-regexp/extended-characters-match_test: RuntimeError
-regexp/find-first-asserted_test: RuntimeError
-regexp/global_test: RuntimeError
-regexp/indexof_test: RuntimeError
-regexp/invalid-range-in-class_test: RuntimeError
-regexp/lastindex_test: RuntimeError
-regexp/look-ahead_test: RuntimeError
-regexp/lookahead_test: RuntimeError
-regexp/loop-capture_test: RuntimeError
-regexp/many-brackets_test: RuntimeError
-regexp/no-extensions_test: RuntimeError
-regexp/non-bmp_test: RuntimeError
-regexp/non-capturing-backtracking_test: RuntimeError
-regexp/non-capturing-groups_test: RuntimeError
-regexp/non-greedy-parentheses_test: RuntimeError
-regexp/parentheses_test: RuntimeError
-regexp/pcre-test-4_test: RuntimeError
 regexp/pcre_test: RuntimeError
-regexp/range-bound-ffff_test: RuntimeError
-regexp/ranges-and-escaped-hyphens_test: RuntimeError
-regexp/regexp_escape_test: RuntimeError
-regexp/regexp_kde_test: RuntimeError
-regexp/regexp_test: RuntimeError
-regexp/regress-regexp-codeflush_test: RuntimeError
-regexp/regress-regexp-construct-result_test: RuntimeError
-regexp/repeat-match-waldemar_test: RuntimeError
-regexp/stack-overflow2_test: RuntimeError
-regexp/stack-overflow_test: RuntimeError
-regexp/standalones_test: RuntimeError
-regexp/unicode-handling_test: RuntimeError
-regexp/zero-length-alternatives_test: RuntimeError
-string_from_list_test: RuntimeError
-string_fromcharcodes_test: RuntimeError
-string_replace_test: RuntimeError
 string_split_test/checkedstore: RuntimeError # Issue 30548: does not check stores into List<String>
-string_split_test/none: RuntimeError
-string_test: RuntimeError
 symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
 uri_base_test: RuntimeError
 uri_parameters_all_test: RuntimeError
@@ -305,15 +242,7 @@
 
 [ $compiler == dart2js && $fasta && $minified && $strong ]
 apply3_test: RuntimeError
-bigint_parse_radix_test: RuntimeError
-bigint_test: RuntimeError
 cast_test: RuntimeError
-date_time2_test: RuntimeError
-date_time3_test: RuntimeError
-date_time4_test: RuntimeError
-date_time7_test: RuntimeError
-date_time_parse_test: RuntimeError
-date_time_test: RuntimeError
 dynamic_nosuchmethod_test: RuntimeError
 error_stack_trace1_test: RuntimeError # Issue 12399
 growable_list_test: RuntimeError # Concurrent modifications test always runs
@@ -328,7 +257,6 @@
 iterable_return_type_test/01: RuntimeError # Issue 20085
 iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
 iterable_to_list_test/01: RuntimeError # Issue 26501
-json_map_test: RuntimeError
 list_concurrent_modify_test: RuntimeError # dart2js does not fully implement these
 list_test/01: RuntimeError
 list_test/none: RuntimeError
@@ -336,62 +264,8 @@
 main_test: RuntimeError
 nan_infinity_test/01: RuntimeError
 nsm_invocation_test: RuntimeError # Symbols don't match due to minifiaction.
-reg_exp_all_matches_test: RuntimeError
-reg_exp_cache_test: RuntimeError
-reg_exp_first_match_test: RuntimeError
-reg_exp_group_test: RuntimeError
-reg_exp_groups_test: RuntimeError
-reg_exp_start_end_test: RuntimeError
-reg_exp_string_match_test: RuntimeError
-regexp/UC16_test: RuntimeError
-regexp/alternatives_test: RuntimeError
-regexp/assertion_test: RuntimeError
-regexp/bol-with-multiline_test: RuntimeError
-regexp/bol_test: RuntimeError
-regexp/capture-3_test: RuntimeError
-regexp/capture_test: RuntimeError
-regexp/character-match-out-of-order_test: RuntimeError
-regexp/default_arguments_test: RuntimeError
-regexp/dotstar_test: RuntimeError
-regexp/early-acid3-86_test: RuntimeError
-regexp/ecma-regex-examples_test: RuntimeError
-regexp/extended-characters-match_test: RuntimeError
-regexp/find-first-asserted_test: RuntimeError
-regexp/global_test: RuntimeError
-regexp/indexof_test: RuntimeError
-regexp/invalid-range-in-class_test: RuntimeError
-regexp/lastindex_test: RuntimeError
-regexp/look-ahead_test: RuntimeError
-regexp/lookahead_test: RuntimeError
-regexp/loop-capture_test: RuntimeError
-regexp/many-brackets_test: RuntimeError
-regexp/no-extensions_test: RuntimeError
-regexp/non-bmp_test: RuntimeError
-regexp/non-capturing-backtracking_test: RuntimeError
-regexp/non-capturing-groups_test: RuntimeError
-regexp/non-greedy-parentheses_test: RuntimeError
-regexp/parentheses_test: RuntimeError
-regexp/pcre-test-4_test: RuntimeError
 regexp/pcre_test: RuntimeError
-regexp/range-bound-ffff_test: RuntimeError
-regexp/ranges-and-escaped-hyphens_test: RuntimeError
-regexp/regexp_escape_test: RuntimeError
-regexp/regexp_kde_test: RuntimeError
-regexp/regexp_test: RuntimeError
-regexp/regress-regexp-codeflush_test: RuntimeError
-regexp/regress-regexp-construct-result_test: RuntimeError
-regexp/repeat-match-waldemar_test: RuntimeError
-regexp/stack-overflow2_test: RuntimeError
-regexp/stack-overflow_test: RuntimeError
-regexp/standalones_test: RuntimeError
-regexp/unicode-handling_test: RuntimeError
-regexp/zero-length-alternatives_test: RuntimeError
-string_from_list_test: RuntimeError
-string_fromcharcodes_test: RuntimeError
-string_replace_test: RuntimeError
 string_split_test/checkedstore: RuntimeError # Issue 30548: does not check stores into List<String>
-string_split_test/none: RuntimeError
-string_test: RuntimeError
 symbol_operator_test/03: RuntimeError
 symbol_operator_test/none: RuntimeError
 symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
@@ -399,9 +273,6 @@
 uri_parameters_all_test: RuntimeError
 uri_test: RuntimeError
 
-[ $compiler == dart2js && $fasta && $strong ]
-shuffle_test: RuntimeError
-
 [ $compiler == dart2js && $fasta && !$strong ]
 *: SkipByDesign
 
@@ -755,6 +626,6 @@
 
 [ $hot_reload || $hot_reload_rollback ]
 bigint_parse_radix_test: Pass, Timeout # Issue 31659
-bigint_test: Pass, Crash # Issue 31660
+bigint_test: Pass, Slow, Crash # Issue 31660
 integer_parsed_mul_div_vm_test: Pass, Slow # Slow
 
diff --git a/tests/language/language.status b/tests/language/language.status
index 78000d4..523475a 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -314,6 +314,13 @@
 assertion_initializer_const_error_test/01: MissingCompileTimeError
 assertion_initializer_const_function_error_test/01: MissingCompileTimeError
 
+# Detection of compile-time errors that are related to constants can't be fully
+# done at the front end, because constants are evaluated at back ends.  So, some
+# errors aren't detected by fasta, but reported by back ends as compile-time
+# errors.
+[ $compiler != dart2js && $runtime != vm && $fasta ]
+deferred_constraints_constants_test/default_argument2: MissingCompileTimeError
+
 [ $compiler != dartk && $compiler != dartkp && ($runtime == dart_precompiled || $runtime == flutter || $runtime == vm) ]
 abstract_beats_arguments2_test/01: Crash # Issue 29171
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 25c60c3..31043ca 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -63,6 +63,12 @@
 named_parameters3_test: RuntimeError
 named_parameters4_test: RuntimeError
 
+[ $compiler == dart2js && $system == windows && $fasta ]
+deep_nesting2_negative_test: Pass, Crash
+illegal_declaration_test/01: Pass, Crash
+issue1578_negative_test: Pass, Crash
+regress_23051_test/01: Pass, Crash
+
 [ $compiler == dart2js && $system == windows && !$fasta && ($runtime == chrome || $runtime == ff) ]
 string_literals_test: RuntimeError # Issue 27533
 
diff --git a/tests/language/language_kernel.status b/tests/language/language_kernel.status
index 4eb9408..89fe0d9 100644
--- a/tests/language/language_kernel.status
+++ b/tests/language/language_kernel.status
@@ -3,6 +3,8 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == fasta ]
+function_type_parameter2_negative_test: Fail
+function_type_parameter_negative_test: Fail
 prefix5_negative_test: Fail
 
 [ $fasta ]
diff --git a/tests/language_2/assertion_initializer_const_error2_test.dart b/tests/language_2/assertion_initializer_const_error2_test.dart
index e406b4a..dd152a3 100644
--- a/tests/language_2/assertion_initializer_const_error2_test.dart
+++ b/tests/language_2/assertion_initializer_const_error2_test.dart
@@ -2,6 +2,7 @@
 // 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.
 // VMOptions=--assert_initializer
+// dart2jsOptions=--enable-asserts
 //
 // Test of asserts in initializer lists.
 
diff --git a/tests/language_2/const_cast1_test.dart b/tests/language_2/const_cast1_test.dart
new file mode 100644
index 0000000..2363f3f
--- /dev/null
+++ b/tests/language_2/const_cast1_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2018, 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.
+
+/// Implicit casts in constants are supported and treated as compile-time errors
+/// if they are not valid.
+
+class A {
+  final int n;
+  const A(dynamic input) : n = input;
+}
+
+main() {
+  print(const A(2)); //# 01: ok
+  print(const A('2')); //# 02: compile-time error
+}
diff --git a/tests/language_2/const_cast2_test.dart b/tests/language_2/const_cast2_test.dart
new file mode 100644
index 0000000..326a884
--- /dev/null
+++ b/tests/language_2/const_cast2_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2018, 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.
+
+/// Explicit casts in constants are supported and treated as compile-time errors
+/// if they are not valid.
+
+class A {
+  final int n;
+  const A(dynamic input) : n = input as int;
+}
+
+main() {
+  print(const A(2)); //# 01: ok
+  print(const A('2')); //# 02: compile-time error
+}
diff --git a/tests/language_2/const_cast3_test.dart b/tests/language_2/const_cast3_test.dart
new file mode 100644
index 0000000..f7d7354
--- /dev/null
+++ b/tests/language_2/const_cast3_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, 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.
+
+/// Casts in constants correctly substitute type variables.
+
+class A {
+  const A();
+}
+
+class B implements A {
+  const B();
+}
+
+class M<T extends A> {
+  final T a;
+  const M(dynamic t) : a = t; // adds implicit cast `as T`
+}
+
+main() {
+  print(const M<B>(const B()));
+}
diff --git a/tests/language_2/implicit_creation/implicit_new_or_const_composite_test.dart b/tests/language_2/implicit_creation/implicit_new_or_const_composite_test.dart
index 54092f7..1a7debe 100644
--- a/tests/language_2/implicit_creation/implicit_new_or_const_composite_test.dart
+++ b/tests/language_2/implicit_creation/implicit_new_or_const_composite_test.dart
@@ -29,12 +29,12 @@
 
     const cd1 = const C(const D<int>(42));
     const cd2 = C(D<int>(42)); // Const context.
-    var cd3 = C(D<int>(42)); // All constant, even in non-const context.
-    var cd4 = C(D<int>(x)); // x is a non-constant expression, so `new`.
-    var cd5 = C(d42); //  d42 is a non-constant expression, so `new`.
+    var cd3 = C(D<int>(42)); // Non-constant context, so `new`.
+    var cd4 = C(D<int>(x)); // Non-constant context, so `new`.
+    var cd5 = C(d42); // Non-constant context, so `new`.
 
     Expect.identical(cd1, cd2);
-    Expect.identical(cd1, cd3);
+    Expect.allDistinct([cd1, cd3]);
     Expect.allDistinct([cd1, cd4, cd5]);
   }
 
@@ -44,16 +44,16 @@
     const cl2 = C(clist); // Constant context.
     const cl3 = C(const <int>[37]); // Constant context.
     const cl4 = C(<int>[37]);
-    var cl5 = C(clist); // Constant argument, so const.
-    var cl6 = C(const <int>[37]); // Constant arg, so const.
-    var cl7 = C(list); // Non-constant arg.
-    var cl8 = C(<int>[37]); // Same if literal.
+    var cl5 = C(clist); // Non-constant context, so `new`.
+    var cl6 = C(const <int>[37]); // Non-constant context, so `new`.
+    var cl7 = C(list); // Non-constant context, so `new`.
+    var cl8 = C(<int>[37]); // Non-constant context, so `new`.
 
     Expect.identical(cl1, cl2);
     Expect.identical(cl1, cl3);
     Expect.identical(cl1, cl4);
-    Expect.identical(cl1, cl5);
-    Expect.identical(cl1, cl6);
+    Expect.allDistinct([cl1, cl5]);
+    Expect.allDistinct([cl1, cl6]);
     Expect.allDistinct([cl1, cl7, cl8]);
   }
 
@@ -62,15 +62,15 @@
     const cm1 = C(cmap); // Constant context.
     const cm2 = C(const <int, int>{19: 87}); // Constant context.
     const cm3 = C(<int, int>{19: 87}); // Constant context.
-    var cm4 = C(cmap); // Constant argument, so const.
-    var cm5 = C(const <int, int>{19: 87}); // Constant arg, so const.
-    var cm6 = C(map); // Non-constant arg, non-const context.
-    var cm7 = C(<int, int>{19: 87}); // Same if literal.
+    var cm4 = C(cmap); // Non-constant context, so `new`.
+    var cm5 = C(const <int, int>{19: 87}); // Non-constant context, so `new`.
+    var cm6 = C(map); // Non-constant context, so `new`.
+    var cm7 = C(<int, int>{19: 87}); // Non-constant context, so `new`.
 
     Expect.identical(cm1, cm2);
     Expect.identical(cm1, cm3);
-    Expect.identical(cm1, cm4);
-    Expect.identical(cm1, cm5);
+    Expect.allDistinct([cm1, cm4]);
+    Expect.allDistinct([cm1, cm5]);
     Expect.allDistinct([cm1, cm6, cm7]);
   }
 
@@ -93,8 +93,8 @@
 
     Expect.identical(n1, n2);
     Expect.identical(n1, n3);
-    Expect.identical(n1, n4);
-    Expect.identical(n1, n8);
+    Expect.allDistinct([n1, n4]);
+    Expect.allDistinct([n1, n8]);
     Expect.allDistinct([n1, n5, n6, n7, n9, n10, n11, n12, n13, n14]);
 
     Expect.identical(clist, n6.left);
@@ -128,12 +128,12 @@
     Expect.identical(n20, n22);
     Expect.identical(n20, n23);
     Expect.identical(n20, n24);
-    Expect.identical(n20, n25);
-    Expect.identical(n20, n26);
-    Expect.identical(n20, n27);
+    Expect.allDistinct([n20, n25]);
+    Expect.allDistinct([n20, n26]);
+    Expect.allDistinct([n20, n27]);
     Expect.allDistinct([n28, n29, n30, n31]);
-    Expect.identical(cc42, n28.left);
-    Expect.identical(cc42, n29.left);
+    Expect.allDistinct([cc42, n28.left]);
+    Expect.allDistinct([cc42, n29.left]);
     Expect.identical(cc42, n30.left);
     Expect.identical(cc42, n31.left);
     Expect.identical(clist, n29.right);
@@ -185,10 +185,10 @@
     // List literals are never const unless in const context.
     Expect.allDistinct([l20, l25, l26, l27, l28, l29, l30, l31]);
     Expect.identical(cc42, l25[0]);
-    Expect.identical(cc42, l26[0]);
-    Expect.identical(cc42, l27[0]);
-    Expect.identical(cc42, l28[0]);
-    Expect.identical(cc42, l29[0]);
+    Expect.allDistinct([cc42, l26[0]]);
+    Expect.allDistinct([cc42, l27[0]]);
+    Expect.allDistinct([cc42, l28[0]]);
+    Expect.allDistinct([cc42, l29[0]]);
     Expect.identical(cc42, l30[0]);
     Expect.identical(cc42, l31[0]);
     Expect.identical(clist, l25[1]);
@@ -236,10 +236,10 @@
     // Map literals are never const unless in const context.
     Expect.allDistinct([m20, m25, m26, m27, m28, m29, m30, m31]);
     Expect.identical(cc42, m25.keys.first);
-    Expect.identical(cc42, m26.keys.first);
-    Expect.identical(cc42, m27.keys.first);
-    Expect.identical(cc42, m28.keys.first);
-    Expect.identical(cc42, m29.keys.first);
+    Expect.allDistinct([cc42, m26.keys.first]);
+    Expect.allDistinct([cc42, m27.keys.first]);
+    Expect.allDistinct([cc42, m28.keys.first]);
+    Expect.allDistinct([cc42, m29.keys.first]);
     Expect.identical(cc42, m30.keys.first);
     Expect.identical(cc42, m31.keys.first);
     Expect.identical(clist, m25.values.first);
diff --git a/tests/language_2/implicit_creation/implicit_new_or_const_generic_test.dart b/tests/language_2/implicit_creation/implicit_new_or_const_generic_test.dart
index 1f58aa5..ab9f148 100644
--- a/tests/language_2/implicit_creation/implicit_new_or_const_generic_test.dart
+++ b/tests/language_2/implicit_creation/implicit_new_or_const_generic_test.dart
@@ -72,7 +72,7 @@
   for (var i = 0; i < instances.length; i++) {
     var d = instances[i];
     Expect.equals(d42, d);
-    if (i % 5 == 2 || i % 5 == 4) {
+    if (i % 5 == 2) {
       // The cases of D(42) without "new" are all constant.
       Expect.identical(d42, d, "$i");
     } else {
diff --git a/tests/language_2/implicit_creation/implicit_new_or_const_test.dart b/tests/language_2/implicit_creation/implicit_new_or_const_test.dart
index 3a0a7b0..00c8ae3 100644
--- a/tests/language_2/implicit_creation/implicit_new_or_const_test.dart
+++ b/tests/language_2/implicit_creation/implicit_new_or_const_test.dart
@@ -43,11 +43,9 @@
   for (var i = 0; i < instances.length; i++) {
     var c = instances[i];
     Expect.equals(c42, c);
-    if (i % 5 == 2 || i % 5 == 4) {
-      // The cases of C(42) without "new" are all constant.
+    if (i % 5 == 2) {
       Expect.identical(c42, c, "$i");
     } else {
-      // The rest are not.
       Expect.notIdentical(c42, c, "$i");
     }
   }
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index 8cb9983..c746cd0 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -47,6 +47,25 @@
 [ $compiler != dart2js && $compiler != dartdevc && !$fasta && $strong ]
 type_promotion_functions_test: CompileTimeError # Issue 30895: This test requires a complete rewrite for 2.0.
 
+# Detection of compile-time errors that are related to constants can't be fully
+# done at the front end, because constants are evaluated at back ends.  So, some
+# errors aren't detected by fasta, but reported by back ends as compile-time
+# errors.
+[ $compiler != dart2js && $runtime != dart_precompiled && $runtime != vm && $fasta ]
+deferred_constraints_constants_test/default_argument2: MissingCompileTimeError
+function_type_parameter2_negative_test: Fail
+function_type_parameter_negative_test: Fail
+implicit_creation/implicit_const_not_default_values_test/e12: MissingCompileTimeError
+implicit_creation/implicit_const_not_default_values_test/e15: MissingCompileTimeError
+implicit_creation/implicit_const_not_default_values_test/e18: MissingCompileTimeError
+implicit_creation/implicit_const_not_default_values_test/e21: MissingCompileTimeError
+implicit_creation/implicit_const_not_default_values_test/e24: MissingCompileTimeError
+implicit_creation/implicit_const_not_default_values_test/e27: MissingCompileTimeError
+implicit_creation/implicit_const_not_default_values_test/e3: MissingCompileTimeError
+implicit_creation/implicit_const_not_default_values_test/e30: MissingCompileTimeError
+implicit_creation/implicit_const_not_default_values_test/e6: MissingCompileTimeError
+implicit_creation/implicit_const_not_default_values_test/e9: MissingCompileTimeError
+
 [ $compiler != dart2js && !$fasta && $strong ]
 compile_time_constant_static5_test/11: CompileTimeError # Issue 30546
 compile_time_constant_static5_test/16: CompileTimeError # Issue 30546
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index 7294e48..78aa5bd 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -13,6 +13,8 @@
 cascade_test/none: Fail # Issue 11577
 config_import_corelib_test: StaticWarning, OK
 conflicting_type_variable_and_setter_test: CompileTimeError # Issue 25525
+const_cast2_test/01: CompileTimeError
+const_cast2_test/none: CompileTimeError
 const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
 constructor_call_wrong_argument_count_negative_test: Fail # Issue 11585
 deep_nesting1_negative_test: CompileTimeError # Issue 25558
@@ -721,6 +723,7 @@
 check_member_static_test/01: MissingCompileTimeError
 check_method_override_test/01: MissingCompileTimeError
 check_method_override_test/02: MissingCompileTimeError
+const_cast1_test/02: MissingCompileTimeError
 const_constructor2_test/13: MissingCompileTimeError
 const_constructor2_test/14: MissingCompileTimeError
 const_constructor2_test/15: MissingCompileTimeError
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 9099b15..716c75e 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -249,8 +249,6 @@
 const_constructor2_test/20: MissingCompileTimeError
 const_constructor2_test/22: MissingCompileTimeError
 const_constructor2_test/24: MissingCompileTimeError
-const_constructor3_test/02: MissingCompileTimeError
-const_constructor3_test/04: MissingCompileTimeError
 const_dynamic_type_literal_test/02: MissingCompileTimeError
 const_error_multiply_initialized_test/02: MissingCompileTimeError
 const_error_multiply_initialized_test/04: MissingCompileTimeError
@@ -548,7 +546,6 @@
 covariance_field_test/03: RuntimeError
 covariance_field_test/04: RuntimeError
 covariance_field_test/05: RuntimeError
-recursive_mixin_test: RuntimeError # no check without --checked
 
 [ $compiler == dart2js && !$checked && !$enable_asserts ]
 assertion_test: RuntimeError, OK
@@ -595,7 +592,6 @@
 vm/reflect_core_vm_test: Fail # mirrors not supported
 
 [ $compiler == dart2js && $fast_startup && $fasta && $strong ]
-assertion_initializer_const_error2_test/none: CompileTimeError
 assertion_initializer_const_function_test/01: MissingCompileTimeError
 assertion_test: RuntimeError
 async_star_cancel_while_paused_test: RuntimeError
@@ -666,8 +662,6 @@
 const_constructor2_test/20: MissingCompileTimeError
 const_constructor2_test/22: MissingCompileTimeError
 const_constructor2_test/24: MissingCompileTimeError
-const_constructor3_test/02: MissingCompileTimeError
-const_constructor3_test/04: MissingCompileTimeError
 const_dynamic_type_literal_test/02: MissingCompileTimeError
 const_error_multiply_initialized_test/02: MissingCompileTimeError
 const_error_multiply_initialized_test/04: MissingCompileTimeError
@@ -1034,17 +1028,14 @@
 mixin_type_parameter_inference_test/13: CompileTimeError
 mixin_type_parameter_inference_test/16: CompileTimeError
 mixin_type_parameter_inference_test/none: CompileTimeError
-partial_tearoff_instantiation_test/02: CompileTimeError
-partial_tearoff_instantiation_test/04: CompileTimeError
 partial_tearoff_instantiation_test/05: Pass # for the wrong reason.
 partial_tearoff_instantiation_test/06: Pass # for the wrong reason.
 partial_tearoff_instantiation_test/07: Pass # for the wrong reason.
 partial_tearoff_instantiation_test/08: Pass # for the wrong reason.
-partial_tearoff_instantiation_test/none: CompileTimeError
-type_alias_equality_test/01: RuntimeError # Issue 31359
-type_alias_equality_test/02: RuntimeError # Issue 31359
-type_alias_equality_test/03: RuntimeError # Issue 31359
-type_alias_equality_test/04: RuntimeError # Issue 31359
+type_alias_equality_test/01: RuntimeError # Issue 32784
+type_alias_equality_test/02: RuntimeError # Issue 32784
+type_alias_equality_test/03: RuntimeError # Issue 32784
+type_alias_equality_test/04: RuntimeError # Issue 32784
 
 [ $compiler == dart2js && $fasta && $host_checked && $strong ]
 abstract_factory_constructor_test/00: MissingCompileTimeError
@@ -1054,8 +1045,6 @@
 abstract_syntax_test/00: MissingCompileTimeError
 additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
 additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
-assertion_initializer_const_error2_test/none: CompileTimeError
-assertion_initializer_test: CompileTimeError
 assertion_test: RuntimeError
 async_await_test/02: RuntimeError
 async_await_test/03: RuntimeError
@@ -1111,8 +1100,6 @@
 closure_invoked_through_interface_target_field_test: MissingCompileTimeError
 closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
 closure_self_reference_test: Crash # 'file:*/pkg/compiler/lib/src/ssa/nodes.dart': Failed assertion: line 641 pos 12: 'isClosed()': is not true.
-compile_time_constant_d_test: CompileTimeError
-compile_time_constant_e_test: CompileTimeError
 compile_time_constant_k_test/01: MissingCompileTimeError
 compile_time_constant_k_test/02: MissingCompileTimeError
 compile_time_constant_k_test/03: MissingCompileTimeError
@@ -1127,9 +1114,6 @@
 conditional_rewrite_test: RuntimeError
 config_import_corelib_test: CompileTimeError
 config_import_test: RuntimeError
-const_constructor2_test/11: CompileTimeError
-const_constructor2_test/12: CompileTimeError
-const_constructor3_test/03: CompileTimeError
 const_dynamic_type_literal_test/02: MissingCompileTimeError
 const_evaluation_test/01: RuntimeError
 const_instance_field_test/01: MissingCompileTimeError
@@ -1137,8 +1121,6 @@
 const_map2_test/00: MissingCompileTimeError
 const_map3_test/00: MissingCompileTimeError
 const_map4_test: RuntimeError
-const_map_test: RuntimeError
-const_redirecting_factory_test: CompileTimeError
 const_switch2_test/01: MissingCompileTimeError
 const_switch_test/02: RuntimeError, OK # constant identity based on JS constants
 const_switch_test/04: RuntimeError, OK # constant identity based on JS constants
@@ -1150,13 +1132,11 @@
 constructor_redirect1_negative_test/01: Crash # Stack Overflow
 constructor_redirect2_negative_test: Crash # Issue 30856
 constructor_redirect_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(A.named2#x), local(A.named2#y), local(A.named2#z)) for j:constructor(A.named2).
-constructor_redirect_test/none: CompileTimeError
 covariance_type_parameter_test/01: RuntimeError
 covariance_type_parameter_test/02: RuntimeError
 covariance_type_parameter_test/03: RuntimeError
 covariant_override/tear_off_type_test: RuntimeError
 covariant_subtyping_test: CompileTimeError
-ct_const_test: CompileTimeError
 cyclic_constructor_test/01: Crash # Issue 30856
 cyclic_type_test/00: RuntimeError
 cyclic_type_test/02: RuntimeError
@@ -1327,7 +1307,6 @@
 library_env_test/has_mirror_support: RuntimeError
 library_env_test/has_no_html_support: RuntimeError
 library_env_test/has_no_io_support: RuntimeError
-library_prefixes_test: CompileTimeError
 local_function2_test/none: RuntimeError
 local_function3_test/none: RuntimeError
 local_function_test/none: RuntimeError
@@ -1543,22 +1522,16 @@
 override_inheritance_no_such_method_test/13: MissingCompileTimeError
 override_method_with_field_test/01: MissingCompileTimeError
 parser_quirks_test: CompileTimeError
-partial_tearoff_instantiation_test/02: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
-partial_tearoff_instantiation_test/04: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
 partial_tearoff_instantiation_test/05: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
 partial_tearoff_instantiation_test/06: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
 partial_tearoff_instantiation_test/07: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
 partial_tearoff_instantiation_test/08: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
-partial_tearoff_instantiation_test/none: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
 prefix5_negative_test: Crash # 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart': Failed assertion: line 441 pos 16: 'identical(combiner.arguments.positional[0], rhs)': is not true.
 redirecting_factory_default_values_test/01: MissingCompileTimeError
 redirecting_factory_default_values_test/02: MissingCompileTimeError
 redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
 redirecting_factory_malbounded_test/01: MissingCompileTimeError
 redirecting_factory_reflection_test: RuntimeError
-reg_ex2_test: RuntimeError
-reg_exp2_test: RuntimeError
-reg_exp_test: RuntimeError
 regress_13462_1_test: RuntimeError
 regress_18535_test: RuntimeError
 regress_22443_test: RuntimeError
@@ -1747,8 +1720,6 @@
 abstract_syntax_test/00: MissingCompileTimeError
 additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
 additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
-assertion_initializer_const_error2_test/none: CompileTimeError
-assertion_initializer_test: CompileTimeError
 assertion_test: RuntimeError
 async_await_test/02: RuntimeError
 async_await_test/03: RuntimeError
@@ -1802,8 +1773,6 @@
 class_literal_static_test/07: MissingCompileTimeError
 closure_invoked_through_interface_target_field_test: MissingCompileTimeError
 closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
-compile_time_constant_d_test: CompileTimeError
-compile_time_constant_e_test: CompileTimeError
 compile_time_constant_k_test/01: MissingCompileTimeError
 compile_time_constant_k_test/02: MissingCompileTimeError
 compile_time_constant_k_test/03: MissingCompileTimeError
@@ -1818,9 +1787,6 @@
 conditional_rewrite_test: RuntimeError
 config_import_corelib_test: CompileTimeError
 config_import_test: RuntimeError
-const_constructor2_test/11: CompileTimeError
-const_constructor2_test/12: CompileTimeError
-const_constructor3_test/03: CompileTimeError
 const_dynamic_type_literal_test/02: MissingCompileTimeError
 const_evaluation_test/01: RuntimeError
 const_instance_field_test/01: MissingCompileTimeError
@@ -1828,8 +1794,6 @@
 const_map2_test/00: MissingCompileTimeError
 const_map3_test/00: MissingCompileTimeError
 const_map4_test: RuntimeError
-const_map_test: RuntimeError
-const_redirecting_factory_test: CompileTimeError
 const_switch2_test/01: MissingCompileTimeError
 const_switch_test/02: RuntimeError, OK # constant identity based on JS constants
 const_switch_test/04: RuntimeError, OK # constant identity based on JS constants
@@ -1841,13 +1805,11 @@
 constructor_redirect1_negative_test/01: Crash # Stack Overflow
 constructor_redirect2_negative_test: Crash # Issue 30856
 constructor_redirect_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(A.named2#x), local(A.named2#y), local(A.named2#z)) for j:constructor(A.named2).
-constructor_redirect_test/none: CompileTimeError
 covariance_type_parameter_test/01: RuntimeError
 covariance_type_parameter_test/02: RuntimeError
 covariance_type_parameter_test/03: RuntimeError
 covariant_override/tear_off_type_test: RuntimeError
 covariant_subtyping_test: CompileTimeError
-ct_const_test: CompileTimeError
 cyclic_constructor_test/01: Crash # Issue 30856
 cyclic_type_variable_test/01: MissingCompileTimeError
 cyclic_type_variable_test/02: MissingCompileTimeError
@@ -2012,7 +1974,6 @@
 library_env_test/has_mirror_support: RuntimeError
 library_env_test/has_no_html_support: RuntimeError
 library_env_test/has_no_io_support: RuntimeError
-library_prefixes_test: CompileTimeError
 local_function2_test/none: RuntimeError
 local_function3_test/none: RuntimeError
 local_function_test/none: RuntimeError
@@ -2236,9 +2197,6 @@
 redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
 redirecting_factory_malbounded_test/01: MissingCompileTimeError
 redirecting_factory_reflection_test: RuntimeError
-reg_ex2_test: RuntimeError
-reg_exp2_test: RuntimeError
-reg_exp_test: RuntimeError
 regress_13462_1_test: RuntimeError
 regress_18535_test: RuntimeError
 regress_21795_test: RuntimeError # Issue 12605
@@ -2363,8 +2321,8 @@
 wrong_number_type_arguments_test/none: Pass
 
 [ $compiler == dart2js && $fasta && $strong ]
-mixin_type_parameter5_test: RuntimeError
-mixin_type_parameter6_test: RuntimeError
+const_constructor3_test/04: MissingCompileTimeError # OK - Subtype check uses JS number semantics.
+ct_const_test: RuntimeError
 
 [ $compiler == dart2js && $fasta && !$strong ]
 *: SkipByDesign
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 823ef0b..f1d8960 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -28,6 +28,8 @@
 conflicting_generic_interfaces_hierarchy_loop_infinite_test: Skip # Crashes or times out
 conflicting_generic_interfaces_simple_test: MissingCompileTimeError
 conflicting_type_variable_and_setter_test: CompileTimeError
+const_cast2_test/01: CompileTimeError
+const_cast2_test/none: CompileTimeError
 const_evaluation_test/01: RuntimeError # Issue 29920
 const_for_in_variable_test/01: MissingCompileTimeError
 const_types_test/07: MissingCompileTimeError
@@ -68,8 +70,6 @@
 implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError
 implicit_creation/implicit_const_context_prefix_constructor_generic_named_test: CompileTimeError
 implicit_creation/implicit_const_context_prefix_constructor_generic_test: CompileTimeError
-implicit_creation/implicit_new_or_const_composite_test: RuntimeError
-implicit_creation/implicit_new_or_const_generic_test: RuntimeError
 implicit_downcast_during_compound_assignment_test: RuntimeError
 implicit_downcast_during_indexed_compound_assignment_test: RuntimeError
 implicit_downcast_during_indexed_if_null_assignment_test: RuntimeError
@@ -181,10 +181,10 @@
 truncdiv_test: RuntimeError # Issue 29920
 try_catch_on_syntax_test/10: MissingCompileTimeError
 try_catch_on_syntax_test/11: MissingCompileTimeError
-type_alias_equality_test/01: RuntimeError # Issue 31359
-type_alias_equality_test/02: RuntimeError # Issue 31359
-type_alias_equality_test/03: RuntimeError # Issue 31359
-type_alias_equality_test/04: RuntimeError # Issue 31359
+type_alias_equality_test/01: RuntimeError # Issue 32785
+type_alias_equality_test/02: RuntimeError # Issue 32785
+type_alias_equality_test/03: RuntimeError # Issue 32785
+type_alias_equality_test/04: RuntimeError # Issue 32785
 type_inference_circularity_test: MissingCompileTimeError
 type_inference_inconsistent_inheritance_test: MissingCompileTimeError
 type_promotion_functions_test/02: CompileTimeError # Issue 30895
@@ -343,6 +343,7 @@
 conditional_import_string_test: CompileTimeError # Test is broken
 conditional_import_test: CompileTimeError # Test is broken
 config_import_test: CompileTimeError
+const_cast1_test/02: MissingCompileTimeError
 const_constructor3_test/04: MissingCompileTimeError
 const_constructor_nonconst_field_test/01: MissingCompileTimeError
 const_dynamic_type_literal_test/02: MissingCompileTimeError
@@ -401,6 +402,8 @@
 function_call_generic_test: RuntimeError # Issue 32756. Crashes on dsend
 function_propagation_test: RuntimeError
 function_subtype_closure0_test: RuntimeError # Expect.throws(TypeError) fails: Did not throw
+function_type_parameter2_negative_test: Fail
+function_type_parameter_negative_test: Fail
 generic_function_bounds_test: RuntimeError
 generic_methods_generic_function_result_test/01: MissingCompileTimeError
 generic_methods_recursive_bound_test/02: MissingCompileTimeError
@@ -655,7 +658,7 @@
 syntax_test/33: MissingCompileTimeError
 tearoff_dynamic_test: RuntimeError # Issue 32194
 try_catch_test/01: MissingCompileTimeError
-type_alias_equality_test/02: RuntimeError # Issue 31359
+type_alias_equality_test/02: RuntimeError # Issue 32785
 type_literal_test: RuntimeError # Expect.equals(expected: <Func>, actual: <(bool) => int>) fails.
 type_promotion_functions_test/02: CompileTimeError # Issue 31537
 type_promotion_functions_test/03: CompileTimeError # Issue 31537
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index e5a5738..73d5031 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -29,6 +29,7 @@
 assertion_initializer_const_error2_test/cc08: MissingCompileTimeError
 assertion_initializer_const_error2_test/cc09: MissingCompileTimeError
 assertion_initializer_const_error2_test/cc10: MissingCompileTimeError
+const_cast1_test/02: MissingCompileTimeError
 generic_test/01: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e1: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e10: MissingCompileTimeError
@@ -74,6 +75,8 @@
 closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
 compile_time_constant_o_test/01: MissingCompileTimeError
 compile_time_constant_o_test/02: MissingCompileTimeError
+const_cast2_test/01: CompileTimeError
+const_cast2_test/none: CompileTimeError
 const_dynamic_type_literal_test/02: MissingCompileTimeError
 const_instance_field_test/01: MissingCompileTimeError # Fasta bug: Const instance field. Issue 32326.
 const_map2_test/00: MissingCompileTimeError # KernelVM bug: Constant evaluation.
@@ -112,11 +115,6 @@
 identical_const_test/02: MissingCompileTimeError
 identical_const_test/03: MissingCompileTimeError
 identical_const_test/04: MissingCompileTimeError
-implicit_creation/implicit_const_context_constructor_generic_named_test: CompileTimeError
-implicit_creation/implicit_const_context_prefix_constructor_generic_named_test: CompileTimeError
-implicit_creation/implicit_new_constructor_generic_named_test: CompileTimeError
-implicit_creation/implicit_new_or_const_generic_test: CompileTimeError
-implicit_creation/implicit_new_prefix_constructor_generic_named_test: CompileTimeError
 implicit_this_test/01: MissingCompileTimeError
 implicit_this_test/04: MissingCompileTimeError
 issue31596_override_test/07: MissingCompileTimeError
@@ -664,7 +662,6 @@
 generic_tearoff_test: CompileTimeError
 generic_tearoff_test: RuntimeError
 if_null_evaluation_order_test: Pass
-implicit_creation/implicit_new_constructor_generic_test: Pass
 initializing_formal_type_annotation_test/01: MissingCompileTimeError
 initializing_formal_type_annotation_test/02: MissingCompileTimeError
 instantiate_tearoff_of_call_test: CompileTimeError
@@ -777,7 +774,6 @@
 assertion_initializer_const_error2_test/cc11: MissingCompileTimeError # Not reporting failed assert() at compile time.
 redirecting_factory_reflection_test: RuntimeError
 
-
 # Enabling of dartk for sim{arm,arm64,dbc64} revelaed these test failures, which
 # are to be triaged.  Isolate tests are skipped on purpose due to the usage of
 # batch mode.
@@ -1008,7 +1004,6 @@
 getter_override_test/02: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
 hello_dart_test: Skip # Incompatible flag: --compile_all
 implicit_closure_test: Skip # Incompatible flag: --use_slow_path
-implicit_creation/implicit_new_constructor_generic_test: Pass
 implicit_downcast_during_assignment_test: Pass # Correctly passes.
 implicit_downcast_during_combiner_test: Pass # Correctly passes.
 implicit_downcast_during_compound_assignment_test: Pass # Correctly passes.
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index a41c57f..cfbf354 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -1341,10 +1341,10 @@
 nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError
 nsm5_test: MissingCompileTimeError
 override_inheritance_no_such_method_test/05: MissingCompileTimeError
-type_alias_equality_test/01: RuntimeError # Issue 31359
-type_alias_equality_test/02: RuntimeError # Issue 31359
-type_alias_equality_test/03: RuntimeError # Issue 31359
-type_alias_equality_test/04: RuntimeError # Issue 31359
+type_alias_equality_test/01: RuntimeError # Issue 32783
+type_alias_equality_test/02: RuntimeError # Issue 32783
+type_alias_equality_test/03: RuntimeError # Issue 32783
+type_alias_equality_test/04: RuntimeError # Issue 32783
 
 [ $compiler == none && $runtime == vm && !$checked ]
 assertion_initializer_const_error_test/01: MissingCompileTimeError
@@ -1353,6 +1353,9 @@
 generic_methods_dynamic_test/04: MissingRuntimeError
 type_parameter_test/05: MissingCompileTimeError
 
+[ ($compiler == app_jit || $compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
+const_cast2_test/01: CompileTimeError
+
 [ $compiler != dartk && $runtime == vm || $compiler != dartkp && $runtime == dart_precompiled ]
 built_in_identifier_type_annotation_test/22: MissingCompileTimeError # Error only in strong mode
 int64_literal_test/*: Skip # This is testing Dart 2.0 int64 semantics.
diff --git a/tests/language_2/operator2_test.dart b/tests/language_2/operator2_test.dart
index 99c770b..17f1fd8f 100644
--- a/tests/language_2/operator2_test.dart
+++ b/tests/language_2/operator2_test.dart
@@ -17,15 +17,38 @@
   }
 }
 
-class OperatorTest {
-  static testMain() {
-    Helper obj = new Helper(10);
-    Expect.equals(10, obj.i);
-    obj[10] = 20;
-    Expect.equals(30, obj[10]);
+main() {
+  Helper obj = new Helper(10);
+  Expect.equals(10, obj.i);
+  obj[10] = 20;
+  Expect.equals(30, obj[10]);
+
+  regress32754();
+}
+
+// Regression test for https://github.com/dart-lang/sdk/issues/32754
+class C {
+  operator []=(i, value) {
+    value = 'OOPS';
   }
 }
 
-main() {
-  OperatorTest.testMain();
+class C2 {
+  int data;
+  operator []=(i, value) {
+    // The return expression must be evaluated, then ignored.
+    return () {
+      data = i + value;
+      return null;
+    }();
+  }
+}
+
+regress32754() {
+  var c = new C();
+  Expect.equals('ok', c[0] = 'ok');
+
+  var c2 = new C2();
+  Expect.equals(23, c2[100] = 23);
+  Expect.equals(123, c2.data);
 }
diff --git a/tests/lib_2/async/null_future_zone_test.dart b/tests/lib_2/async/null_future_zone_test.dart
new file mode 100644
index 0000000..802c399
--- /dev/null
+++ b/tests/lib_2/async/null_future_zone_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2013, 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:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import 'dart:async';
+
+main() {
+  asyncStart(2);
+  () async {
+    var it = new StreamIterator(new Stream.fromIterable([]));
+    Expect.isFalse(await it.moveNext());
+
+    Future nullFuture;
+    Future falseFuture;
+
+    runZoned(() {
+      nullFuture = (new StreamController()..stream.listen(null).cancel()).done;
+      falseFuture = it.moveNext();
+    }, zoneSpecification: new ZoneSpecification(scheduleMicrotask:
+        (Zone self, ZoneDelegate parent, Zone zone, void f()) {
+      Expect.fail("Should not be called");
+    }));
+
+    nullFuture.then((value) {
+      Expect.isNull(value);
+      asyncEnd();
+    });
+
+    falseFuture.then((value) {
+      Expect.isFalse(value);
+      asyncEnd();
+    });
+  }();
+}
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index d3e9fe3..b8926562 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -89,7 +89,6 @@
 html/element_classes_svg_test: RuntimeError # Issue 29922
 html/element_classes_test: RuntimeError # Issue 29922
 html/fontface_loaded_test: RuntimeError
-html/gamepad_test: RuntimeError # Issue 31029
 html/interactive_media_test: Skip # requests interactive permissions (camera, geolocation)
 html/isolates_test: RuntimeError # Issue 29922
 html/js_typed_interop_default_arg_test/default_value: MissingCompileTimeError # Issue 29922
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index 50ce4be..3ee3c80 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -22,7 +22,7 @@
 package/scenarios/invalid/non_existent_packages_file_test: CompileTimeError # Issue 32085
 
 [ $builder_tag == optimization_counter_threshold && $compiler == dartk ]
-map_insert_remove_oom_test: Pass, Crash # Flaky on vm-kernel-optcounter-threshold-linux-release-x64, bug #31838
+map_insert_remove_oom_test: Pass, Crash, Timeout # Flaky on vm-kernel-optcounter-threshold-linux-release-x64, bug #31838. Sometimes times out, see issue 32786.
 
 [ $compiler == dartk && $mode == debug && $runtime == vm && $strong ]
 io/file_lock_test: Slow, Pass
diff --git a/tools/VERSION b/tools/VERSION
index 1d9868f..5eab473 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 0
 PATCH 0
-PRERELEASE 46
+PRERELEASE 47
 PRERELEASE_PATCH 0
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 6e7b905..cde90fb 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -400,6 +400,7 @@
   'MediaKeys.createSession',
   'MediaKeySession.update',
   'MessageEvent.initMessageEvent',
+  'MessagePort.start',
   'MouseEvent.initMouseEvent',
   'MouseEvent.clientX',
   'MouseEvent.clientY',
@@ -410,6 +411,7 @@
   'MouseEvent.screenX',
   'MouseEvent.screenY',
   'MutationObserver.observe',
+  'Navigator.getGamepads',
   'Node.attributes',
   'Node.localName',
   'Node.namespaceURI',
diff --git a/tools/dom/src/dart2js_CustomElementSupport.dart b/tools/dom/src/dart2js_CustomElementSupport.dart
index 7869ea3..983ba1a 100644
--- a/tools/dom/src/dart2js_CustomElementSupport.dart
+++ b/tools/dom/src/dart2js_CustomElementSupport.dart
@@ -147,7 +147,8 @@
     JS('=Object', '#.extends = #', opts, extendsTagName);
   }
 
-  return JS('=Object', '#.registerElement(#, #)', document, tag, opts);
+  return JS(
+      'JavaScriptFunction', '#.registerElement(#, #)', document, tag, opts);
 }
 
 //// Called by Element.created to do validation & initialization.
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index b6959e6..2baac67 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -58,7 +58,7 @@
     findDispatchTagForInterceptorClass, setNativeSubclassDispatchRecord,
     makeLeafDispatchRecord, registerGlobalObject, applyExtension;
 import 'dart:_interceptors' show
-    Interceptor, JSExtendableArray, JSUInt31,
+    Interceptor, JavaScriptFunction, JSExtendableArray, JSUInt31,
     findInterceptorConstructorForType,
     findConstructorForNativeSubclassType,
     getNativeInterceptor,
diff --git a/tools/dom/templates/html/impl/impl_MessagePort.darttemplate b/tools/dom/templates/html/impl/impl_MessagePort.darttemplate
index 824012e..0dbf89b 100644
--- a/tools/dom/templates/html/impl/impl_MessagePort.darttemplate
+++ b/tools/dom/templates/html/impl/impl_MessagePort.darttemplate
@@ -13,7 +13,7 @@
     // Messages posted to ports are initially paused, allowing listeners to be
     // setup, start() needs to be explicitly invoked to begin handling messages.
     if (type == 'message') {
-      start();
+      _start();
     }
 
     super.addEventListener(type, listener, useCapture);
diff --git a/tools/dom/templates/html/impl/impl_Navigator.darttemplate b/tools/dom/templates/html/impl/impl_Navigator.darttemplate
index 079fa93..022e9e3 100644
--- a/tools/dom/templates/html/impl/impl_Navigator.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Navigator.darttemplate
@@ -6,6 +6,20 @@
 
 $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
 
+  @DomName('Navigator.getGamepads')
+  List<Gamepad> getGamepads() {
+    var gamepadList = _getGamepads();
+
+    // If no prototype we need one for the world to hookup to the proper Dart class.
+    var jsProto = JS('', '#.prototype', gamepadList);
+    if (jsProto == null) {
+      JS('', '#.prototype = Object.create(null)', gamepadList);
+    }
+
+    applyExtension('GamepadList', gamepadList);
+    return gamepadList;
+  }
+
   @DomName('Navigator.language')
   String get language => JS('String', '#.language || #.userLanguage', this,
       this);
diff --git a/tools/sdks/linux/dart-sdk.tar.gz.sha1 b/tools/sdks/linux/dart-sdk.tar.gz.sha1
index fcfff24..b8078c6 100644
--- a/tools/sdks/linux/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/linux/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-e1d5dbecbca504ffa66db767045aeb3714a2a696
\ No newline at end of file
+d603d2f9fe59281e37a250cb3105ab54d1c25e64
\ No newline at end of file
diff --git a/tools/sdks/mac/dart-sdk.tar.gz.sha1 b/tools/sdks/mac/dart-sdk.tar.gz.sha1
index 9921e91..e7dd518 100644
--- a/tools/sdks/mac/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/mac/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-3e694dc99bb13d9b094401c6424764459109676e
\ No newline at end of file
+7b5adc71c75dc07815ccd8f233c4ccf50d11e11f
\ No newline at end of file
diff --git a/tools/sdks/win/dart-sdk.tar.gz.sha1 b/tools/sdks/win/dart-sdk.tar.gz.sha1
index 81e6c51..5ade4b8 100644
--- a/tools/sdks/win/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/win/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-8ea5e44f520f93a65f05f36f1d7886d04650d29a
\ No newline at end of file
+520e55c06f22a50938c1682e6e0a56161fc43a65
\ No newline at end of file
diff --git a/utils/bazel/kernel_summary_worker.dart b/utils/bazel/kernel_summary_worker.dart
index 461e390..c572e88 100644
--- a/utils/bazel/kernel_summary_worker.dart
+++ b/utils/bazel/kernel_summary_worker.dart
@@ -131,11 +131,12 @@
           new TargetFlags(strongMode: true)),
       fileSystem);
 
-  void onProblem(problem, severity, String formatted, line, column) {
-    if (outputBuffer != null) {
-      outputBuffer.writeln(formatted);
-    } else {
-      stderr.writeln(formatted);
+  void onProblem(fe.FormattedMessage message, severity,
+      List<fe.FormattedMessage> context) {
+    dynamic out = outputBuffer ?? stderr;
+    out.println(message.formatted);
+    for (fe.FormattedMessage message in context) {
+      out.println(message.formatted);
     }
     if (severity != fe.Severity.nit) {
       succeeded = false;