mirror of
https://github.com/dart-lang/sdk
synced 2024-10-04 16:04:53 +00:00
[vm/aot] Partition table selector IDs based on hierarchy connectedness.
Compared to assigning selector IDs purely by name, this improves the packing of selector rows, reducing the in-memory size of the dispatch table by typically around 20% (75k memory usage reduction for Flutter Gallery on ARM64). It also improved tree shaking of methods called (or rather, not called) via dispatch table calls, reducing the total snapshot sizes of Flutter benchmarks by up to 2.1% (Flutter Gallery: ARM 1.8%, ARM64 2.1%). Fixes https://github.com/dart-lang/sdk/issues/40660 Fixes https://github.com/dart-lang/sdk/issues/41647 Change-Id: Ia9ecfb0818b301bcbad631c377f3910b0a5956de Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/152323 Commit-Queue: Aske Simon Christensen <askesc@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
parent
34dbe66e7d
commit
0549295eb4
|
@ -4,6 +4,7 @@
|
|||
|
||||
import 'package:kernel/ast.dart';
|
||||
|
||||
import 'utils.dart' show assertx, UnionFind;
|
||||
import '../../metadata/procedure_attributes.dart';
|
||||
import '../../metadata/table_selector.dart';
|
||||
|
||||
|
@ -13,51 +14,102 @@ import '../../metadata/table_selector.dart';
|
|||
class TableSelectorAssigner {
|
||||
final TableSelectorMetadata metadata = TableSelectorMetadata();
|
||||
|
||||
final Map<Name, int> _methodSelectorId = {};
|
||||
final Map<Name, int> _getterSelectorId = {};
|
||||
final Map<Name, int> _setterSelectorId = {};
|
||||
final Map<Class, Map<Name, int>> _getterMemberIds = {};
|
||||
final Map<Class, Map<Name, int>> _methodOrSetterMemberIds = {};
|
||||
|
||||
int _selectorIdForMap(Map<Name, int> map, Member member) {
|
||||
return map.putIfAbsent(member.name, () => metadata.addSelector());
|
||||
final UnionFind _unionFind = UnionFind();
|
||||
List<int> _selectorIdForMemberId;
|
||||
|
||||
TableSelectorAssigner(Component component) {
|
||||
for (Library library in component.libraries) {
|
||||
for (Class cls in library.classes) {
|
||||
_memberIdsForClass(cls, getter: false);
|
||||
_memberIdsForClass(cls, getter: true);
|
||||
}
|
||||
}
|
||||
_selectorIdForMemberId = List(_unionFind.size);
|
||||
}
|
||||
|
||||
Map<Name, int> _memberIdsForClass(Class cls, {bool getter}) {
|
||||
if (cls == null) return {};
|
||||
|
||||
final cache = getter ? _getterMemberIds : _methodOrSetterMemberIds;
|
||||
|
||||
// Already computed for this class?
|
||||
Map<Name, int> memberIds = cache[cls];
|
||||
if (memberIds != null) return memberIds;
|
||||
|
||||
// Merge maps from supertypes.
|
||||
memberIds = Map.from(_memberIdsForClass(cls.superclass, getter: getter));
|
||||
for (Supertype impl in cls.implementedTypes) {
|
||||
_memberIdsForClass(impl.classNode, getter: getter).forEach((name, id) {
|
||||
final int firstId = memberIds[name];
|
||||
if (firstId == null) {
|
||||
memberIds[name] = id;
|
||||
} else if (firstId != id) {
|
||||
_unionFind.union(firstId, id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Add declared instance members.
|
||||
for (Member member in cls.members) {
|
||||
if (member.isInstanceMember) {
|
||||
bool addToMap;
|
||||
if (member is Procedure) {
|
||||
switch (member.kind) {
|
||||
case ProcedureKind.Method:
|
||||
addToMap = true;
|
||||
break;
|
||||
case ProcedureKind.Operator:
|
||||
case ProcedureKind.Setter:
|
||||
addToMap = !getter;
|
||||
break;
|
||||
case ProcedureKind.Getter:
|
||||
addToMap = getter;
|
||||
break;
|
||||
default:
|
||||
throw "Unexpected procedure kind '${member.kind}'";
|
||||
}
|
||||
} else if (member is Field) {
|
||||
addToMap = true;
|
||||
} else {
|
||||
throw "Unexpected member kind '${member.runtimeType}'";
|
||||
}
|
||||
if (addToMap && !memberIds.containsKey(member.name)) {
|
||||
memberIds[member.name] = _unionFind.add();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cache[cls] = memberIds;
|
||||
}
|
||||
|
||||
int _selectorIdForMap(Map<Class, Map<Name, int>> map, Member member) {
|
||||
int memberId = map[member.enclosingClass][member.name];
|
||||
if (memberId == null) {
|
||||
assertx(member is Procedure &&
|
||||
((identical(map, _getterMemberIds) &&
|
||||
(member.kind == ProcedureKind.Operator ||
|
||||
member.kind == ProcedureKind.Setter)) ||
|
||||
identical(map, _methodOrSetterMemberIds) &&
|
||||
member.kind == ProcedureKind.Getter));
|
||||
return ProcedureAttributesMetadata.kInvalidSelectorId;
|
||||
}
|
||||
memberId = _unionFind.find(memberId);
|
||||
int selectorId = _selectorIdForMemberId[memberId];
|
||||
if (selectorId == null) {
|
||||
_selectorIdForMemberId[memberId] = selectorId = metadata.addSelector();
|
||||
}
|
||||
return selectorId;
|
||||
}
|
||||
|
||||
int methodOrSetterSelectorId(Member member) {
|
||||
if (member is Procedure) {
|
||||
switch (member.kind) {
|
||||
case ProcedureKind.Method:
|
||||
case ProcedureKind.Operator:
|
||||
return _selectorIdForMap(_methodSelectorId, member);
|
||||
case ProcedureKind.Setter:
|
||||
return _selectorIdForMap(_setterSelectorId, member);
|
||||
case ProcedureKind.Getter:
|
||||
return ProcedureAttributesMetadata.kInvalidSelectorId;
|
||||
default:
|
||||
throw "Unexpected procedure kind '${member.kind}'";
|
||||
}
|
||||
}
|
||||
if (member is Field) {
|
||||
return _selectorIdForMap(_setterSelectorId, member);
|
||||
}
|
||||
throw "Unexpected member kind '${member.runtimeType}'";
|
||||
return _selectorIdForMap(_methodOrSetterMemberIds, member);
|
||||
}
|
||||
|
||||
int getterSelectorId(Member member) {
|
||||
if (member is Procedure) {
|
||||
switch (member.kind) {
|
||||
case ProcedureKind.Getter:
|
||||
case ProcedureKind.Method:
|
||||
return _selectorIdForMap(_getterSelectorId, member);
|
||||
case ProcedureKind.Operator:
|
||||
case ProcedureKind.Setter:
|
||||
return ProcedureAttributesMetadata.kInvalidSelectorId;
|
||||
default:
|
||||
throw "Unexpected procedure kind '${member.kind}'";
|
||||
}
|
||||
}
|
||||
if (member is Field) {
|
||||
return _selectorIdForMap(_getterSelectorId, member);
|
||||
}
|
||||
throw "Unexpected member kind '${member.runtimeType}'";
|
||||
return _selectorIdForMap(_getterMemberIds, member);
|
||||
}
|
||||
|
||||
void registerMethodOrSetterCall(Member member, bool calledOnNull) {
|
||||
|
|
|
@ -163,7 +163,7 @@ class AnnotateKernel extends RecursiveVisitor<Null> {
|
|||
_procedureAttributesMetadata =
|
||||
new ProcedureAttributesMetadataRepository(),
|
||||
_tableSelectorMetadata = new TableSelectorMetadataRepository(),
|
||||
_tableSelectorAssigner = new TableSelectorAssigner(),
|
||||
_tableSelectorAssigner = new TableSelectorAssigner(component),
|
||||
_unboxingInfoMetadata = new UnboxingInfoMetadataRepository(),
|
||||
_intClass = _typeFlowAnalysis.environment.coreTypes.intClass {
|
||||
component.addMetadataRepository(_inferredTypeMetadata);
|
||||
|
|
|
@ -261,6 +261,48 @@ int findOverlap(List list, List sublist) {
|
|||
return list.length;
|
||||
}
|
||||
|
||||
/// A Union-Find data structure over integers.
|
||||
class UnionFind {
|
||||
// Negative weight if root, parent index otherwise.
|
||||
final List<int> _elements;
|
||||
|
||||
UnionFind([int initialSize = 0])
|
||||
: _elements = List<int>.filled(initialSize, -1, growable: true);
|
||||
|
||||
/// Add a new singleton set.
|
||||
int add() {
|
||||
int id = _elements.length;
|
||||
_elements.add(-1);
|
||||
return id;
|
||||
}
|
||||
|
||||
/// Find the canonical element for the set containing the given element.
|
||||
/// Two elements belonging to the same set have the same canonical element.
|
||||
int find(int id) {
|
||||
return _elements[id] < 0 ? id : _elements[id] = find(_elements[id]);
|
||||
}
|
||||
|
||||
/// Merge the sets containing the given elements.
|
||||
void union(int id1, int id2) {
|
||||
id1 = find(id1);
|
||||
id2 = find(id2);
|
||||
if (id1 == id2) return;
|
||||
final int w1 = _elements[id1];
|
||||
final int w2 = _elements[id2];
|
||||
assertx(w1 < 0 && w2 < 0);
|
||||
if (w1 < w2) {
|
||||
_elements[id1] += w2;
|
||||
_elements[id2] = id1;
|
||||
} else {
|
||||
_elements[id2] += w1;
|
||||
_elements[id1] = id2;
|
||||
}
|
||||
}
|
||||
|
||||
/// Total number of elements in the sets.
|
||||
int get size => _elements.length;
|
||||
}
|
||||
|
||||
const nullabilitySuffix = {
|
||||
Nullability.legacy: '*',
|
||||
Nullability.nullable: '?',
|
||||
|
|
|
@ -52,13 +52,13 @@ class DeepCaller2 extends core::Object {
|
|||
synthetic constructor •() → self::DeepCaller2*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method barL1([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method barL1([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
|
||||
return [@vm.direct-call.metadata=#lib::DeepCaller2.barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(dd);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL2([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method barL2([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
|
||||
return [@vm.direct-call.metadata=#lib::DeepCaller2.barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(dd);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL3([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method barL3([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
|
||||
return [@vm.direct-call.metadata=#lib::DeepCaller2.barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(dd);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method barL4([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method barL4([@vm.inferred-type.metadata=#lib::D] self::D* dd) → dynamic
|
||||
return [@vm.direct-call.metadata=#lib::D.field2] [@vm.inferred-type.metadata=!] dd.{self::D::field2};
|
||||
}
|
||||
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
|
||||
|
|
|
@ -32,11 +32,11 @@ class B extends core::Object {
|
|||
synthetic constructor •() → self::B*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → dynamic
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method foo() → dynamic
|
||||
return new self::T1::•();
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method bar() → dynamic
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method bar() → dynamic
|
||||
return new self::T2::•();
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method bazz() → dynamic
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method bazz() → dynamic
|
||||
return new self::T3::•();
|
||||
}
|
||||
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
|
||||
|
|
|
@ -36,13 +36,13 @@ class DeepCaller2 extends core::Object {
|
|||
synthetic constructor •() → self::DeepCaller2*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method barL1([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] method barL1([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
|
||||
return [@vm.direct-call.metadata=#lib::DeepCaller2.barL2] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL2}(aa);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method barL2([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16] method barL2([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
|
||||
return [@vm.direct-call.metadata=#lib::DeepCaller2.barL3] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL3}(aa);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10] method barL3([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18] method barL3([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
|
||||
return [@vm.direct-call.metadata=#lib::DeepCaller2.barL4] [@vm.inferred-type.metadata=! (skip check)] this.{self::DeepCaller2::barL4}(aa);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method barL4([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20] method barL4([@vm.inferred-type.metadata=#lib::A?] self::A* aa) → dynamic
|
||||
return [@vm.direct-call.metadata=#lib::A.field2??] [@vm.inferred-type.metadata=!] aa.{self::A::field2};
|
||||
}
|
||||
[@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
|
||||
|
|
|
@ -104,7 +104,7 @@ class H extends core::Object {
|
|||
synthetic constructor •() → self::H*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo({[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic left = #C1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic right = #C1}) → dynamic
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8,getterSelectorId:9] method foo({[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic left = #C1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic right = #C1}) → dynamic
|
||||
return new self::T6::•();
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] method noSuchMethod(core::Invocation* invocation) → dynamic {
|
||||
return new self::T7::•();
|
||||
|
|
|
@ -55,20 +55,20 @@ class FooKeep extends pro::GeneratedMessage {
|
|||
@#C10
|
||||
static method create() → self::FooKeep*
|
||||
return new self::FooKeep::_();
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4] @#C12
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] @#C12
|
||||
get barKeep() → self::BarKeep*
|
||||
return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getN] [@vm.inferred-type.metadata=foo.pb.dart::BarKeep? (skip check)] this.{pro::GeneratedMessage::$_getN}<self::BarKeep*>(0);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5] @#C12
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] @#C12
|
||||
set barKeep([@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep* v) → void {
|
||||
[@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(1, v);
|
||||
}
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:6] @#C14
|
||||
get mapKeep() → core::Map<core::String*, self::BarKeep*>*
|
||||
return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::BarKeep*>(2);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:7] @#C16
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] @#C16
|
||||
get aKeep() → core::int*
|
||||
return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(4);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8] @#C16
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] @#C16
|
||||
set aKeep([@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int* v) → void {
|
||||
[@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(4, v);
|
||||
}
|
||||
|
@ -95,10 +95,10 @@ class BarKeep extends pro::GeneratedMessage {
|
|||
@#C10
|
||||
static method create() → self::BarKeep*
|
||||
return new self::BarKeep::_();
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:7] @#C12
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] @#C12
|
||||
get aKeep() → core::int*
|
||||
return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(0);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8] @#C12
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] @#C12
|
||||
set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int* v) → void {
|
||||
[@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ class BarKeep extends pro::GeneratedMessage {
|
|||
@#C11
|
||||
static method create() → self::BarKeep*
|
||||
return new self::BarKeep::_();
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:7] @#C13
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:12] @#C13
|
||||
get aKeep() → core::int*
|
||||
return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(0);
|
||||
}
|
||||
|
|
|
@ -101,11 +101,11 @@ class BarKeep extends pro::GeneratedMessage {
|
|||
@#C11
|
||||
static method create() → self::BarKeep*
|
||||
return new self::BarKeep::_();
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6] @#C13
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9] @#C13
|
||||
set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int* v) → void {
|
||||
[@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
|
||||
}
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9] @#C25
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:10] @#C25
|
||||
set bDrop([@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] core::int* v) → void {
|
||||
[@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(1, v);
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ class ZopDrop extends pro::GeneratedMessage {
|
|||
@#C11
|
||||
static method create() → self::ZopDrop*
|
||||
return new self::ZopDrop::_();
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:10] @#C13
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11] @#C13
|
||||
set aDrop([@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] core::int* v) → void {
|
||||
[@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
|
||||
}
|
||||
|
|
|
@ -59,20 +59,20 @@ class FooKeep extends pro::GeneratedMessage {
|
|||
@#C10
|
||||
static method create() → self::FooKeep*
|
||||
return new self::FooKeep::_();
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4] @#C12
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] @#C12
|
||||
get barKeep() → self::BarKeep*
|
||||
return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getN] [@vm.inferred-type.metadata=foo.pb.dart::BarKeep? (skip check)] this.{pro::GeneratedMessage::$_getN}<self::BarKeep*>(0);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5] @#C12
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] @#C12
|
||||
set barKeep([@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep* v) → void {
|
||||
[@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(1, v);
|
||||
}
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:6] @#C14
|
||||
get mapKeep() → core::Map<core::String*, self::BarKeep*>*
|
||||
return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::BarKeep*>(2);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:7] @#C16
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] @#C16
|
||||
get aKeep() → core::int*
|
||||
return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(4);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8] @#C16
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] @#C16
|
||||
set aKeep([@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int* v) → void {
|
||||
[@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(4, v);
|
||||
}
|
||||
|
@ -99,10 +99,10 @@ class BarKeep extends pro::GeneratedMessage {
|
|||
@#C10
|
||||
static method create() → self::BarKeep*
|
||||
return new self::BarKeep::_();
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:7] @#C12
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] @#C12
|
||||
get aKeep() → core::int*
|
||||
return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(0);
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8] @#C12
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] @#C12
|
||||
set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int* v) → void {
|
||||
[@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
|
||||
}
|
||||
|
|
|
@ -38,27 +38,27 @@ class T2 extends core::Object {
|
|||
}
|
||||
}
|
||||
class A2 extends core::Object {
|
||||
[@vm.inferred-type.metadata=#lib::T2?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] field dynamic foo = null;
|
||||
[@vm.inferred-type.metadata=#lib::T2?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14] field dynamic foo = null;
|
||||
synthetic constructor •() → self::A2*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=#lib::T2?] dynamic a6 = #C1]) → void {
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=#lib::T2?] dynamic a6 = #C1]) → void {
|
||||
[@vm.direct-call.metadata=#lib::A2.foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A2::foo} = a6;
|
||||
}
|
||||
}
|
||||
abstract class B2Base extends core::Object {
|
||||
[@vm.inferred-type.metadata=#lib::A2] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:12,getterSelectorId:13] field dynamic _aa = new self::A2::•();
|
||||
[@vm.inferred-type.metadata=#lib::A2] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:16,getterSelectorId:17] field dynamic _aa = new self::A2::•();
|
||||
synthetic constructor •() → self::B2Base*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:11] get aa2() → dynamic
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:15] get aa2() → dynamic
|
||||
return [@vm.direct-call.metadata=#lib::B2Base._aa] [@vm.inferred-type.metadata=#lib::A2] this.{self::B2Base::_aa};
|
||||
}
|
||||
class B2 extends self::B2Base {
|
||||
synthetic constructor •() → self::B2*
|
||||
: super self::B2Base::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:14,getterSelectorId:15] method doSuperCall() → void {
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:18,getterSelectorId:19] method doSuperCall() → void {
|
||||
[@vm.call-site-attributes.metadata=receiverType:dynamic] [@vm.direct-call.metadata=#lib::A2.call] [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.inferred-type.metadata=#lib::A2] super.{self::B2Base::aa2}.call(1, 2, 3, 4, 5, new self::T2::•());
|
||||
}
|
||||
}
|
||||
|
@ -66,21 +66,21 @@ class T3 extends core::Object {
|
|||
synthetic constructor •() → self::T3*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:16,getterSelectorId:17] method doTest3() → void {
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:20,getterSelectorId:21] method doTest3() → void {
|
||||
self::ok = true;
|
||||
}
|
||||
}
|
||||
class A3 extends core::Object {
|
||||
[@vm.inferred-type.metadata=#lib::T3?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] field dynamic foo = null;
|
||||
[@vm.inferred-type.metadata=#lib::T3?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:24,getterSelectorId:25] field dynamic foo = null;
|
||||
synthetic constructor •() → self::A3*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=#lib::T3?] dynamic a7 = #C1]) → void {
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:22,getterSelectorId:23] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=#lib::T3?] dynamic a7 = #C1]) → void {
|
||||
[@vm.direct-call.metadata=#lib::A3.foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A3::foo} = a7;
|
||||
}
|
||||
}
|
||||
class B3 extends core::Object {
|
||||
[@vm.inferred-type.metadata=#lib::A3] [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:18,getterSelectorId:19] field self::A3* aa3 = new self::A3::•();
|
||||
[@vm.inferred-type.metadata=#lib::A3] [@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:26,getterSelectorId:27] field self::A3* aa3 = new self::A3::•();
|
||||
synthetic constructor •() → self::B3*
|
||||
: super core::Object::•()
|
||||
;
|
||||
|
@ -89,25 +89,25 @@ class T4 extends core::Object {
|
|||
synthetic constructor •() → self::T4*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:20,getterSelectorId:21] method doTest4() → void {
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:28,getterSelectorId:29] method doTest4() → void {
|
||||
self::ok = true;
|
||||
}
|
||||
}
|
||||
class A4 extends core::Object {
|
||||
[@vm.inferred-type.metadata=#lib::T4?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] field dynamic foo = null;
|
||||
[@vm.inferred-type.metadata=#lib::T4?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:32,getterSelectorId:33] field dynamic foo = null;
|
||||
synthetic constructor •() → self::A4*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a7 = #C1, [@vm.inferred-type.metadata=#lib::T4?] dynamic a8 = #C1]) → void {
|
||||
[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:30,getterSelectorId:31] method call([dynamic a1 = #C1, dynamic a2 = #C1, dynamic a3 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a5 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a6 = #C1, [@vm.inferred-type.metadata=dart.core::_Smi?] dynamic a7 = #C1, [@vm.inferred-type.metadata=#lib::T4?] dynamic a8 = #C1]) → void {
|
||||
[@vm.direct-call.metadata=#lib::A4.foo] [@vm.inferred-type.metadata=!? (skip check)] this.{self::A4::foo} = a8;
|
||||
}
|
||||
}
|
||||
class B4 extends core::Object {
|
||||
[@vm.inferred-type.metadata=#lib::A4] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:12,getterSelectorId:13] field dynamic _aa = new self::A4::•();
|
||||
[@vm.inferred-type.metadata=#lib::A4] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:35,getterSelectorId:36] field dynamic _aa = new self::A4::•();
|
||||
synthetic constructor •() → self::B4*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,getterSelectorId:22] get aa4() → dynamic
|
||||
[@vm.procedure-attributes.metadata=hasThisUses:false,hasTearOffUses:false,getterSelectorId:34] get aa4() → dynamic
|
||||
return [@vm.direct-call.metadata=#lib::B4._aa] [@vm.inferred-type.metadata=#lib::A4] this.{self::B4::_aa};
|
||||
}
|
||||
[@vm.inferred-type.metadata=dart.core::bool?]static field core::bool* ok;
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Validate the partitioning of methods for selector ID assignment.
|
||||
// Two members should get the same selector ID(s) iff they have the same name
|
||||
// and are defined in classes with the same number.
|
||||
|
||||
class X {}
|
||||
|
||||
class A1 {
|
||||
void foo() {
|
||||
print("A1");
|
||||
}
|
||||
}
|
||||
|
||||
class B1 extends A1 {}
|
||||
|
||||
class C1 extends B1 {
|
||||
void foo() {
|
||||
print("C1");
|
||||
}
|
||||
}
|
||||
|
||||
class A2 {
|
||||
void foo() {
|
||||
print("A2");
|
||||
}
|
||||
}
|
||||
|
||||
class B2 extends A2 implements X {
|
||||
void foo() {
|
||||
print("B2");
|
||||
}
|
||||
}
|
||||
|
||||
abstract class A3 {
|
||||
void foo();
|
||||
}
|
||||
|
||||
class B3 extends A3 implements X {
|
||||
void foo() {
|
||||
print("B3");
|
||||
}
|
||||
}
|
||||
|
||||
class C3 implements A3 {
|
||||
void foo() {
|
||||
print("C3");
|
||||
}
|
||||
}
|
||||
|
||||
class A4 {
|
||||
void foo() {
|
||||
print("A4");
|
||||
}
|
||||
}
|
||||
|
||||
class B4 {
|
||||
void foo() {
|
||||
print("B4");
|
||||
}
|
||||
}
|
||||
|
||||
class C4 {
|
||||
void foo() {
|
||||
print("C4");
|
||||
}
|
||||
}
|
||||
|
||||
class D4 extends A4 implements B4 {
|
||||
void foo() {
|
||||
print("D4");
|
||||
}
|
||||
}
|
||||
|
||||
class E4 extends C4 implements B4 {}
|
||||
|
||||
main() {
|
||||
List<A1> x1 = [A1(), B1(), C1()];
|
||||
for (A1 o in x1) o.foo();
|
||||
List<A2> x2 = [A2(), B2()];
|
||||
for (A2 o in x2) o.foo();
|
||||
List<A3> x3 = [B3(), C3()];
|
||||
for (A3 o in x3) o.foo();
|
||||
List<A4> x4 = [A4(), D4()];
|
||||
for (A4 o in x4) o.foo();
|
||||
List<B4> y4 = [B4(), D4(), E4()];
|
||||
for (B4 o in y4) o.foo();
|
||||
List<C4> z4 = [C4(), E4()];
|
||||
for (C4 o in z4) o.foo();
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
library #lib;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
abstract class X extends core::Object {
|
||||
}
|
||||
class A1 extends core::Object {
|
||||
synthetic constructor •() → self::A1*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → void {
|
||||
core::print("A1");
|
||||
}
|
||||
}
|
||||
class B1 extends self::A1 {
|
||||
synthetic constructor •() → self::B1*
|
||||
: super self::A1::•()
|
||||
;
|
||||
}
|
||||
class C1 extends self::B1 {
|
||||
synthetic constructor •() → self::C1*
|
||||
: super self::B1::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → void {
|
||||
core::print("C1");
|
||||
}
|
||||
}
|
||||
class A2 extends core::Object {
|
||||
synthetic constructor •() → self::A2*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method foo() → void {
|
||||
core::print("A2");
|
||||
}
|
||||
}
|
||||
class B2 extends self::A2 implements self::X {
|
||||
synthetic constructor •() → self::B2*
|
||||
: super self::A2::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method foo() → void {
|
||||
core::print("B2");
|
||||
}
|
||||
}
|
||||
abstract class A3 extends core::Object {
|
||||
synthetic constructor •() → self::A3*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] abstract method foo() → void;
|
||||
}
|
||||
class B3 extends self::A3 implements self::X {
|
||||
synthetic constructor •() → self::B3*
|
||||
: super self::A3::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method foo() → void {
|
||||
core::print("B3");
|
||||
}
|
||||
}
|
||||
class C3 extends core::Object implements self::A3 {
|
||||
synthetic constructor •() → self::C3*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method foo() → void {
|
||||
core::print("C3");
|
||||
}
|
||||
}
|
||||
class A4 extends core::Object {
|
||||
synthetic constructor •() → self::A4*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method foo() → void {
|
||||
core::print("A4");
|
||||
}
|
||||
}
|
||||
class B4 extends core::Object {
|
||||
synthetic constructor •() → self::B4*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method foo() → void {
|
||||
core::print("B4");
|
||||
}
|
||||
}
|
||||
class C4 extends core::Object {
|
||||
synthetic constructor •() → self::C4*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method foo() → void {
|
||||
core::print("C4");
|
||||
}
|
||||
}
|
||||
class D4 extends self::A4 implements self::B4 {
|
||||
synthetic constructor •() → self::D4*
|
||||
: super self::A4::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method foo() → void {
|
||||
core::print("D4");
|
||||
}
|
||||
}
|
||||
class E4 extends self::C4 implements self::B4 {
|
||||
synthetic constructor •() → self::E4*
|
||||
: super self::C4::•()
|
||||
;
|
||||
}
|
||||
static method main() → dynamic {
|
||||
core::List<self::A1*>* x1 = <self::A1*>[new self::A1::•(), new self::B1::•(), new self::C1::•()];
|
||||
{
|
||||
core::Iterator<self::A1*>* :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::A1*>] x1.{core::Iterable::iterator};
|
||||
for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
|
||||
self::A1* o = [@vm.direct-call.metadata=dart._internal::ListIterator.current] :sync-for-iterator.{core::Iterator::current};
|
||||
o.{self::A1::foo}();
|
||||
}
|
||||
}
|
||||
core::List<self::A2*>* x2 = <self::A2*>[new self::A2::•(), new self::B2::•()];
|
||||
{
|
||||
core::Iterator<self::A2*>* :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::A2*>] x2.{core::Iterable::iterator};
|
||||
for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
|
||||
self::A2* o = [@vm.direct-call.metadata=dart._internal::ListIterator.current] :sync-for-iterator.{core::Iterator::current};
|
||||
o.{self::A2::foo}();
|
||||
}
|
||||
}
|
||||
core::List<self::A3*>* x3 = <self::A3*>[new self::B3::•(), new self::C3::•()];
|
||||
{
|
||||
core::Iterator<self::A3*>* :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::A3*>] x3.{core::Iterable::iterator};
|
||||
for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
|
||||
self::A3* o = [@vm.direct-call.metadata=dart._internal::ListIterator.current] :sync-for-iterator.{core::Iterator::current};
|
||||
o.{self::A3::foo}();
|
||||
}
|
||||
}
|
||||
core::List<self::A4*>* x4 = <self::A4*>[new self::A4::•(), new self::D4::•()];
|
||||
{
|
||||
core::Iterator<self::A4*>* :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::A4*>] x4.{core::Iterable::iterator};
|
||||
for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
|
||||
self::A4* o = [@vm.direct-call.metadata=dart._internal::ListIterator.current] :sync-for-iterator.{core::Iterator::current};
|
||||
o.{self::A4::foo}();
|
||||
}
|
||||
}
|
||||
core::List<self::B4*>* y4 = <self::B4*>[new self::B4::•(), new self::D4::•(), new self::E4::•()];
|
||||
{
|
||||
core::Iterator<self::B4*>* :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::B4*>] y4.{core::Iterable::iterator};
|
||||
for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
|
||||
self::B4* o = [@vm.direct-call.metadata=dart._internal::ListIterator.current] :sync-for-iterator.{core::Iterator::current};
|
||||
o.{self::B4::foo}();
|
||||
}
|
||||
}
|
||||
core::List<self::C4*>* z4 = <self::C4*>[new self::C4::•(), new self::E4::•()];
|
||||
{
|
||||
core::Iterator<self::C4*>* :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::C4*>] z4.{core::Iterable::iterator};
|
||||
for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
|
||||
self::C4* o = [@vm.direct-call.metadata=dart._internal::ListIterator.current] :sync-for-iterator.{core::Iterator::current};
|
||||
[@vm.direct-call.metadata=#lib::C4.foo??] [@vm.inferred-type.metadata=!? (skip check)] o.{self::C4::foo}();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,16 +20,16 @@ abstract class Base extends core::Object {
|
|||
synthetic constructor •() → self::Base*
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method foo() → core::int*
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method foo() → core::int*
|
||||
return _in::unsafeCast<core::int*>([@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] 3.{core::num::+}(_in::unsafeCast<core::num>([@vm.direct-call.metadata=#lib::B.foo] [@vm.inferred-type.metadata=int? (receiver not int)] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo())));
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] method doCall(dynamic x) → core::int*
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method doCall(dynamic x) → core::int*
|
||||
return [@vm.call-site-attributes.metadata=receiverType:dynamic] x.call() as{TypeError,ForDynamic} core::int*;
|
||||
}
|
||||
class TearOffSuperMethod extends self::Base {
|
||||
synthetic constructor •() → self::TearOffSuperMethod*
|
||||
: super self::Base::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] method bar() → core::int*
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] method bar() → core::int*
|
||||
return [@vm.direct-call.metadata=#lib::Base.doCall] [@vm.inferred-type.metadata=int? (skip check)] this.{self::Base::doCall}(super.{self::Base::foo});
|
||||
}
|
||||
[@vm.inferred-type.metadata=#lib::B?]static field self::A* aa = new self::B::•();
|
||||
|
|
|
@ -12,11 +12,11 @@ class A extends core::Object {
|
|||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3] set /*isNullableByDefault*/ x(core::int value) → void;
|
||||
}
|
||||
class B extends core::Object {
|
||||
[@vm.inferred-type.metadata=dart.core::_Smi?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] late final [setter] field core::int x;
|
||||
[@vm.inferred-type.metadata=dart.core::_Smi?] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7] late final [setter] field core::int x;
|
||||
synthetic constructor •() → self::B
|
||||
: super core::Object::•()
|
||||
;
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] method use() → dynamic {
|
||||
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] method use() → dynamic {
|
||||
[@vm.direct-call.metadata=#lib::B.x] [@vm.inferred-type.metadata=!? (skip check)] this.{self::B::x} = 3;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue