Version 2.14.0-264.0.dev

Merge commit '43311ae7ec64dcc05c23043da9ff8b8e963c50c5' into 'dev'
diff --git a/DEPS b/DEPS
index e7492f9..97f5438 100644
--- a/DEPS
+++ b/DEPS
@@ -164,7 +164,7 @@
   "test_process_tag": "2.0.0",
   "term_glyph_rev": "6a0f9b6fb645ba75e7a00a4e20072678327a0347",
   "test_reflective_loader_rev": "54e930a11c372683792e22bddad79197728c91ce",
-  "test_rev": "eb1155c999b298e641c22b7fea42c8f6c4bcb00b",
+  "test_rev": "030816c32b6fe78d5fb7653afbd9f63cca18bacf",
   "typed_data_tag": "f94fc57b8e8c0e4fe4ff6cfd8290b94af52d3719",
   "usage_rev": "e0780cd8b2f8af69a28dc52678ffe8492da27d06",
   "vector_math_rev": "0c9f5d68c047813a6dcdeb88ba7a42daddf25025",
diff --git a/benchmarks/ObjectHash/dart/ObjectHash.dart b/benchmarks/ObjectHash/dart/ObjectHash.dart
new file mode 100644
index 0000000..67ad018
--- /dev/null
+++ b/benchmarks/ObjectHash/dart/ObjectHash.dart
@@ -0,0 +1,253 @@
+// Copyright (c) 2021, 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.
+
+// ignore_for_file: hash_and_equals
+
+// Benchmark for `Object.hash` and `Object.hashAll`.
+
+import 'dart:math';
+import 'package:benchmark_harness/benchmark_harness.dart';
+
+int get nextHash => Random().nextInt(0x20000000);
+
+// An object with a fast hashCode.
+class Leaf {
+  @override
+  final int hashCode = nextHash;
+}
+
+abstract class Node5 {
+  final item1 = Leaf();
+  final item2 = Leaf();
+  final item3 = Leaf();
+  final item4 = Random().nextBool();
+  final item5 = nextHash;
+}
+
+class Node5Hash extends Node5 {
+  // This is the main subject of the benchmark - a typical use of `Object.hash`.
+  @override
+  int get hashCode => Object.hash(item1, item2, item3, item4, item5);
+}
+
+class Node5Manual extends Node5 {
+  // This is a similar quality hashCode but with statically resolvable
+  // `hashCode` calls.
+  @override
+  int get hashCode => _SystemHash.hash5(item1.hashCode, item2.hashCode,
+      item3.hashCode, item4.hashCode, item5.hashCode);
+}
+
+class Node5List extends Node5 {
+  // This is a pattern that is sometimes used, especially for large numbers of
+  // items.
+  @override
+  int get hashCode => Object.hashAll([item1, item2, item3, item4, item5]);
+}
+
+/// Returns a list with most values created by [makeValue], and a few objects of
+/// different types so that the `hashCode` calls are polymorphic, like the ones
+/// in the hashed collections.
+List generateData(Object Function(int) makeValue) {
+  final List data = List.generate(1000, makeValue);
+  final exceptions = [
+    Leaf(),
+    Node5Hash(),
+    Node5Manual(),
+    Node5List(),
+    '',
+    true,
+    false,
+    123,
+    Object()
+  ];
+  data.setRange(1, 1 + exceptions.length, exceptions);
+  return data;
+}
+
+class BenchmarkNode5Hash extends BenchmarkBase {
+  final List data = generateData((_) => Node5Hash());
+
+  BenchmarkNode5Hash() : super('ObjectHash.hash.5');
+
+  @override
+  void run() {
+    for (final e in data) {
+      sink = e.hashCode;
+    }
+  }
+}
+
+class BenchmarkNode5Manual extends BenchmarkBase {
+  final List data = generateData((_) => Node5Manual());
+
+  BenchmarkNode5Manual() : super('ObjectHash.manual.5');
+
+  @override
+  void run() {
+    for (final e in data) {
+      sink = e.hashCode;
+    }
+  }
+}
+
+class BenchmarkNode5List extends BenchmarkBase {
+  final List data = generateData((_) => Node5List());
+
+  BenchmarkNode5List() : super('ObjectHash.list.5');
+
+  @override
+  void run() {
+    for (final e in data) {
+      sink = e.hashCode;
+    }
+  }
+}
+
+class BenchmarkNode5HashHashAll extends BenchmarkBase {
+  final List data = generateData((_) => Node5Hash());
+
+  BenchmarkNode5HashHashAll() : super('ObjectHash.hash.5.hashAll');
+
+  @override
+  void run() {
+    sink = Object.hashAll(data);
+  }
+}
+
+class BenchmarkNode5ManualHashAll extends BenchmarkBase {
+  final List data = generateData((_) => Node5Manual());
+
+  BenchmarkNode5ManualHashAll() : super('ObjectHash.manual.5.hashAll');
+
+  @override
+  void run() {
+    sink = Object.hashAll(data);
+  }
+}
+
+Object? sink;
+
+void main() {
+  generalUses();
+
+  final benchmarks = [
+    () => BenchmarkNode5Hash(),
+    () => BenchmarkNode5Manual(),
+    () => BenchmarkNode5List(),
+    () => BenchmarkNode5HashHashAll(),
+    () => BenchmarkNode5ManualHashAll(),
+  ];
+
+  // Warmup all benchmarks so that JIT compilers see full polymorphism before
+  // measuring.
+  for (var benchmark in benchmarks) {
+    benchmark().warmup();
+  }
+
+  if (sink == null) throw StateError('sink unassigned');
+
+  generalUses();
+
+  for (var benchmark in benchmarks) {
+    benchmark().report();
+  }
+}
+
+/// Does a variety of calls to `Object.hash` to ensure the compiler does not
+/// over-specialize the code on a few benchmark inputs.
+void generalUses() {
+  void check(int a, int b) {
+    if (a != b) throw StateError('inconsistent');
+  }
+
+  // Exercise arity dispatch.
+  check(Object.hash(1, 2), Object.hash(1, 2));
+  check(Object.hash(1, 2, 3), Object.hash(1, 2, 3));
+  check(Object.hash(1, 2, 3, 4), Object.hash(1, 2, 3, 4));
+  check(Object.hash(1, 2, 3, 4, 5), Object.hash(1, 2, 3, 4, 5));
+  check(Object.hash(1, 2, 3, 4, 5, 6), Object.hash(1, 2, 3, 4, 5, 6));
+  check(Object.hash(1, 2, 3, 4, 5, 6, 7), Object.hash(1, 2, 3, 4, 5, 6, 7));
+
+  final xs = Iterable.generate(20).toList();
+  check(Function.apply(Object.hash, xs), Function.apply(Object.hash, xs));
+
+  // Exercise internal hashCode dispatch.
+  final a1 = 123;
+  final a2 = 'hello';
+  final a3 = true;
+  final a4 = Object();
+  final a5 = StringBuffer();
+  const a6 = Point<int>(1, 2);
+  const a7 = Rectangle<int>(100, 200, 1, 1);
+
+  check(Object.hash(a1, a2, a3, a4, a5), Object.hash(a1, a2, a3, a4, a5));
+  check(Object.hash(a2, a3, a4, a5, a6), Object.hash(a2, a3, a4, a5, a6));
+  check(Object.hash(a3, a4, a5, a6, a7), Object.hash(a3, a4, a5, a6, a7));
+  check(Object.hash(a4, a5, a6, a7, a1), Object.hash(a4, a5, a6, a7, a1));
+  check(Object.hash(a5, a6, a7, a1, a2), Object.hash(a5, a6, a7, a1, a2));
+  check(Object.hash(a6, a7, a1, a2, a3), Object.hash(a6, a7, a1, a2, a3));
+  check(Object.hash(a7, a1, a2, a3, a4), Object.hash(a7, a1, a2, a3, a4));
+
+  check(_SystemHash.hash2(1, 2), _SystemHash.hash2(1, 2));
+  check(_SystemHash.hash3(1, 2, 3), _SystemHash.hash3(1, 2, 3));
+  check(_SystemHash.hash4(1, 2, 3, 4), _SystemHash.hash4(1, 2, 3, 4));
+  check(_SystemHash.hash5(1, 2, 3, 4, 5), _SystemHash.hash5(1, 2, 3, 4, 5));
+
+  // Pollute hashAll argument type.
+  check(Object.hashAll({}), Object.hashAll([]));
+  check(Object.hashAll({}.values), Object.hashAll({}.keys));
+  check(Object.hashAll(''.codeUnits), Object.hashAll(const Iterable.empty()));
+  check(Object.hashAll(const [0]), Object.hashAll(Iterable.generate(1)));
+}
+
+// Partial copy of dart:internal `SystemHash` that is used by `Object.hash` so
+// that we can create comparable manual hashCode methods.
+class _SystemHash {
+  static int combine(int hash, int value) {
+    hash = 0x1fffffff & (hash + value);
+    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+    return hash ^ (hash >> 6);
+  }
+
+  static int finish(int hash) {
+    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+    hash = hash ^ (hash >> 11);
+    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+  }
+
+  static int hash2(int v1, int v2, [int seed = 0]) {
+    int hash = seed;
+    hash = combine(hash, v1);
+    hash = combine(hash, v2);
+    return finish(hash);
+  }
+
+  static int hash3(int v1, int v2, int v3, [int seed = 0]) {
+    int hash = seed;
+    hash = combine(hash, v1);
+    hash = combine(hash, v2);
+    hash = combine(hash, v3);
+    return finish(hash);
+  }
+
+  static int hash4(int v1, int v2, int v3, int v4, [int seed = 0]) {
+    int hash = seed;
+    hash = combine(hash, v1);
+    hash = combine(hash, v2);
+    hash = combine(hash, v3);
+    hash = combine(hash, v4);
+    return finish(hash);
+  }
+
+  static int hash5(int v1, int v2, int v3, int v4, int v5, [int seed = 0]) {
+    int hash = seed;
+    hash = combine(hash, v1);
+    hash = combine(hash, v2);
+    hash = combine(hash, v3);
+    hash = combine(hash, v4);
+    hash = combine(hash, v5);
+    return finish(hash);
+  }
+}
diff --git a/benchmarks/ObjectHash/dart2/ObjectHash.dart b/benchmarks/ObjectHash/dart2/ObjectHash.dart
new file mode 100644
index 0000000..49ac7ae
--- /dev/null
+++ b/benchmarks/ObjectHash/dart2/ObjectHash.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2021, 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.
+
+// @dart=2.9
+
+import '../dart/ObjectHash.dart' as benchmark;
+
+void main() {
+  benchmark.main();
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 7365ef4..a7160e1 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -82,7 +82,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 159;
+  static const int DATA_VERSION = 160;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index df060fa..26339f7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -150,6 +150,7 @@
                 partDirectiveIndex: partIndex - 1,
                 partUriStr: partUriStr,
                 source: file.source,
+                sourceContent: file.content,
                 isSynthetic: isSynthetic,
                 unit: unit,
               ),
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 07cfa16..a6a03a6 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -926,6 +926,10 @@
   @override
   late Source source;
 
+  /// The content of the [source] for which this element model was built.
+  /// Might be `null` if we don't have it (for example in google3 summaries).
+  String? sourceContent;
+
   @override
   LineInfo? lineInfo;
 
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index 611c2c0..570ef8f 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -50,7 +50,7 @@
 
   /// Creates an [ElementWalker] which walks the child elements of a compilation
   /// unit element.
-  ElementWalker.forCompilationUnit(CompilationUnitElement element,
+  ElementWalker.forCompilationUnit(CompilationUnitElementImpl element,
       {this.libraryFilePath, this.unitFilePath})
       : element = element,
         _accessors = element.accessors.where(_isNotSynthetic).toList(),
@@ -107,6 +107,16 @@
             (element.aliasedElement as GenericFunctionTypeElement).parameters,
         _typeParameters = element.typeParameters;
 
+  String? get _unitSourceContent {
+    Element? element = this.element;
+    while (element != null) {
+      if (element is CompilationUnitElementImpl) {
+        return element.sourceContent;
+      }
+      element = element.enclosingElement;
+    }
+  }
+
   void consumeLocalElements() {
     _functionIndex = _functions!.length;
   }
@@ -117,8 +127,23 @@
 
   /// Returns the next non-synthetic child of [element] which is an accessor;
   /// throws an [IndexError] if there are no more.
-  PropertyAccessorElementImpl getAccessor() =>
-      _accessors![_accessorIndex++] as PropertyAccessorElementImpl;
+  PropertyAccessorElementImpl getAccessor() {
+    // TODO(scheglov) Remove after fixing.
+    // https://github.com/dart-lang/sdk/issues/46392
+    var accessors = _accessors;
+    if (accessors != null && _accessorIndex >= accessors.length) {
+      throw StateError(
+        '[_accessorIndex: $_accessorIndex]'
+        '[_accessors.length: ${accessors.length}]'
+        '[accessors: $accessors]'
+        '[element.source: ${element.source?.fullName}]'
+        '[libraryFilePath: $libraryFilePath]'
+        '[unitFilePath: $unitFilePath]'
+        '[unitSourceContent: $_unitSourceContent]',
+      );
+    }
+    return _accessors![_accessorIndex++] as PropertyAccessorElementImpl;
+  }
 
   /// Returns the next non-synthetic child of [element] which is a class; throws
   /// an [IndexError] if there are no more.
@@ -133,7 +158,8 @@
         '[classes: $classes]'
         '[element.source: ${element.source?.fullName}]'
         '[libraryFilePath: $libraryFilePath]'
-        '[unitFilePath: $unitFilePath]',
+        '[unitFilePath: $unitFilePath]'
+        '[unitSourceContent: $_unitSourceContent]',
       );
     }
     return _classes![_classIndex++] as ClassElementImpl;
