[vm/aot/tfa] Detect if a method/setter is called from this

This information could useful in AOT to omit unchecked entry points.

Change-Id: I1c54720e46d578dc64f67306abdf4619a34ae122
Reviewed-on: https://dart-review.googlesource.com/c/77921
Auto-Submit: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Samir Jindel <sjindel@google.com>
Reviewed-by: Samir Jindel <sjindel@google.com>
diff --git a/pkg/vm/lib/metadata/procedure_attributes.dart b/pkg/vm/lib/metadata/procedure_attributes.dart
index 531f7d2..5b9f5ce 100644
--- a/pkg/vm/lib/metadata/procedure_attributes.dart
+++ b/pkg/vm/lib/metadata/procedure_attributes.dart
@@ -9,19 +9,28 @@
 /// Metadata for annotating procedures with various attributes.
 class ProcedureAttributesMetadata {
   final bool hasDynamicUses;
+  final bool hasThisUses;
   final bool hasNonThisUses;
   final bool hasTearOffUses;
 
   const ProcedureAttributesMetadata(
-      {this.hasDynamicUses, this.hasNonThisUses, this.hasTearOffUses});
+      {this.hasDynamicUses: true,
+      this.hasThisUses: true,
+      this.hasNonThisUses: true,
+      this.hasTearOffUses: true});
 
   const ProcedureAttributesMetadata.noDynamicUses()
-      : this(hasDynamicUses: false, hasNonThisUses: true, hasTearOffUses: true);
+      : this(hasDynamicUses: false);
 
   @override
-  String toString() => "hasDynamicUses:$hasDynamicUses,"
-      "hasNonThisUses:$hasNonThisUses,"
-      "hasTearOffUses:$hasTearOffUses";
+  String toString() {
+    final attrs = <String>[];
+    if (!hasDynamicUses) attrs.add('hasDynamicUses:false');
+    if (!hasThisUses) attrs.add('hasThisUses:false');
+    if (!hasNonThisUses) attrs.add('hasNonThisUses:false');
+    if (!hasTearOffUses) attrs.add('hasTearOffUses:false');
+    return attrs.join(',');
+  }
 }
 
 /// Repository for [ProcedureAttributesMetadata].
@@ -30,6 +39,7 @@
   static const int kDynamicUsesBit = 1 << 0;
   static const int kNonThisUsesBit = 1 << 1;
   static const int kTearOffUsesBit = 1 << 2;
+  static const int kThisUsesBit = 1 << 3;
 
   @override
   final String tag = 'vm.procedure-attributes.metadata';
@@ -45,6 +55,9 @@
     if (metadata.hasDynamicUses) {
       flags |= kDynamicUsesBit;
     }
+    if (metadata.hasThisUses) {
+      flags |= kThisUsesBit;
+    }
     if (metadata.hasNonThisUses) {
       flags |= kNonThisUsesBit;
     }
@@ -58,12 +71,14 @@
   ProcedureAttributesMetadata readFromBinary(Node node, BinarySource source) {
     final int flags = source.readByte();
 
-    final bool hasDynamicUses = (flags & kDynamicUsesBit) == kDynamicUsesBit;
-    final bool hasNonThisUses = (flags & kNonThisUsesBit) == kNonThisUsesBit;
-    final bool hasTearOffUses = (flags & kTearOffUsesBit) == kTearOffUsesBit;
+    final bool hasDynamicUses = (flags & kDynamicUsesBit) != 0;
+    final bool hasThisUses = (flags & kThisUsesBit) != 0;
+    final bool hasNonThisUses = (flags & kNonThisUsesBit) != 0;
+    final bool hasTearOffUses = (flags & kTearOffUsesBit) != 0;
 
     return new ProcedureAttributesMetadata(
         hasDynamicUses: hasDynamicUses,
+        hasThisUses: hasThisUses,
         hasNonThisUses: hasNonThisUses,
         hasTearOffUses: hasTearOffUses);
   }
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index f2e28a8..8c406ea 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -350,7 +350,9 @@
           if (selector.callKind != CallKind.PropertyGet) {
             if (selector is DynamicSelector) {
               typeFlowAnalysis._calledViaDynamicSelector.add(target);
-            } else if (selector is! VirtualSelector) {
+            } else if (selector is VirtualSelector) {
+              typeFlowAnalysis._calledViaThis.add(target);
+            } else {
               typeFlowAnalysis._calledViaInterfaceSelector.add(target);
             }
           }
