[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.