@@ -178,8 +204,23 @@
   /// Returns the next non-synthetic child of [element] which is a top level
   /// variable, field, or local variable; throws an [IndexError] if there are no
   /// more.
-  VariableElementImpl getVariable() =>
-      _variables![_variableIndex++] as VariableElementImpl;
+  VariableElementImpl getVariable() {
+    // TODO(scheglov) Remove after fixing.
+    // https://github.com/dart-lang/sdk/issues/46392
+    var variables = _variables;
+    if (variables != null && _variableIndex >= variables.length) {
+      throw StateError(
+        '[_variableIndex: $_variableIndex]'
+        '[_variables.length: ${variables.length}]'
+        '[variables: $variables]'
+        '[element.source: ${element.source?.fullName}]'
+        '[libraryFilePath: $libraryFilePath]'
+        '[unitFilePath: $unitFilePath]'
+        '[unitSourceContent: $_unitSourceContent]',
+      );
+    }
+    return _variables![_variableIndex++] as VariableElementImpl;
+  }
 
   /// Verifies that all non-synthetic children of [element] have been obtained
   /// from their corresponding "get" method calls; if not, throws a
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index ab5c7de..b21dfaa 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -1208,6 +1208,7 @@
 
     unitElement.uri = _reader.readOptionalStringReference();
     unitElement.isSynthetic = _reader.readBool();
+    unitElement.sourceContent = _reader.readOptionalStringUtf8();
 
     _readClasses(unitElement, unitReference);
     _readEnums(unitElement, unitReference);
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 78d6953..9b3bb27 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -434,11 +434,13 @@
   }
 
   void _writeUnitElement(CompilationUnitElement unitElement) {
+    unitElement as CompilationUnitElementImpl;
     _sink.writeUInt30(_resolutionSink.offset);
 
     _sink._writeStringReference('${unitElement.source.uri}');
     _sink._writeOptionalStringReference(unitElement.uri);
     _sink.writeBool(unitElement.isSynthetic);
+    _sink.writeOptionalStringUtf8(unitElement.sourceContent);
     _resolutionSink._writeAnnotationList(unitElement.metadata);
     _writeList(unitElement.classes, _writeClassElement);
     _writeList(unitElement.enums, _writeEnumElement);
diff --git a/pkg/analyzer/lib/src/summary2/data_reader.dart b/pkg/analyzer/lib/src/summary2/data_reader.dart
index 787029e..a961d0d 100644
--- a/pkg/analyzer/lib/src/summary2/data_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/data_reader.dart
@@ -60,6 +60,12 @@
     }
   }
 