@@ -1200,6 +1202,7 @@
   final Set<Member> _tearOffTaken = new Set<Member>();
   final Set<Member> _calledViaDynamicSelector = new Set<Member>();
   final Set<Member> _calledViaInterfaceSelector = new Set<Member>();
+  final Set<Member> _calledViaThis = new Set<Member>();
 
   TypeFlowAnalysis(this.target, Component component, CoreTypes coreTypes,
       ClosedWorldClassHierarchy hierarchy, this.environment, this.libraryIndex,
@@ -1255,6 +1258,10 @@
   bool isCalledDynamically(Member member) =>
       _calledViaDynamicSelector.contains(member);
 
+  /// Returns true if this member is called via this call.
+  /// Getters are not tracked. For fields, only setter is tracked.
+  bool isCalledViaThis(Member member) => _calledViaThis.contains(member);
+
   /// Returns true if this member is called via non-this call.
   /// Getters are not tracked. For fields, only setter is tracked.
   bool isCalledNotViaThis(Member member) =>
@@ -1328,4 +1335,9 @@
   void recordMemberCalledViaInterfaceSelector(Member target) {
     _calledViaInterfaceSelector.add(target);
   }
+
+  @override
+  void recordMemberCalledViaThis(Member target) {
+    _calledViaThis.add(target);
+  }
 }
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index 01ca9c2..8497461 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -28,6 +28,9 @@
   /// Record the fact that given member is called via interface selector
   /// (not dynamically, and not from `this`).
   void recordMemberCalledViaInterfaceSelector(Member target);
+
+  /// Record the fact that given member is called from this.
+  void recordMemberCalledViaThis(Member target);
 }
 
 abstract class ParsedPragma {}
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index aeb1c0e..e1030c7 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -638,14 +638,17 @@
   TypeExpr visitDirectMethodInvocation(DirectMethodInvocation node) {
     final receiver = _visit(node.receiver);
     final args = _visitArguments(receiver, node.arguments);
-    assertx(node.target is! Field);
-    assertx(!node.target.isGetter && !node.target.isSetter);
-    if (receiver is! ThisExpression) {
+    final target = node.target;
+    assertx(target is! Field);
+    assertx(!target.isGetter && !target.isSetter);
+    if (receiver is ThisExpression) {
+      _entryPointsListener.recordMemberCalledViaThis(target);
+    } else {
       // Conservatively record direct invocations with non-this receiver
       // as being done via interface selectors.
-      _entryPointsListener.recordMemberCalledViaInterfaceSelector(node.target);
+      _entryPointsListener.recordMemberCalledViaInterfaceSelector(target);
     }
-    return _makeCall(node, new DirectSelector(node.target), args);
+    return _makeCall(node, new DirectSelector(target), args);
   }
 
   @override
@@ -653,8 +656,8 @@
     final receiver = _visit(node.receiver);
     final args = new Args<TypeExpr>([receiver]);
     final target = node.target;
-    // No need to record this invocation as performed via interface selector as
-    // PropertyGet invocations are not tracked at all.
+    // No need to record this invocation as performed via this or via interface
+    // selector as PropertyGet invocations are not tracked at all.
     return _makeCall(
         node, new DirectSelector(target, callKind: CallKind.PropertyGet), args);
   }
@@ -666,7 +669,9 @@
     final args = new Args<TypeExpr>([receiver, value]);
     final target = node.target;
     assertx((target is Field) || ((target is Procedure) && target.isSetter));
