Version 2.10.0-25.0.dev

Merge commit '0057b6066cf0455ab3b51262e3e9462ed8692926' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index d93eff3..b98042d 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -5186,7 +5186,8 @@
   @override
   final LinkedUnitContext linkedContext;
 
-  final bool isNonNullableByDefaultInternal;
+  @override
+  final FeatureSet featureSet;
 
   /// The compilation unit that defines this library.
   CompilationUnitElement _definingCompilationUnit;
@@ -5232,7 +5233,7 @@
   /// Initialize a newly created library element in the given [context] to have
   /// the given [name] and [offset].
   LibraryElementImpl(this.context, this.session, String name, int offset,
-      this.nameLength, this.isNonNullableByDefaultInternal)
+      this.nameLength, this.featureSet)
       : linkedContext = null,
         super(name, offset);
 
@@ -5245,7 +5246,7 @@
       this.linkedContext,
       Reference reference,
       CompilationUnit linkedNode)
-      : isNonNullableByDefaultInternal = linkedContext.isNNBD,
+      : featureSet = linkedNode.featureSet,
         super.forLinkedNode(null, reference, linkedNode) {
     _name = name;
     _nameOffset = offset;
@@ -5363,9 +5364,6 @@
   }
 
   @override
-  FeatureSet get featureSet => (linkedNode as CompilationUnit).featureSet;
-
-  @override
   bool get hasExtUri {
     if (linkedNode != null) {
       var unit = linkedContext.unit_withDirectives;
@@ -5481,6 +5479,10 @@
   bool get isNonNullableByDefault =>
       ElementTypeProvider.current.isLibraryNonNullableByDefault(this);
 
+  bool get isNonNullableByDefaultInternal {
+    return featureSet.isEnabled(Feature.non_nullable);
+  }
+
   /// Return `true` if the receiver directly or indirectly imports the
   /// 'dart:html' libraries.
   bool get isOrImportsBrowserLibrary {
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index f01860f..1a89506 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -1347,88 +1347,13 @@
   @override
   DartType refineBinaryExpressionType(DartType leftType, TokenType operator,
       DartType rightType, DartType currentType) {
-    if (leftType is TypeParameterType && leftType.bound.isDartCoreNum) {
-      if (rightType == leftType || rightType.isDartCoreInt) {
-        if (operator == TokenType.PLUS ||
-            operator == TokenType.MINUS ||
-            operator == TokenType.STAR ||
-            operator == TokenType.PLUS_EQ ||
-            operator == TokenType.MINUS_EQ ||
-            operator == TokenType.STAR_EQ ||
-            operator == TokenType.PLUS_PLUS ||
-            operator == TokenType.MINUS_MINUS) {
-          if (isNonNullableByDefault) {
-            return promoteToNonNull(leftType as TypeImpl);
-          }
-          return leftType;
-        }
-      }
-      if (rightType.isDartCoreDouble) {
-        if (operator == TokenType.PLUS ||
-            operator == TokenType.MINUS ||
-            operator == TokenType.STAR ||
-            operator == TokenType.SLASH) {
-          InterfaceTypeImpl doubleType = typeProvider.doubleType;
-          if (isNonNullableByDefault) {
-            return promoteToNonNull(doubleType);
-          }
-          return doubleType;
-        }
-      }
-      return currentType;
+    if (isNonNullableByDefault) {
+      return _refineBinaryExpressionTypeNullSafe(
+          leftType, operator, rightType, currentType);
+    } else {
+      return _refineBinaryExpressionTypeLegacy(
+          leftType, operator, rightType, currentType);
     }
-    // bool
-    if (operator == TokenType.AMPERSAND_AMPERSAND ||
-        operator == TokenType.BAR_BAR ||
-        operator == TokenType.EQ_EQ ||
-        operator == TokenType.BANG_EQ) {
-      if (isNonNullableByDefault) {
-        return promoteToNonNull(typeProvider.boolType);
-      }
-      return typeProvider.boolType;
-    }
-    if (leftType.isDartCoreInt) {
-      // int op double
-      if (operator == TokenType.MINUS ||
-          operator == TokenType.PERCENT ||
-          operator == TokenType.PLUS ||
-          operator == TokenType.STAR ||
-          operator == TokenType.MINUS_EQ ||
-          operator == TokenType.PERCENT_EQ ||
-          operator == TokenType.PLUS_EQ ||
-          operator == TokenType.STAR_EQ) {
-        if (rightType.isDartCoreDouble) {
-          InterfaceTypeImpl doubleType = typeProvider.doubleType;
-          if (isNonNullableByDefault) {
-            return promoteToNonNull(doubleType);
-          }
-          return doubleType;
-        }
-      }
-      // int op int
-      if (operator == TokenType.MINUS ||
-          operator == TokenType.PERCENT ||
-          operator == TokenType.PLUS ||
-          operator == TokenType.STAR ||
-          operator == TokenType.TILDE_SLASH ||
-          operator == TokenType.MINUS_EQ ||
-          operator == TokenType.PERCENT_EQ ||
-          operator == TokenType.PLUS_EQ ||
-          operator == TokenType.STAR_EQ ||
-          operator == TokenType.TILDE_SLASH_EQ ||
-          operator == TokenType.PLUS_PLUS ||
-          operator == TokenType.MINUS_MINUS) {
-        if (rightType.isDartCoreInt) {
-          InterfaceTypeImpl intType = typeProvider.intType;
-          if (isNonNullableByDefault) {
-            return promoteToNonNull(intType);
-          }
-          return intType;
-        }
-      }
-    }
-    // default
-    return currentType;
   }
 
   /// Replaces all covariant occurrences of `dynamic`, `void`, and `Object` or
@@ -1516,6 +1441,148 @@
       return typeParameterImpl.defaultType;
     }).toList();
   }
+
+  DartType _refineBinaryExpressionTypeLegacy(DartType leftType,
+      TokenType operator, DartType rightType, DartType currentType) {
+    if (leftType is TypeParameterType && leftType.bound.isDartCoreNum) {
+      if (rightType == leftType || rightType.isDartCoreInt) {
+        if (operator == TokenType.PLUS ||
+            operator == TokenType.MINUS ||
+            operator == TokenType.STAR ||
+            operator == TokenType.PLUS_EQ ||
+            operator == TokenType.MINUS_EQ ||
+            operator == TokenType.STAR_EQ ||
+            operator == TokenType.PLUS_PLUS ||
+            operator == TokenType.MINUS_MINUS) {
+          return leftType;
+        }
+      }
+      if (rightType.isDartCoreDouble) {
+        if (operator == TokenType.PLUS ||
+            operator == TokenType.MINUS ||
+            operator == TokenType.STAR ||
+            operator == TokenType.SLASH) {
+          InterfaceTypeImpl doubleType = typeProvider.doubleType;
+          return doubleType;
+        }
+      }
+      return currentType;
+    }
+    // bool
+    if (operator == TokenType.AMPERSAND_AMPERSAND ||
+        operator == TokenType.BAR_BAR ||
+        operator == TokenType.EQ_EQ ||
+        operator == TokenType.BANG_EQ) {
+      return typeProvider.boolType;
+    }
+    if (leftType.isDartCoreInt) {
+      // int op double
+      if (operator == TokenType.MINUS ||
+          operator == TokenType.PERCENT ||
+          operator == TokenType.PLUS ||
+          operator == TokenType.STAR ||
+          operator == TokenType.MINUS_EQ ||
+          operator == TokenType.PERCENT_EQ ||
+          operator == TokenType.PLUS_EQ ||
+          operator == TokenType.STAR_EQ) {
+        if (rightType.isDartCoreDouble) {
+          InterfaceTypeImpl doubleType = typeProvider.doubleType;
+          return doubleType;
+        }
+      }
+      // int op int
+      if (operator == TokenType.MINUS ||
+          operator == TokenType.PERCENT ||
+          operator == TokenType.PLUS ||
+          operator == TokenType.STAR ||
+          operator == TokenType.TILDE_SLASH ||
+          operator == TokenType.MINUS_EQ ||
+          operator == TokenType.PERCENT_EQ ||
+          operator == TokenType.PLUS_EQ ||
+          operator == TokenType.STAR_EQ ||
+          operator == TokenType.TILDE_SLASH_EQ ||
+          operator == TokenType.PLUS_PLUS ||
+          operator == TokenType.MINUS_MINUS) {
+        if (rightType.isDartCoreInt) {
+          InterfaceTypeImpl intType = typeProvider.intType;
+          return intType;
+        }
+      }
+    }
+    // default
+    return currentType;
+  }
+
+  DartType _refineBinaryExpressionTypeNullSafe(DartType leftType,
+      TokenType operator, DartType rightType, DartType currentType) {
+    if (leftType is TypeParameterType && leftType.bound.isDartCoreNum) {
+      if (rightType == leftType || rightType.isDartCoreInt) {
+        if (operator == TokenType.PLUS ||
+            operator == TokenType.MINUS ||
+            operator == TokenType.STAR ||
+            operator == TokenType.PLUS_EQ ||
+            operator == TokenType.MINUS_EQ ||
+            operator == TokenType.STAR_EQ ||
+            operator == TokenType.PLUS_PLUS ||
+            operator == TokenType.MINUS_MINUS) {
+          return promoteToNonNull(leftType as TypeImpl);
+        }
+      }
+      if (rightType.isDartCoreDouble) {
+        if (operator == TokenType.PLUS ||
+            operator == TokenType.MINUS ||
+            operator == TokenType.STAR ||
+            operator == TokenType.SLASH) {
+          InterfaceTypeImpl doubleType = typeProvider.doubleType;
+          return promoteToNonNull(doubleType);
+        }
+      }
+      return currentType;
+    }
+    // bool
+    if (operator == TokenType.AMPERSAND_AMPERSAND ||
+        operator == TokenType.BAR_BAR ||
+        operator == TokenType.EQ_EQ ||
+        operator == TokenType.BANG_EQ) {
+      return promoteToNonNull(typeProvider.boolType);
+    }
+    if (leftType.isDartCoreInt) {
+      // int op double
+      if (operator == TokenType.MINUS ||
+          operator == TokenType.PERCENT ||
+          operator == TokenType.PLUS ||
+          operator == TokenType.STAR ||
+          operator == TokenType.MINUS_EQ ||
+          operator == TokenType.PERCENT_EQ ||
+          operator == TokenType.PLUS_EQ ||
+          operator == TokenType.STAR_EQ) {
+        if (rightType.isDartCoreDouble) {
+          InterfaceTypeImpl doubleType = typeProvider.doubleType;
+          return promoteToNonNull(doubleType);
+        }
+      }
+      // int op int
+      if (operator == TokenType.MINUS ||
+          operator == TokenType.PERCENT ||
+          operator == TokenType.PLUS ||
+          operator == TokenType.STAR ||
+          operator == TokenType.TILDE_SLASH ||
+          operator == TokenType.MINUS_EQ ||
+          operator == TokenType.PERCENT_EQ ||
+          operator == TokenType.PLUS_EQ ||
+          operator == TokenType.STAR_EQ ||
+          operator == TokenType.TILDE_SLASH_EQ ||
+          operator == TokenType.PLUS_PLUS ||
+          operator == TokenType.MINUS_MINUS) {
+        if (rightType.isDartCoreInt) {
+          InterfaceTypeImpl intType = typeProvider.intType;
+          return promoteToNonNull(intType);
+        }
+      }
+    }
+    // default
+    return currentType;
+  }
 }
 
 class _TypeVariableEliminator extends Substitution {
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 0b63323..ec6ff4a 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -4,12 +4,14 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -439,12 +441,15 @@
     String fileName = "/$libraryName.dart";
     CompilationUnitElementImpl unit = compilationUnit(fileName);
     LibraryElementImpl library = LibraryElementImpl(
-        context,
-        AnalysisSessionImpl(null),
-        libraryName,
-        0,
-        libraryName.length,
-        isNonNullableByDefault);
+      context,
+      AnalysisSessionImpl(null),
+      libraryName,
+      0,
+      libraryName.length,
+      FeatureSet.fromEnableFlags(
+        isNonNullableByDefault ? [EnableString.non_nullable] : [],
+      ),
+    );
     library.definingCompilationUnit = unit;
     return library;
   }
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 0058130..727b439 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -2,7 +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.
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -79,11 +78,6 @@
   /// Return `true` if this unit is a part of a bundle that is being linked.
   bool get isLinking => bundleContext.isLinking;
 
-  /// TODO(scheglov) remove it
-  bool get isNNBD {
-    return _unit.featureSet.isEnabled(Feature.non_nullable);
-  }
-
   TypeProvider get typeProvider {
     var libraryReference = libraryContext.reference;
     var libraryElement = libraryReference.element as LibraryElementImpl;
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
index 400a4bb..f97de63 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
@@ -2,9 +2,11 @@
 // 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:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -823,7 +825,7 @@
       'dart.async',
       0,
       0,
-      true,
+      FeatureSet.fromEnableFlags([EnableString.non_nullable]),
     );
 
     var asyncUnit = CompilationUnitElementImpl();
@@ -916,7 +918,7 @@
       'dart.core',
       0,
       0,
-      true,
+      FeatureSet.fromEnableFlags([EnableString.non_nullable]),
     );
     coreLibrary.definingCompilationUnit = coreUnit;
 
diff --git a/pkg/analyzer/test/generated/elements_types_mixin.dart b/pkg/analyzer/test/generated/elements_types_mixin.dart
index 00b967c..9740869 100644
--- a/pkg/analyzer/test/generated/elements_types_mixin.dart
+++ b/pkg/analyzer/test/generated/elements_types_mixin.dart
@@ -2,10 +2,12 @@
 // 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:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -400,8 +402,16 @@
     AnalysisContext analysisContext,
     AnalysisSessionImpl analysisSession,
   }) {
-    var library = LibraryElementImpl(analysisContext, analysisSession, uriStr,
-        -1, 0, typeSystem.isNonNullableByDefault);
+    var library = LibraryElementImpl(
+      analysisContext,
+      analysisSession,
+      uriStr,
+      -1,
+      0,
+      FeatureSet.fromEnableFlags(
+        typeSystem.isNonNullableByDefault ? [EnableString.non_nullable] : [],
+      ),
+    );
     library.typeSystem = typeSystem;
     library.typeProvider = typeSystem.typeProvider;
 
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index dddd438..33b96b4 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -488,12 +488,7 @@
         compilationUnit.source = definingCompilationUnitSource;
     var featureSet = context.analysisOptions.contextFeatures;
     LibraryElementImpl library = LibraryElementImpl(
-        context,
-        driver?.currentSession,
-        libraryName,
-        -1,
-        0,
-        featureSet.isEnabled(Feature.non_nullable));
+        context, driver?.currentSession, libraryName, -1, 0, featureSet);
     library.definingCompilationUnit = compilationUnit;
     library.parts = sourcedCompilationUnits;
     return library;
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index e51614b..b501bfe 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -739,8 +739,8 @@
         definingCompilationUnit.source = source;
     var featureSet = FeatureSet.forTesting();
 
-    _definingLibrary = LibraryElementImpl(
-        context, null, null, -1, 0, featureSet.isEnabled(Feature.non_nullable));
+    _definingLibrary =
+        LibraryElementImpl(context, null, null, -1, 0, featureSet);
     _definingLibrary.definingCompilationUnit = definingCompilationUnit;
 
     _definingLibrary.typeProvider = context.typeProviderLegacy;
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 311e888..476dcf7 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_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.
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -706,7 +707,8 @@
 
   void test_visitPartDirective() {
     PartDirective fromNode = AstTestFactory.partDirective2("part.dart");
-    LibraryElement element = LibraryElementImpl(null, null, 'lib', -1, 0, true);
+    LibraryElement element = LibraryElementImpl(
+        null, null, 'lib', -1, 0, FeatureSet.fromEnableFlags([]));
     fromNode.element = element;
     PartDirective toNode = AstTestFactory.partDirective2("part.dart");
     ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -716,7 +718,8 @@
   void test_visitPartOfDirective() {
     PartOfDirective fromNode = AstTestFactory.partOfDirective(
         AstTestFactory.libraryIdentifier2(["lib"]));
-    LibraryElement element = LibraryElementImpl(null, null, 'lib', -1, 0, true);
+    LibraryElement element = LibraryElementImpl(
+        null, null, 'lib', -1, 0, FeatureSet.fromEnableFlags([]));
     fromNode.element = element;
     PartOfDirective toNode = AstTestFactory.partOfDirective(
         AstTestFactory.libraryIdentifier2(["lib"]));
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 3b0915a..f8fa5e5 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_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.
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/constant/value.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -2197,8 +2198,8 @@
 
   void test_setImports() {
     AnalysisContext context = TestAnalysisContext();
-    LibraryElementImpl library =
-        LibraryElementImpl(context, null, 'l1', -1, 0, true);
+    LibraryElementImpl library = LibraryElementImpl(
+        context, null, 'l1', -1, 0, FeatureSet.fromEnableFlags([]));
     List<ImportElementImpl> expectedImports = [
       ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
       ElementFactory.importFor(ElementFactory.library(context, "l3"), null)
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index adc7f8d..e864bec 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -2,12 +2,14 @@
 // 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:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
@@ -462,7 +464,7 @@
     var uriStr = 'package:test/test.dart';
 
     _myLibrary = LibraryElementImpl(analysisContext, analysisSession, uriStr,
-        -1, 0, typeSystem.isNonNullableByDefault);
+        -1, 0, FeatureSet.fromEnableFlags([EnableString.non_nullable]));
     _myLibrary.typeSystem = typeSystem;
     _myLibrary.typeProvider = coreLibrary.typeProvider;
 
diff --git a/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart b/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
index c5be237..a63524f 100644
--- a/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
+++ b/pkg/vm_snapshot_analysis/test/instruction_sizes_test.dart
@@ -370,8 +370,6 @@
               diffToJson(diff),
               equals({
                 '#type': 'library',
-                '@stubs': {'#type': 'library'},
-                '@unknown': {'#type': 'library'},
                 'package:input': {
                   '#type': 'package',
                   'package:input/input.dart': {
@@ -421,8 +419,6 @@
               diffToJson(diff),
               equals({
                 '#type': 'library',
-                '@stubs': {'#type': 'library'},
-                '@unknown': {'#type': 'library'},
                 'package:input': {
                   '#type': 'package',
                   'package:input/input.dart': {
@@ -624,8 +620,6 @@
                   '#type': 'package',
                   'package:input/input.dart': {
                     '#type': 'library',
-                    '#size': lessThan(0),
-                    'K': {'#size': isA<int>(), '#type': 'class'},
                     '::': {
                       '#type': 'class',
                       'makeSomeClosures': {
@@ -691,10 +685,48 @@
 // On Windows there is some issue with interpreting entry point URI as a package URI
 // it instead gets interpreted as a file URI - which breaks comparison. So we
 // simply ignore entry point library (main.dart).
+// Additionally this function removes all nodes with the size below
+// the given threshold.
 Map<String, dynamic> diffToJson(ProgramInfo diff,
     {bool keepOnlyInputPackage = false}) {
   final diffJson = diff.toJson();
   diffJson.removeWhere((key, _) =>
       keepOnlyInputPackage ? key != 'package:input' : key.startsWith('file:'));
-  return diffJson;
+
+  // Rebuild the diff JSON discarding all nodes with size below threshold.
+  const smallChangeThreshold = 16;
+  Map<String, dynamic> discardSmallChanges(Map<String, dynamic> map) {
+    final result = <String, dynamic>{};
+
+    // First recursively process all children (skipping #type and #size keys).
+    for (var key in map.keys) {
+      if (key == '#type' || key == '#size') continue;
+      final value = discardSmallChanges(map[key]);
+      if (value != null) {
+        result[key] = value;
+      }
+    }
+
+    // Check if this node own #size is above the threshold and copy it
+    // into the result if it is.
+    final size = map['#size'] ?? 0;
+    if (size.abs() > smallChangeThreshold) {
+      result['#size'] = size;
+    }
+
+    // If the node has no children and its own size does not pass the threshold
+    // drop it.
+    if (result.isEmpty) {
+      return null;
+    }
+
+    // We decided that this node is meaningful - preserve its type.
+    if (map.containsKey('#type')) {
+      result['#type'] = map['#type'];
+    }
+
+    return result;
+  }
+
+  return discardSmallChanges(diffJson);
 }
diff --git a/runtime/tests/vm/dart/deferred_loading_and_weak_serialization_references_test.dart b/runtime/tests/vm/dart/deferred_loading_and_weak_serialization_references_test.dart
new file mode 100644
index 0000000..7447a06
--- /dev/null
+++ b/runtime/tests/vm/dart/deferred_loading_and_weak_serialization_references_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// These flags can cause WeakSerializationReferences to replace the owner of
+// some Code, which must be accounted for in AssignLoadingUnitsCodeVisitor.
+
+// VMOptions=--no_retain_function_objects
+// VMOptions=--dwarf_stack_traces
+
+import "splay_test.dart" deferred as splay; // Some non-trivial code.
+
+main() async {
+  await splay.loadLibrary();
+  splay.main();
+}
diff --git a/runtime/tests/vm/dart_2/deferred_loading_and_weak_serialization_references_test.dart b/runtime/tests/vm/dart_2/deferred_loading_and_weak_serialization_references_test.dart
new file mode 100644
index 0000000..7447a06
--- /dev/null
+++ b/runtime/tests/vm/dart_2/deferred_loading_and_weak_serialization_references_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// These flags can cause WeakSerializationReferences to replace the owner of
+// some Code, which must be accounted for in AssignLoadingUnitsCodeVisitor.
+
+// VMOptions=--no_retain_function_objects
+// VMOptions=--dwarf_stack_traces
+
+import "splay_test.dart" deferred as splay; // Some non-trivial code.
+
+main() async {
+  await splay.loadLibrary();
+  splay.main();
+}
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 34cc58e..f535c91 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -213,6 +213,12 @@
       }
     }
 
+    if (FLAG_print_classes) {
+      for (intptr_t i = 0; i < class_array.Length(); i++) {
+        cls ^= class_array.At(i);
+        PrintClassInformation(cls);
+      }
+    }
     // Clear pending classes array.
     class_array = GrowableObjectArray::New();
     object_store->set_pending_classes(class_array);
@@ -1155,9 +1161,6 @@
   }
   // Mark as loaded and finalized.
   cls.Finalize();
-  if (FLAG_print_classes) {
-    PrintClassInformation(cls);
-  }
   FinalizeMemberTypes(cls);
 
   if (cls.is_enum_class()) {
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index c604a7c..878ce4a 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -391,7 +391,7 @@
 
       TraceForRetainedFunctions();
       FinalizeDispatchTable();
-      ReplaceFunctionPCRelativeCallEntries();
+      ReplaceFunctionStaticCallEntries();
 
       DropFunctions();
       DropFields();
@@ -1644,7 +1644,7 @@
   printed.Release();
 }
 
-void Precompiler::ReplaceFunctionPCRelativeCallEntries() {
+void Precompiler::ReplaceFunctionStaticCallEntries() {
   class StaticCallTableEntryFixer : public CodeVisitor {
    public:
     explicit StaticCallTableEntryFixer(Zone* zone)
@@ -1660,7 +1660,9 @@
       for (auto& view : static_calls) {
         kind_and_offset_ = view.Get<Code::kSCallTableKindAndOffset>();
         auto const kind = Code::KindField::decode(kind_and_offset_.Value());
-        if (kind != Code::kPcRelativeCall) continue;
+
+        if ((kind != Code::kCallViaCode) && (kind != Code::kPcRelativeCall))
+          continue;
 
         target_function_ = view.Get<Code::kSCallTableFunctionTarget>();
         if (target_function_.IsNull()) continue;
@@ -1671,6 +1673,12 @@
         ASSERT(!target_code_.IsStubCode());
         view.Set<Code::kSCallTableCodeOrTypeTarget>(target_code_);
         view.Set<Code::kSCallTableFunctionTarget>(Object::null_function());
+        if (kind == Code::kCallViaCode) {
+          auto const pc_offset =
+              Code::OffsetField::decode(kind_and_offset_.Value());
+          const uword pc = pc_offset + code.PayloadStart();
+          CodePatcher::PatchStaticCallAt(pc, code, target_code_);
+        }
         if (FLAG_trace_precompiler) {
           THR_Print("Updated static call entry to %s in \"%s\"\n",
                     target_function_.ToFullyQualifiedCString(),
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 5f84a82..e80a81c 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -301,7 +301,7 @@
 
   void TraceForRetainedFunctions();
   void FinalizeDispatchTable();
-  void ReplaceFunctionPCRelativeCallEntries();
+  void ReplaceFunctionStaticCallEntries();
   void DropFunctions();
   void DropFields();
   void TraceTypesFromRetainedClasses();
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 1785105..718c6df 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2002,11 +2002,8 @@
 
 NameIndex KernelReaderHelper::ReadInterfaceMemberNameReference() {
   NameIndex name_index = reader_.ReadCanonicalNameReference();
-  NameIndex origin_name_index = reader_.ReadCanonicalNameReference();
-  if (!FLAG_precompiled_mode && origin_name_index != NameIndex::kInvalidName) {
-    // Reference to a skipped member signature target, return the origin target.
-    return origin_name_index;
-  }
+  reader_
+      .ReadCanonicalNameReference();  // read interface target origin reference
   return name_index;
 }
 
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index a992ff3..092af49 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1947,16 +1947,7 @@
   ProcedureHelper procedure_helper(&helper_);
 
   procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
-  // CFE adds 'member signature' abstract functions to a legacy class deriving
-  // or implementing an opted-in interface. The signature of these functions is
-  // legacy erased and used as the target of interface calls. They are used for
-  // static reasoning about the program by CFE, but not really needed by the VM.
-  // In certain situations (e.g. issue 162073826), a large number of these
-  // additional functions can cause strain on the VM. They are therefore skipped
-  // in jit mode and their associated origin function is used instead as
-  // interface call target.
-  if (procedure_helper.IsRedirectingFactoryConstructor() ||
-      (!FLAG_precompiled_mode && procedure_helper.IsMemberSignature())) {
+  if (procedure_helper.IsRedirectingFactoryConstructor()) {
     helper_.SetOffset(procedure_end);
     return;
   }
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index 13665eb..b5f73c3 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -368,8 +368,7 @@
         if (target_.IsNull()) {
           target_ =
               Code::RawCast(view.Get<Code::kSCallTableCodeOrTypeTarget>());
-          ASSERT(!Code::Cast(target_).IsFunctionCode());
-          // Allocation stub or AllocateContext or AllocateArray or ...
+          ASSERT(!target_.IsNull());  // Already bound.
           continue;
         }
 
@@ -1314,7 +1313,7 @@
   void VisitCode(const Code& code) {
     intptr_t id;
     if (code.IsFunctionCode()) {
-      func_ ^= code.owner();
+      func_ ^= code.function();
       cls_ = func_.Owner();
       lib_ = cls_.library();
       unit_ = lib_.loading_unit();
diff --git a/tools/VERSION b/tools/VERSION
index d3b9276..93f5efb 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 24
+PRERELEASE 25
 PRERELEASE_PATCH 0
\ No newline at end of file