+  String? readOptionalStringUtf8() {
+    if (readBool()) {
+      return readStringUtf8();
+    }
+  }
+
   int? readOptionalUInt30() {
     if (readBool()) {
       return readUInt30();
diff --git a/pkg/analyzer/lib/src/summary2/data_writer.dart b/pkg/analyzer/lib/src/summary2/data_writer.dart
index 18fdf73..d7aedcd 100644
--- a/pkg/analyzer/lib/src/summary2/data_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/data_writer.dart
@@ -137,6 +137,15 @@
     }
   }
 
+  void writeOptionalStringUtf8(String? value) {
+    if (value != null) {
+      writeBool(true);
+      writeStringUtf8(value);
+    } else {
+      writeBool(false);
+    }
+  }
+
   void writeOptionalUInt30(int? value) {
     if (value != null) {
       writeBool(true);
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 9d3fa60..396b8f7 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -81,14 +81,17 @@
     _libraryElement.imports = _imports;
     _libraryElement.hasExtUri = _hasExtUri;
 
-    var firstDirective = unit.directives.firstOrNull;
-    if (firstDirective != null) {
-      _libraryElement.documentationComment = getCommentNodeRawText(
-        firstDirective.documentationComment,
-      );
-      var firstDirectiveMetadata = firstDirective.element?.metadata;
-      if (firstDirectiveMetadata != null) {
-        _libraryElement.metadata = firstDirectiveMetadata;
+    if (_isFirstLibraryDirective) {
+      _isFirstLibraryDirective = false;
+      var firstDirective = unit.directives.firstOrNull;
+      if (firstDirective != null) {
+        _libraryElement.documentationComment = getCommentNodeRawText(
+          firstDirective.documentationComment,
+        );
+        var firstDirectiveMetadata = firstDirective.element?.metadata;
+        if (firstDirectiveMetadata != null) {
+          _libraryElement.metadata = firstDirectiveMetadata;
+        }
       }
     }
   }
@@ -626,6 +629,9 @@
     if (_isFirstLibraryDirective) {
       _isFirstLibraryDirective = false;
       node.element = _libraryElement;
+      _libraryElement.documentationComment = getCommentNodeRawText(
+        node.documentationComment,
+      );
       _libraryElement.metadata = _buildAnnotations(node.metadata);
     }
   }
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index d3531b7..a36ee5c 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -251,6 +251,7 @@
       unitElement.librarySource = inputLibrary.source;
       unitElement.lineInfo = unitNode.lineInfo;
       unitElement.source = inputUnit.source;
+      unitElement.sourceContent = inputUnit.sourceContent;
       unitElement.uri = inputUnit.partUriStr;
       unitElement.setCodeRange(0, unitNode.length);
 
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 5156b61..4cc4a03 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -252,6 +252,7 @@
   final int? partDirectiveIndex;
   final String? partUriStr;
   final Source source;
+  final String? sourceContent;
   final bool isSynthetic;
   final ast.CompilationUnit unit;
 
@@ -259,6 +260,7 @@
     required this.partDirectiveIndex,
     this.partUriStr,
     required this.source,
+    this.sourceContent,
     required this.isSynthetic,
     required this.unit,
   });
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index 19b6f2b..54794d7 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -368,6 +368,14 @@
 ''');
   }
 
+  test_libraryAfterImport() async {
+    await _assertCanBeAnalyzed(r'''
+import 'dart:async';
+@foo
+library my;
+''');
+  }
+
   test_localFunction_defaultFieldFormalParameter_metadata() async {
     await _assertCanBeAnalyzed(r'''
 const my = 0;
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 33cc919..771756b 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -138,6 +138,9 @@
 
   static const String cfeInvocationModes = '--cfe-invocation-modes';
 
+  /// Flag to stop after splitting the program.
+  static const String stopAfterProgramSplit = '--stop-after-program-split';
+
   // The syntax-only level of support for generic methods is included in the
   // 1.50 milestone for Dart. It is not experimental, but also not permanent:
   // a full implementation is expected in the future. Hence, the
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 8f52c10..9d3ca36 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -481,7 +481,7 @@
         serializationTask.serializeClosedWorld(closedWorld);
         return;
       }
-      if (stopAfterClosedWorld) return;
+      if (stopAfterClosedWorld || options.stopAfterProgramSplit) return;
       GlobalTypeInferenceResults globalInferenceResults =
           performGlobalTypeInference(closedWorld);
       if (options.writeDataUri != null) {
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index bdbd352..f62a0c8 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -546,6 +546,7 @@
     new OptionHandler(Flags.serverMode, passThrough),
     new OptionHandler(Flags.disableInlining, passThrough),
     new OptionHandler(Flags.disableProgramSplit, passThrough),
+    new OptionHandler(Flags.stopAfterProgramSplit, passThrough),
     new OptionHandler(Flags.disableTypeInference, passThrough),
     new OptionHandler(Flags.useTrivialAbstractValueDomain, passThrough),
     new OptionHandler(Flags.experimentalWrapped, passThrough),
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index da2aa26..5c89ed6 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -40,6 +40,11 @@
     _state = value;
   }
 
+  void set override(bool value) {
+    assert(_state != null);
+    _state = value;
+  }
+
   FeatureOption(this.flag, {this.isNegativeFlag = false});
 }
 
@@ -67,6 +72,13 @@
   /// [FeatureOption]s which default to disabled.
   List<FeatureOption> canary;
 