-    if (receiver is! ThisExpression) {
+    if (receiver is ThisExpression) {
+      _entryPointsListener.recordMemberCalledViaThis(target);
+    } else {
       // Conservatively record direct invocations with non-this receiver
       // as being done via interface selectors.
       _entryPointsListener.recordMemberCalledViaInterfaceSelector(target);
@@ -835,7 +840,7 @@
       return new Type.empty();
     } else {
       if ((target is Field) || ((target is Procedure) && target.isGetter)) {
-        // Call via field.
+        // Call via field/getter.
         // TODO(alexmarkov): Consider cleaning up this code as it duplicates
         // processing in DirectInvocation.
         final fieldValue = _makeCall(
@@ -846,6 +851,7 @@
             new Args.withReceiver(args, fieldValue));
         return _staticType(node);
       } else {
+        _entryPointsListener.recordMemberCalledViaThis(target);
         return _makeCall(node, new DirectSelector(target), args);
       }
     }
@@ -878,6 +884,7 @@
         .getDispatchTarget(_superclass, node.name, setter: true);
     if (target != null) {
       assertx((target is Field) || ((target is Procedure) && target.isSetter));
+      _entryPointsListener.recordMemberCalledViaThis(target);
       _makeCall(node,
           new DirectSelector(target, callKind: CallKind.PropertySet), args);
     }
@@ -1232,6 +1239,9 @@
 
   @override
   void recordMemberCalledViaInterfaceSelector(Member target) {}
+
+  @override
+  void recordMemberCalledViaThis(Member target) {}
 }
 
 class CreateAllSummariesVisitor extends RecursiveVisitor<Null> {
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 32a37f7..42835d1 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -215,6 +215,7 @@
           !(member is Procedure && member.isGetter)) {
         final attrs = new ProcedureAttributesMetadata(
             hasDynamicUses: _typeFlowAnalysis.isCalledDynamically(member),
+            hasThisUses: _typeFlowAnalysis.isCalledViaThis(member),
             hasNonThisUses: _typeFlowAnalysis.isCalledNotViaThis(member),
             hasTearOffUses: _typeFlowAnalysis.isTearOffTaken(member));
         _procedureAttributesMetadata.mapping[member] = attrs;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
index 18791a5..6e4319f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
@@ -32,7 +32,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  @self::MethodAnnotation::•(42)
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  @self::MethodAnnotation::•(42)
   method instanceMethod() → void {}
 }
 static method foo([@vm.inferred-type.metadata=dart.core::Null?] (core::List<core::int>) → void a) → core::int {
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 a70213a..4fe492d 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
@@ -4,18 +4,18 @@
 import "dart:typed_data" as typ;
 
 class _Vector extends core::Object {
-[@vm.inferred-type.metadata=dart.core::_Smi] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field core::int _offset;
-[@vm.inferred-type.metadata=dart.core::_Smi] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field core::int _length;
-[@vm.inferred-type.metadata=dart.typed_data::_Float64List] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field core::List<core::double> _elements;
+[@vm.inferred-type.metadata=dart.core::_Smi] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field core::int _offset;
+[@vm.inferred-type.metadata=dart.core::_Smi] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field core::int _length;
+[@vm.inferred-type.metadata=dart.typed_data::_Float64List] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field core::List<core::double> _elements;
   constructor •([@vm.inferred-type.metadata=dart.core::_Smi] core::int size) → self::_Vector
     : self::_Vector::_offset = 0, self::_Vector::_length = size, self::_Vector::_elements = [@vm.inferred-type.metadata=dart.typed_data::_Float64List] typ::Float64List::•(size), super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  operator [](core::int i) → core::double
+[@vm.procedure-attributes.metadata=hasTearOffUses:false]  operator [](core::int i) → core::double
     return [@vm.direct-call.metadata=dart.typed_data::_Float64List::[]] [@vm.inferred-type.metadata=dart.core::_Double] [@vm.direct-call.metadata=#lib::_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements}.{core::List::[]}([@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int?] i.{core::num::+}([@vm.direct-call.metadata=#lib::_Vector::_offset] [@vm.inferred-type.metadata=dart.core::_Smi] this.{self::_Vector::_offset}));
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  operator []=([@vm.inferred-type.metadata=dart.core::_OneByteString] core::int i, core::double value) → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  operator []=([@vm.inferred-type.metadata=dart.core::_OneByteString] core::int i, core::double value) → void {
     let dynamic #t1 = [@vm.direct-call.metadata=#lib::_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements} in let dynamic #t2 = i in let dynamic #t3 = [@vm.direct-call.metadata=#lib::_Vector::_offset] [@vm.inferred-type.metadata=dart.core::_Smi] this.{self::_Vector::_offset} in throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
   }
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  operator *([@vm.inferred-type.metadata=#lib::_Vector?] self::_Vector a) → core::double {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  operator *([@vm.inferred-type.metadata=#lib::_Vector?] self::_Vector a) → core::double {
     core::double result = 0.0;
     for (core::int i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<??] [@vm.inferred-type.metadata=dart.core::bool] i.{core::num::<}([@vm.direct-call.metadata=#lib::_Vector::_length] [@vm.inferred-type.metadata=dart.core::_Smi] this.{self::_Vector::_length}); i = [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+??] [@vm.inferred-type.metadata=int?] 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)));
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
index dbb202b..a64c4af 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
@@ -12,14 +12,14 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foo() → core::int
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method foo() → core::int
     return 1;
 }
 class C extends core::Object implements self::A {
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foo() → core::int
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method foo() → core::int
     return 2;
 }
 class D extends self::C {
@@ -31,7 +31,7 @@
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method toString() → core::String
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method toString() → core::String
     return "D";
 }
 [@vm.inferred-type.metadata=#lib::D?]static field self::A dd;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
index 9d2b351..8c953da 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
@@ -27,7 +27,7 @@
   synthetic constructor •() → self::_StreamImpl
     : super self::Stream::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foobar([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData, {[@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = null}) → self::StreamSubscription {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method foobar([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData, {[@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = null}) → self::StreamSubscription {
     return [@vm.inferred-type.metadata=!] this.{self::_StreamImpl::_createSubscription}();
   }
 [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  method _createSubscription() → self::StreamSubscription {
@@ -48,11 +48,11 @@
     ;
 }
 abstract class StreamView extends self::Stream {
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field self::Stream _stream;
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field self::Stream _stream;
   constructor •([@vm.inferred-type.metadata=!] self::Stream stream) → self::StreamView
     : self::StreamView::_stream = stream, super self::Stream::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foobar([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData, {[@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = null}) → self::StreamSubscription {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasTearOffUses:false]  method foobar([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData, {[@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = null}) → self::StreamSubscription {
     return [@vm.direct-call.metadata=#lib::StreamView::_stream] [@vm.inferred-type.metadata=!] this.{self::StreamView::_stream}.{self::Stream::foobar}(onData, onError: onError);
   }
 }
@@ -60,13 +60,13 @@
   constructor •([@vm.inferred-type.metadata=!] self::Stream stream) → self::ByteStream
     : super self::StreamView::•(stream)
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method super_foobar1([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method super_foobar1([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData) → dynamic {
     super.{self::StreamView::foobar}(onData);
   }
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method super_foobar2([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method super_foobar2([@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData) → dynamic {
     super.{self::StreamView::foobar}(onData);
   }
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method super_foobar3({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = null, [@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = null}) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method super_foobar3({[@vm.inferred-type.metadata=dart.core::Null?] (dynamic) → void onData = null, [@vm.inferred-type.metadata=dart.core::Null?] core::Function onError = null}) → dynamic {
     super.{self::StreamView::foobar}(onData, onError: onError);
   }
   get super_stream() → self::Stream
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
index 059840d..e1eda81 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
@@ -19,21 +19,21 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foo() → core::Object
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method foo() → core::Object
     return new self::T1::•();
 }
 class C extends core::Object implements self::A {
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foo() → core::Object
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method foo() → core::Object
     return new self::T2::•();
 }
 class DeepCaller1 extends core::Object {
   synthetic constructor •() → self::DeepCaller1
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method barL1() → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method barL1() → dynamic
     return [@vm.direct-call.metadata=#lib::DeepCaller1::barL2] this.{self::DeepCaller1::barL2}();
 [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  method barL2() → dynamic
     return [@vm.direct-call.metadata=#lib::DeepCaller1::barL3] this.{self::DeepCaller1::barL3}();
@@ -43,7 +43,7 @@
     return self::field1;
 }
 class D extends core::Object {
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  field core::Object field2 = [@vm.inferred-type.metadata=!] self::getValue();
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  field core::Object field2 = [@vm.inferred-type.metadata=!] self::getValue();
   synthetic constructor •() → self::D
     : super core::Object::•()
     ;
@@ -52,7 +52,7 @@
   synthetic constructor •() → self::DeepCaller2
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method barL1([@vm.inferred-type.metadata=#lib::D] self::D dd) → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method barL1([@vm.inferred-type.metadata=#lib::D] self::D dd) → dynamic
     return [@vm.direct-call.metadata=#lib::DeepCaller2::barL2] [@vm.inferred-type.metadata=!] this.{self::DeepCaller2::barL2}(dd);
 [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  method barL2([@vm.inferred-type.metadata=#lib::D] self::D dd) → dynamic
     return [@vm.direct-call.metadata=#lib::DeepCaller2::barL3] [@vm.inferred-type.metadata=!] this.{self::DeepCaller2::barL3}(dd);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
index bfd1b3b..dafde6a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
@@ -17,14 +17,14 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foo() → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method foo() → dynamic
     return new self::T1::•();
 }
 class Intermediate extends core::Object {
   synthetic constructor •() → self::Intermediate
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method bar([@vm.inferred-type.metadata=#lib::B?] self::A aa) → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method bar([@vm.inferred-type.metadata=#lib::B?] self::A aa) → dynamic
     return [@vm.direct-call.metadata=#lib::B::foo??] [@vm.inferred-type.metadata=#lib::T1] aa.{self::A::foo}();
 }
 [@vm.inferred-type.metadata=dart.core::Null?]static field core::Function unknown;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
index 2646d8c..97088fd 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
@@ -22,7 +22,7 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foo() → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method foo() → dynamic
     return new self::T1::•();
 }
 abstract class C extends core::Object implements self::B {
@@ -41,14 +41,14 @@
   synthetic constructor •() → self::E
     : super self::D::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foo() → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method foo() → dynamic
     return new self::T2::•();
 }
 class Intermediate extends core::Object {
   synthetic constructor •() → self::Intermediate
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method bar(self::A aa) → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method bar(self::A aa) → dynamic
     return [@vm.inferred-type.metadata=!] aa.{self::A::foo}();
 }
 [@vm.inferred-type.metadata=dart.core::Null?]static field core::Function unknown;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
index 678c481..2cadebe 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
@@ -21,22 +21,22 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method foo() → dynamic
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method foo() → dynamic
     return new self::T1::•();
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method bar() → dynamic
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method bar() → dynamic
     return new self::T2::•();
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method bazz() → dynamic
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method bazz() → dynamic
     return new self::T3::•();
 }
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method foo() → dynamic
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method foo() → dynamic
     return new self::T1::•();
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method bar() → dynamic
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method bar() → dynamic
     return new self::T2::•();
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method bazz() → dynamic
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method bazz() → dynamic
     return new self::T3::•();
 }
 [@vm.inferred-type.metadata=dart.core::Null?]static field core::Function unknown;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
index 4cd386d..8557ca8 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
@@ -13,8 +13,8 @@
     ;
 }
 class A extends core::Object {
-[@vm.inferred-type.metadata=#lib::T1] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  field dynamic field1 = new self::T1::•();
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  field dynamic field2 = new self::T1::•();
+[@vm.inferred-type.metadata=#lib::T1] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  field dynamic field1 = new self::T1::•();
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  field dynamic field2 = new self::T1::•();
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
@@ -23,7 +23,7 @@
   synthetic constructor •() → self::DeepCaller1
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method barL1([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method barL1([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
     return [@vm.direct-call.metadata=#lib::DeepCaller1::barL2] [@vm.inferred-type.metadata=#lib::T1] this.{self::DeepCaller1::barL2}(aa);
 [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  method barL2([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
     return [@vm.direct-call.metadata=#lib::DeepCaller1::barL3] [@vm.inferred-type.metadata=#lib::T1] this.{self::DeepCaller1::barL3}(aa);
@@ -36,7 +36,7 @@
   synthetic constructor •() → self::DeepCaller2
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method barL1([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method barL1([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
     return [@vm.direct-call.metadata=#lib::DeepCaller2::barL2] [@vm.inferred-type.metadata=!] this.{self::DeepCaller2::barL2}(aa);
 [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  method barL2([@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
     return [@vm.direct-call.metadata=#lib::DeepCaller2::barL3] [@vm.inferred-type.metadata=!] this.{self::DeepCaller2::barL3}(aa);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect
index 416c061..7f7b453 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::T1
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method go() → self::T3
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method go() → self::T3
     return new self::T3::•();
 }
 class T2 extends core::Object {
@@ -18,12 +18,12 @@
   synthetic constructor •() → self::T3
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method run() → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method run() → dynamic {
     core::print("hi");
   }
 }
 class Q<T extends core::Object = dynamic> extends core::Object {
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field self::Q::T result;
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field self::Q::T result;
   constructor •(self::Q::T result) → self::Q<self::Q::T>
     : self::Q::result = result, super core::Object::•()
     ;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect
index 185ec67..9e1d95e 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect
@@ -9,22 +9,22 @@
   synthetic constructor •() → self::T1
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foo() → void {}
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method foo() → void {}
 }
 class T2 extends core::Object implements self::I {
   synthetic constructor •() → self::T2
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foo() → void {}
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method foo() → void {}
 }
 class Point extends core::Object {
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field self::I x;
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field self::I x;
   const constructor •([@vm.inferred-type.metadata=!] self::I x) → self::Point
     : self::Point::x = x, super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method newPoint1() → self::Point
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method newPoint1() → self::Point
     return new self::Point::•([@vm.direct-call.metadata=#lib::Point::x] [@vm.inferred-type.metadata=!] this.{self::Point::x});
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method newPoint2() → self::Point
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method newPoint2() → self::Point
     return new self::Point::•([@vm.direct-call.metadata=#lib::Point::x] [@vm.inferred-type.metadata=!] this.{self::Point::x});
 }
 static method getX([@vm.inferred-type.metadata=#lib::Point] dynamic point) → dynamic {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
index 0f919ab..691d012 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
@@ -44,21 +44,21 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
     return new self::T1::•();
   }
   no-such-method-forwarder get bar() → dynamic
     return [@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withoutType("get:bar", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  no-such-method-forwarder method foo() → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  no-such-method-forwarder method foo() → dynamic
     return [@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5 = null]) → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5 = null]) → dynamic
     return [@vm.direct-call.metadata=#lib::B::noSuchMethod] [@vm.inferred-type.metadata=#lib::T1] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withoutType("bazz", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
     return new self::T2::•();
   }
 }
@@ -68,16 +68,16 @@
     ;
   no-such-method-forwarder get bar() → dynamic
     return [@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withoutType("get:bar", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  no-such-method-forwarder method foo() → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  no-such-method-forwarder method foo() → dynamic
     return [@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withoutType("foo", const <core::Type>[], const <dynamic>[], [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5 = null]) → dynamic
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::Null?] dynamic a5 = null]) → dynamic
     return [@vm.direct-call.metadata=#lib::C::noSuchMethod] [@vm.inferred-type.metadata=#lib::T2] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withoutType("bazz", const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView] core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}), false)) as{TypeError} dynamic;
 }
 class E extends core::Object implements self::A {
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
     return new self::T4::•();
   }
   no-such-method-forwarder get bar() → dynamic
@@ -87,7 +87,7 @@
   synthetic constructor •() → self::F
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
     return new self::T2::•();
   }
 }
@@ -95,7 +95,7 @@
   synthetic constructor •() → self::G
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
     return new self::T5::•();
   }
 }
@@ -103,9 +103,9 @@
   synthetic constructor •() → self::H
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method foo({[@vm.inferred-type.metadata=dart.core::_Smi] dynamic left = null, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic right = null}) → dynamic
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method foo({[@vm.inferred-type.metadata=dart.core::_Smi] dynamic left = null, [@vm.inferred-type.metadata=dart.core::_Smi] dynamic right = null}) → dynamic
     return new self::T6::•();
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method noSuchMethod(core::Invocation invocation) → dynamic {
     return new self::T7::•();
   }
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
index 2f15671..f898084 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
@@ -12,13 +12,13 @@
   synthetic constructor •() → self::T2
     : super self::T0::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method foo() → void {}
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method foo() → void {}
 }
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:true]  method method1(self::T0 t0) → void {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false]  method method1(self::T0 t0) → void {
     [@vm.direct-call.metadata=#lib::T2::foo??] t0.{self::T0::foo}();
   }
 }
@@ -29,7 +29,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method method2(covariant self::T0 t0) → void {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method method2(covariant self::T0 t0) → void {
     [@vm.direct-call.metadata=#lib::T2::foo??] t0.{self::T0::foo}();
   }
 }
@@ -37,7 +37,7 @@
   synthetic constructor •() → self::D
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method method3(self::T0 t0) → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method method3(self::T0 t0) → void {
     [@vm.direct-call.metadata=#lib::T2::foo??] t0.{self::T0::foo}();
   }
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
index d53e30a..3de865c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
@@ -7,7 +7,7 @@
   synthetic constructor •() → self::T1
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method doTest1() → void {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method doTest1() → void {
     self::ok = true;
   }
 }
@@ -16,12 +16,12 @@
   synthetic constructor •() → self::A1
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=#lib::T1?] dynamic a5 = null]) → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=#lib::T1?] dynamic a5 = null]) → void {
     [@vm.direct-call.metadata=#lib::A1::foo] this.{self::A1::foo} = a5 as{TypeError} self::T1;
   }
 }
 class B1 extends core::Object {
-[@vm.inferred-type.metadata=#lib::A1] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  field self::A1 aa1 = new self::A1::•();
+[@vm.inferred-type.metadata=#lib::A1] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  field self::A1 aa1 = new self::A1::•();
   synthetic constructor •() → self::B1
     : super core::Object::•()
     ;
@@ -30,7 +30,7 @@
   synthetic constructor •() → self::T2
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method doTest2() → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method doTest2() → void {
     self::ok = true;
   }
 }
@@ -39,12 +39,12 @@
   synthetic constructor •() → self::A2
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = null, [@vm.inferred-type.metadata=#lib::T2?] dynamic a6 = null]) → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = null, [@vm.inferred-type.metadata=#lib::T2?] dynamic a6 = null]) → void {
     [@vm.direct-call.metadata=#lib::A2::foo] this.{self::A2::foo} = a6;
   }
 }
 abstract class B2Base extends core::Object {
-[@vm.inferred-type.metadata=#lib::A2] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  field dynamic _aa = new self::A2::•();
+[@vm.inferred-type.metadata=#lib::A2] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  field dynamic _aa = new self::A2::•();
   synthetic constructor •() → self::B2Base
     : super core::Object::•()
     ;
@@ -55,7 +55,7 @@
   synthetic constructor •() → self::B2
     : super self::B2Base::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method doSuperCall() → void {
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method doSuperCall() → void {
     [@vm.call-site-attributes.metadata=receiverType:dynamic] [@vm.direct-call.metadata=#lib::A2::call] [@vm.inferred-type.metadata=#lib::A2] super.{self::B2Base::aa2}.call(1, 2, 3, 4, 5, new self::T2::•());
   }
 }
@@ -63,7 +63,7 @@
   synthetic constructor •() → self::T3
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method doTest3() → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method doTest3() → void {
     self::ok = true;
   }
 }
@@ -72,12 +72,12 @@
   synthetic constructor •() → self::A3
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = null, [@vm.inferred-type.metadata=#lib::T3?] dynamic a7 = null]) → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = null, [@vm.inferred-type.metadata=#lib::T3?] dynamic a7 = null]) → void {
     [@vm.direct-call.metadata=#lib::A3::foo] this.{self::A3::foo} = a7;
   }
 }
 class B3 extends core::Object {
-[@vm.inferred-type.metadata=#lib::A3] [@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  field self::A3 aa3 = new self::A3::•();
+[@vm.inferred-type.metadata=#lib::A3] [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  field self::A3 aa3 = new self::A3::•();
   synthetic constructor •() → self::B3
     : super core::Object::•()
     ;
@@ -86,7 +86,7 @@
   synthetic constructor •() → self::T4
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method doTest4() → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method doTest4() → void {
     self::ok = true;
   }
 }
@@ -95,12 +95,12 @@
   synthetic constructor •() → self::A4
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a7 = null, [@vm.inferred-type.metadata=#lib::T4?] dynamic a8 = null]) → void {
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method call([dynamic a1 = null, dynamic a2 = null, dynamic a3 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = null, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a7 = null, [@vm.inferred-type.metadata=#lib::T4?] dynamic a8 = null]) → void {
     [@vm.direct-call.metadata=#lib::A4::foo] this.{self::A4::foo} = a8;
   }
 }
 class B4 extends core::Object {
-[@vm.inferred-type.metadata=#lib::A4] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  field dynamic _aa = new self::A4::•();
+[@vm.inferred-type.metadata=#lib::A4] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  field dynamic _aa = new self::A4::•();
   synthetic constructor •() → self::B4
     : super core::Object::•()
     ;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
index 73ca4dc..2f8a8ba 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
@@ -11,11 +11,11 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:true]  method foo() → core::int
+[@vm.procedure-attributes.metadata=hasThisUses:false]  method foo() → core::int
     return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo() as{TypeError} core::num) as{TypeError} core::int;
 }
 class TearOffDynamicMethod extends core::Object {
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  field dynamic bazz;
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  field dynamic bazz;
   constructor •(dynamic arg) → self::TearOffDynamicMethod
     : self::TearOffDynamicMethod::bazz = arg.foo, super core::Object::•() {
     this.{self::TearOffDynamicMethod::bazz}();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
index 6ba149e..f56b7cc 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
@@ -12,13 +12,13 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:true]  method foo() → core::int
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false]  method foo() → core::int
     return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int?] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B::bar] [@vm.inferred-type.metadata=dart.core::_Smi] [@vm.inferred-type.metadata=#lib::B] self::knownResult().bar() as{TypeError} core::num) as{TypeError} core::int;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method bar() → core::int
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method bar() → core::int
     return 3;
 }
 class TearOffInterfaceMethod extends core::Object {
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  field dynamic bazz;
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  field dynamic bazz;
   constructor •([@vm.inferred-type.metadata=#lib::B] self::A arg) → self::TearOffInterfaceMethod
     : self::TearOffInterfaceMethod::bazz = arg.{self::A::foo}, super core::Object::•()
     ;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
index def90fa..1410d58 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
@@ -12,14 +12,14 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:true,hasNonThisUses:true,hasTearOffUses:false]  method foo() → core::int
+[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false]  method foo() → core::int
     return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int?] 1.{core::num::+}([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=int?] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo() as{TypeError} core::num) as{TypeError} core::int;
 }
 abstract class Base extends core::Object {
   synthetic constructor •() → self::Base
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:true]  method foo() → core::int
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false]  method foo() → core::int
     return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int?] 3.{core::num::+}([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=int?] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo() as{TypeError} core::num) as{TypeError} core::int;
 [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:false,hasTearOffUses:false]  method doCall(dynamic x) → core::int
     return [@vm.call-site-attributes.metadata=receiverType:dynamic] x.call() as{TypeError} core::int;
@@ -28,7 +28,7 @@
   synthetic constructor •() → self::TearOffSuperMethod
     : super self::Base::•()
     ;
-[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasNonThisUses:true,hasTearOffUses:false]  method bar() → core::int
+[@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasTearOffUses:false]  method bar() → core::int
     return [@vm.direct-call.metadata=#lib::Base::doCall] [@vm.inferred-type.metadata=int?] this.{self::Base::doCall}(super.{self::Base::foo});
 }
 [@vm.inferred-type.metadata=#lib::B?]static field self::A aa = new self::B::•();
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index cdbafc0..cf59420 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -1665,12 +1665,13 @@
   const int kDynamicUsesBit = 1 << 0;
   const int kNonThisUsesBit = 1 << 1;
   const int kTearOffUsesBit = 1 << 2;
+  const int kThisUsesBit = 1 << 3;
 
   const uint8_t flags = helper_->ReadByte();
-  metadata->has_dynamic_invocations =
-      (flags & kDynamicUsesBit) == kDynamicUsesBit;
-  metadata->has_non_this_uses = (flags & kNonThisUsesBit) == kNonThisUsesBit;
-  metadata->has_tearoff_uses = (flags & kTearOffUsesBit) == kTearOffUsesBit;
+  metadata->has_dynamic_invocations = (flags & kDynamicUsesBit) != 0;
+  metadata->has_this_uses = (flags & kThisUsesBit) != 0;
+  metadata->has_non_this_uses = (flags & kNonThisUsesBit) != 0;
+  metadata->has_tearoff_uses = (flags & kTearOffUsesBit) != 0;
   return true;
 }
 
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 7a3fe1a..d7737be 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -876,15 +876,10 @@
 };
 
 struct ProcedureAttributesMetadata {
-  ProcedureAttributesMetadata(bool has_dynamic_invocations = true,
-                              bool has_non_this_uses = true,
-                              bool has_tearoff_uses = true)
-      : has_dynamic_invocations(has_dynamic_invocations),
-        has_non_this_uses(has_non_this_uses),
-        has_tearoff_uses(has_tearoff_uses) {}
-  bool has_dynamic_invocations;
-  bool has_non_this_uses;
-  bool has_tearoff_uses;
+  bool has_dynamic_invocations = true;
+  bool has_this_uses = true;
+  bool has_non_this_uses = true;
+  bool has_tearoff_uses = true;
 };
 
 // Helper class which provides access to direct call metadata.