+  /// Forces canary feature on. This must run after [Option].parse.
+  void forceCanary() {
+    for (var feature in canary) {
+      feature.override = feature.isNegativeFlag ? false : true;
+    }
+  }
+
   // Initialize feature lists.
   FeatureOptions() {
     shipping = [];
@@ -247,6 +259,9 @@
   /// checkLibrary calls are correct.
   bool disableProgramSplit = false;
 
+  // Whether or not to stop compilation after splitting the
+  bool stopAfterProgramSplit = false;
+
   /// Diagnostic option: If `true`, warnings cause the compilation to fail.
   @override
   bool fatalWarnings = false;
@@ -549,6 +564,7 @@
       ..explicitExperimentalFlags = explicitExperimentalFlags
       ..disableInlining = _hasOption(options, Flags.disableInlining)
       ..disableProgramSplit = _hasOption(options, Flags.disableProgramSplit)
+      ..stopAfterProgramSplit = _hasOption(options, Flags.stopAfterProgramSplit)
       ..disableTypeInference = _hasOption(options, Flags.disableTypeInference)
       ..useTrivialAbstractValueDomain =
           _hasOption(options, Flags.useTrivialAbstractValueDomain)
@@ -678,6 +694,7 @@
       // Set flags implied by '--benchmarking-x'.
       // TODO(sra): Use this for some NNBD variant.
       useContentSecurityPolicy = true;
+      features.forceCanary();
     }
 
     if (_soundNullSafety) nullSafetyMode = NullSafetyMode.sound;
diff --git a/pkg/dart2js_tools/lib/src/dart2js_mapping.dart b/pkg/dart2js_tools/lib/src/dart2js_mapping.dart
index 1bb8cf3..ac6b9d7 100644
--- a/pkg/dart2js_tools/lib/src/dart2js_mapping.dart
+++ b/pkg/dart2js_tools/lib/src/dart2js_mapping.dart
@@ -152,6 +152,7 @@
 
 _extractMinifedNames(String encodedInput, SingleMapping sourceMap,
     Map<String, String> minifiedNames, Logger logger) {
+  if (encodedInput.isEmpty) return;
   List<String> input = encodedInput.split(',');
   if (input.length % 2 != 0) {
     logger?.log("Error: expected an even number of entries");
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index ff820cf..438cec8 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -527,7 +527,7 @@
     output = invoker.input + ".S"
     args = [
       "--input",
-      rebase_path(invoker.input),
+      rebase_path(invoker.input, root_build_dir),
       "--output",
       rebase_path(output),
       "--symbol_name",
@@ -546,6 +546,9 @@
     if (invoker.executable) {
       args += [ "--executable" ]
     }
+    if (current_os != "win") {
+      args += [ "--incbin" ]
+    }
     inputs = [ invoker.input ]
     outputs = [ output ]
   }
diff --git a/runtime/docs/types.md b/runtime/docs/types.md
index 9969394..a14ba1b 100644
--- a/runtime/docs/types.md
+++ b/runtime/docs/types.md
@@ -56,7 +56,7 @@
 
 Variable `c` is assigned a new instance of type `C<bool>`. According to the previous sections, the type arguments of the instance `c` could simply be the vector `[bool]`. When the method `foo()` is called on receiver `c`,  the type `bool` in the type argument vector of `c` would properly reflect the type parameter `T` of class `C`. However, when the method `bar()` is called on the same receiver `c`, its type argument vector would need some transformation so that the correct type argument `List<bool>` reflects the type parameter `X` of class `B`.
 
-For this reason, the type argument vector stored in instance `c` is not simply `[bool]`, but `[List<bool>, bool]`. More generally, the type argument vector stored in any instance of class ‘C’ will have the form `[List<T>, T]`, where `T` is substituted with the actual type argument used to allocate the instance. The type at index 0 in the vector represents `X` in class `B` and the type at index 1 represents `T` in class `C`.
+For this reason, the type argument vector stored in instance `c` is not simply `[bool]`, but `[List<bool>, bool]`. More generally, the type argument vector stored in any instance of class `C` will have the form `[List<T>, T]`, where `T` is substituted with the actual type argument used to allocate the instance. The type at index 0 in the vector represents `X` in class `B` and the type at index 1 represents `T` in class `C`.
 
 This *index* is an important attribute of the type parameter. In fact, the `TypeParameter` object contains a field `index` specifying which type argument to look up in the vector in order to *instantiate* the type parameter.
 
@@ -90,14 +90,14 @@
   foo() => T;
 }
 ```
-Note how the flattened type argument vector would now repeat type parameter `T` as in `[T, T]’. This repetition is not necessary, since the type at index 0 in the vector representing `X` in class `B` is always identical to the type at index 1 representing `T` in class `C`. Therefore, the *overlapping* vectors are collapsed into a simple vector `[T]`. In other words, both type parameters `T` of `B` and `C` have now the same index 0.
+Note how the flattened type argument vector would now repeat type parameter `T` as in `[T, T]`. This repetition is not necessary, since the type at index 0 in the vector representing `X` in class `B` is always identical to the type at index 1 representing `T` in class `C`. Therefore, the repeating parts of the vector are shifted as to *overlap* each other. The longer vector `[T, T]` is collapsed into a shorter vector `[T]`. In other words, both type parameters `X` of `B` and `T` of `C` now have the same index 0.
 More complex situations can arise with overlapping vectors:
 ```dart
 class B<R, S> { }
 class C<T> extends B<List<T>, T> { }
 ```
-Instead of using `[List[T], T, T]`, the last `T` is overlapping and collapsed into `[List[T], T]`.
-Class `B` has 2 type parameters and 2 type arguments, whereas class `C` has 1 type parameter and 3 type arguments.
+Instead of using `[List[T], T, T]`, the last overlapping `T` is collapsed and the vector becomes `[List[T], T]`.
+Class `B` has 2 type parameters and 2 type arguments, whereas class `C` has 1 type parameter and 2 type arguments.
 
 
 ## TypeRef
@@ -107,7 +107,7 @@
 class B<T> { }
 class D extends B<D> { }
 ```
-Flattening the type argument vector of instances of class `D` poses a problem. Indeed, the type argument at index 0 must represent type `D`, which is the type argument of class `B`. Therefore, type `D` is represented by `D[D[D[D[...]]]]` ad infinitum. To solve this problem, the `TypeRef` object extending `AbstractType` is introduced. It contains a single field `type`, which points to an `AbstractType`. Basically, `TypeRef` references another type and it is used to break cycles in type graphs. In this example, type `D` is represented as `D[TypeRef to D]`, or graphically:
+Flattening the type argument vector of instances of class `D` poses a problem. Indeed, the type argument at index 0 must represent type `D`, which is the type argument of class `B`. Therefore, type `D` would need to be represented by `D[D[D[D[...]]]]` ad infinitum. To solve this problem, the `TypeRef` object extending `AbstractType` is introduced. It contains a single field `type`, which points to an `AbstractType`. Basically, `TypeRef` references another type and it is used to break cycles in type graphs. In this example, type `D` is represented as `D[TypeRef -> D]`, or graphically:
 ```
 D:    D[TypeRef]
       ^    |
@@ -122,8 +122,8 @@
 ```
 Corresponding types and their internal representation:
 ```
-D1:    D1[TypeRef to D2]
-D2:    D2[TypeRef to D1]
+D1:    D1[TypeRef -> D2]
+D2:    D2[TypeRef -> D1]
 ```
 
 Note that not all declarations of types can be represented this way, but only what is called *contractive* types:
@@ -145,7 +145,7 @@
 D<D<D<T>>>: D[D<D<D<D<T>>>>, D<D<T>>]
 ...
 ```
-The representation is divergent and therefore not possible. The VM detects non-contractive types and reports an error. These non-contractive types make no sense in real programs and rejecting them is not an issue at all.
+The representation is divergent and therefore not possible. The VM detects non-contractive types (search for `ClassFinalizer::CheckRecursiveType` in the [class finalizer](https://github.com/dart-lang/sdk/blob/master/runtime/vm/class_finalizer.cc)) and reports an error. These non-contractive types make no sense in real programs and rejecting them is not an issue at all.
 
 ## Compile Time Type
 
@@ -220,7 +220,7 @@
 
 The index of function type parameters can be assigned immediately upon loading of the type parameter from the kernel file. This is possible because enclosing generic functions are always loaded prior to inner generic functions. Therefore the number of type parameters declared in the  enclosing scope is known. The picture is more complicated with class type parameters. Classes can reference each other and a clear order is not defined in the kernel file. Clusters of classes must be fully loaded before type arguments can be flattened, which in turn determines the indices of class type parameters.
 
-As a last step of finalization, types and type argument vectors get canonicalized not only to minimize memory usage but also to optimize type tests. Indeed, previously tested types can be entered in test caches to speed up further tests. Since types are canonical, using their address in the heap works.
+As a last step of finalization, types and type argument vectors get canonicalized not only to minimize memory usage but also to optimize type tests. Indeed, previously tested types can be entered in test caches to speed up further tests. Since types are canonical, using their heap address as an identifier works (different addresses imply unequal types).
 
 ## Canonicalization and Hash
 
@@ -249,5 +249,5 @@
 
 ## Nullability of TypeArguments
 
-The previous section ignores an important point, sharing is only allowed if the nullability of each type argument in the instantiator is not modified by the instantiation. If the new instance was allocated with `A<S?, T>()` instead, it would only work if the first type argument in the instantiator is nullable, otherwise, its nullability would change from legacy or non-nullable to nullable. This check cannot be performed at compile time and performing it at run time undermines the benefits of the optimization. However, the nullability change can be computed quickly for the whole vector with a simple integer operation. Since two bits are required per type argument, there is a maximal vector length allowed to apply this optimization. For details, search for `kNullabilityBitsPerType` in the [source](https://github.com/dart-lang/sdk/blob/master/runtime/vm/object.h) and read the comments.
+The previous section ignores an important point, namely, sharing is only allowed if the nullability of each type argument in the instantiator is not modified by the instantiation. If the new instance was allocated with `A<S?, T>()` instead, it would only work if the first type argument in the instantiator is nullable, otherwise, its nullability would change from legacy or non-nullable to nullable. This check cannot be performed at compile time and performing it at run time undermines the benefits of the optimization. However, whether the nullability will remain unchanged for each type argument in the vector can be computed quickly for the whole vector with a simple integer operation. Each type argument vector is assigned a nullability value reflecting the nullability of each one of its type arguments. Since two bits are required per type argument, there is a maximal vector length allowed to apply this optimization. For a more detailed explanation, search for `kNullabilityBitsPerType` in the [source](https://github.com/dart-lang/sdk/blob/master/runtime/vm/object.h) and read the comments.
 
diff --git a/runtime/tools/bin_to_assembly.py b/runtime/tools/bin_to_assembly.py
index b66c285..3a9257a 100755
--- a/runtime/tools/bin_to_assembly.py
+++ b/runtime/tools/bin_to_assembly.py
@@ -26,6 +26,7 @@
     parser.add_option("--target_os", action="store", type="string")
     parser.add_option("--size_symbol_name", action="store", type="string")
     parser.add_option("--target_arch", action="store", type="string")
+    parser.add_option("--incbin", action="store_true", default=False)
 
     (options, args) = parser.parse_args()
     if not options.output:
@@ -86,9 +87,15 @@
                     output_file.write("byte %d\n" % (byte if isinstance(byte, int) else ord(byte)))
                     size += 1
             else:
+                incbin = options.incbin
                 for byte in input_file.read():
-                    output_file.write(".byte %d\n" % (byte if isinstance(byte, int) else ord(byte)))
                     size += 1
+                    if not incbin:
+                        output_file.write(
+                            ".byte %d\n" %
+                            (byte if isinstance(byte, int) else ord(byte)))
+                if incbin:
+                    output_file.write(".incbin \"%s\"\n" % options.input)
 
         if options.target_os not in ["mac", "ios", "win"]:
             output_file.write(".size {0}, .-{0}\n".format(options.symbol_name))
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 3807314..7e9299f 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -991,7 +991,7 @@
   } else {
     ASSERT(base != TMP2);
     AddImmediate(TMP2, base, offset);
-    ldr(dest, Address(base, 0, Address::Offset, kObjectBytes),
+    ldr(dest, Address(TMP2, 0, Address::Offset, kObjectBytes),
         kUnsignedFourBytes);  // Zero-extension.
   }
   add(dest, dest, Operand(HEAP_BITS, LSL, 32));
@@ -1024,7 +1024,7 @@
   } else {
     ASSERT(base != TMP2);
     AddImmediate(TMP2, base, offset);
-    ldr(dest, Address(base, 0, Address::Offset, kObjectBytes),
+    ldr(dest, Address(TMP2, 0, Address::Offset, kObjectBytes),
         kUnsignedFourBytes);  // Zero-extension.
   }
 #endif
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index ca85ce7..56144e61 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -2412,7 +2412,8 @@
   }
 
   // At this point temp is known to be type arguments offset in words.
-  __ movq(temp, compiler::FieldAddress(value_reg, temp, TIMES_8, 0));
+  __ movq(temp, compiler::FieldAddress(value_reg, temp,
+                                       TIMES_COMPRESSED_WORD_SIZE, 0));
   __ CompareObject(temp, TypeArguments::ZoneHandle(
                              compiler->zone(),
                              AbstractType::Handle(field().type()).arguments()));
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index ed0be69..f72258a 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -3312,7 +3312,7 @@
   const intptr_t entry_length =
       target::ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) *
       target::kCompressedWordSize;
-  __ OBJ(add)(R13, Immediate(entry_length));  // Next entry.
+  __ addq(R13, Immediate(entry_length));  // Next entry.
   __ jmp(&loop);
 
   __ Bind(&found);
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index ab868b4..461d575 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -329,7 +329,9 @@
                                         const Array& arguments_descriptor) {
   auto const zone = thread->zone();
   const ArgumentsDescriptor args_desc(arguments_descriptor);
-  ASSERT(receiver.ptr() == arguments.At(args_desc.FirstArgIndex()));
+  ASSERT(
+      CompressedInstancePtr(receiver.ptr()).Decompress(thread->heap_base()) ==
+      arguments.At(args_desc.FirstArgIndex()));
   // Allocate an Invocation object.
   const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
 
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 278a04f..0b47906 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -617,7 +617,7 @@
     ASSERT(instance_size > 0);
     // Allocate the instance and read in all the fields for the object.
     *result ^= Object::Allocate(cls_.id(), instance_size, Heap::kNew,
-                                /*compressed*/ false);
+                                Instance::ContainsCompressedPointers());
   } else {
     cls_ ^= ReadObjectImpl(kAsInlinedObject);
     ASSERT(!cls_.IsNull());
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
index 694bc1d..7c915db 100644
--- a/sdk/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -556,14 +556,14 @@
     Object? universe, Object? rtiArray, Object? typeArguments, int depth) {
   bool changed = false;
   int length = _Utils.arrayLength(rtiArray);
-  Object? result = JS('', '[]');
+  Object? result = _Utils.newArrayOrEmpty(length);
   for (int i = 0; i < length; i++) {
     Rti rti = _Utils.asRti(_Utils.arrayAt(rtiArray, i));
     Rti substitutedRti = _substitute(universe, rti, typeArguments, depth);
     if (_Utils.isNotIdentical(substitutedRti, rti)) {
       changed = true;
     }
-    _Utils.arrayPush(result, substitutedRti);
+    _Utils.arraySetAt(result, i, substitutedRti);
   }
   return changed ? result : rtiArray;
 }
@@ -573,7 +573,7 @@
   bool changed = false;
   int length = _Utils.arrayLength(namedArray);
   assert(_Utils.isMultipleOf(length, 3));
-  Object? result = JS('', '[]');
+  Object? result = _Utils.newArrayOrEmpty(length);
   for (int i = 0; i < length; i += 3) {
     String name = _Utils.asString(_Utils.arrayAt(namedArray, i));
     bool isRequired = _Utils.asBool(_Utils.arrayAt(namedArray, i + 1));
@@ -582,9 +582,8 @@
     if (_Utils.isNotIdentical(substitutedRti, rti)) {
       changed = true;
     }
-    _Utils.arrayPush(result, name);
-    _Utils.arrayPush(result, isRequired);
-    _Utils.arrayPush(result, substitutedRti);
+    JS('', '#.splice(#, #, #, #, #)', result, i, 3, name, isRequired,
+        substitutedRti);
   }
   return changed ? result : namedArray;
 }
@@ -1419,7 +1418,7 @@
     String name = Rti._getInterfaceName(rti);
     name = _unminifyOrTag(name);
     var arguments = Rti._getInterfaceTypeArguments(rti);
-    if (arguments.length != 0) {
+    if (arguments.length > 0) {
       name += '<' + _rtiArrayToString(arguments, genericContext) + '>';
     }
     return name;
@@ -1633,9 +1632,9 @@
     } else if (_Utils.isNum(probe)) {
       int length = _Utils.asInt(probe);
       Rti erased = _lookupErasedRti(universe);
-      Object? arguments = JS('', '[]');
+      Object? arguments = _Utils.newArrayOrEmpty(length);
       for (int i = 0; i < length; i++) {
-        _Utils.arrayPush(arguments, erased);
+        _Utils.arraySetAt(arguments, i, erased);
       }
       Rti interface = _lookupInterfaceRti(universe, cls, arguments);
       JS('', '#.# = #', metadata, cls, interface);
@@ -1657,8 +1656,8 @@
   static void addTypeParameterVariances(Object? universe, Object? variances) =>
       _Utils.objectAssign(typeParameterVariances(universe), variances);
 
-  static JSArray sharedEmptyArray(Object? universe) =>
-      JS('JSArray', '#.#', universe, RtiUniverseFieldNames.sharedEmptyArray);
+  static JSArray sharedEmptyArray(Object? universe) => JS('JSUnmodifiableArray',
+      '#.#', universe, RtiUniverseFieldNames.sharedEmptyArray);
 
   /// Evaluates [recipe] in the global environment.
   static Rti eval(Object? universe, String recipe, bool normalize) {
@@ -1986,7 +1985,7 @@
     assert(_Utils.isString(name));
     String s = _Utils.asString(name);
     int length = _Utils.arrayLength(arguments);
-    if (length != 0) {
+    if (length > 0) {
       s = _recipeJoin4(s, Recipe.startTypeArgumentsString,
           _canonicalRecipeJoin(arguments), Recipe.endTypeArgumentsString);
     }
@@ -2143,7 +2142,7 @@
     if (normalize) {
       int length = _Utils.arrayLength(bounds);
       int count = 0;
-      Object? typeArguments = JS('', 'new Array(#)', length);
+      Object? typeArguments = _Utils.newArrayOrEmpty(length);
       for (int i = 0; i < length; i++) {
         Rti bound = _Utils.asRti(_Utils.arrayAt(bounds, i));
         if (Rti._getKind(bound) == Rti.kindNever) {
@@ -2996,7 +2995,7 @@
     var recipes = TypeRule.lookupSupertype(rule, tName);
     if (recipes == null) return false;
     int length = _Utils.arrayLength(recipes);
-    Object? supertypeArgs = length > 0 ? JS('', 'new Array(#)', length) : null;
+    Object? supertypeArgs = _Utils.newArrayOrEmpty(length);
     for (int i = 0; i < length; i++) {
       String recipe = _Utils.asString(_Utils.arrayAt(recipes, i));
       Rti supertypeArg = _Universe.evalInEnvironment(universe, s, recipe);
@@ -3020,7 +3019,7 @@
 
 bool _areArgumentsSubtypes(Object? universe, Object? sArgs, Object? sVariances,
     Object? sEnv, Object? tArgs, Object? tEnv) {
-  int length = sArgs != null ? _Utils.arrayLength(sArgs) : 0;
+  int length = _Utils.arrayLength(sArgs);
   assert(length == _Utils.arrayLength(tArgs));
   bool hasVariances = sVariances != null;
   if (JS_GET_FLAG("VARIANCE")) {
@@ -3139,6 +3138,10 @@
     }
   }
 
+  static Object? newArrayOrEmpty(int length) => length > 0
+      ? JS('', 'new Array(#)', length)
+      : _Universe.sharedEmptyArray(_theUniverse());
+
   static bool isArray(Object? o) => JS('bool', 'Array.isArray(#)', o);
 
   static int arrayLength(Object? array) => JS('int', '#.length', array);
@@ -3158,10 +3161,6 @@
   static JSArray arrayConcat(Object? a1, Object? a2) =>
       JS('JSArray', '#.concat(#)', a1, a2);
 
-  static void arrayPush(Object? array, Object? value) {
-    JS('', '#.push(#)', array, value);
-  }
-
   static String substring(String s, int start, int end) =>
       JS('String', '#.substring(#, #)', s, start, end);
 
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 1c4e7ce..b931e84 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -40,6 +40,7 @@
 js/js_util/async_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/jsify_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/promise_reject_null_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
+js/js_util/properties_implicit_checks_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/properties_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/method_call_on_object_test: SkipByDesign # Issue 42085.
 js/mock_test/*: SkipByDesign # Issue 42085.
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index a6d093b..7fbd5a0 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -40,6 +40,7 @@
 js/js_util/async_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/jsify_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/promise_reject_null_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
+js/js_util/properties_implicit_checks_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/js_util/properties_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
 js/method_call_on_object_test: SkipByDesign # Issue 42085.
 js/mock_test/*: SkipByDesign # Issue 42085.
diff --git a/tools/VERSION b/tools/VERSION
index dcd145e..438d0ba 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 263
+PRERELEASE 264
 PRERELEASE_PATCH 0
\ No newline at end of file