Files
sdk/pkg/vm/testcases/bytecode/instance_creation.dart.expect
T
Alexander Markov feff33b892 [vm/kernel/bytecode] Implement overlapping of type arguments in bytecode
Instantiator type arguments are sometimes reused instead of doing
instantiation at run time. VM has a bunch of assertions to verify
that this optimization happened. In case of bytecode pipeline, decision
to reuse instantiator type arguments is done while generating bytecode.

For this optimization to correctly happen, bytecode generator
should be able to construct instantiator type arguments the same way
as VM does at run time. Besides flattening of type arguments of
superclasses, VM shrinks them by overlapping type parameters with
type arguments of a superclass (if they match). This CL implements
such overlapping in bytecode generator.

Also, --overlap_type_arguments VM option is removed, as disabling
of type arguments overlapping would break bytecode pipeline.

Change-Id: Ib276c0e688e0e86b44278d88a5c0af09dd342798
Reviewed-on: https://dart-review.googlesource.com/70060
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
2018-08-14 21:51:17 +00:00

624 lines
16 KiB
Plaintext

library #lib;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
class Base<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic> extends core::Object {
generic-covariant-impl field self::Base::T1 t1 = null;
generic-covariant-impl field self::Base::T2 t2 = null;
[@vm.bytecode=
Bytecode {
Entry 1
CheckStack
Push FP[-5]
PushConstant CP#1
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
PushConstant CP#3
CreateArrayTOS
StoreLocal r0
Push r0
PushConstant CP#4
PushConstant CP#5
StoreIndexedTOS
Push r0
PushConstant CP#6
Push FP[-5]
LoadTypeArgumentsField CP#8
PushConstant CP#2
InstantiateType CP#7
StoreIndexedTOS
Push r0
PushConstant CP#9
PushConstant CP#10
StoreIndexedTOS
Push r0
PushConstant CP#11
Push FP[-5]
LoadTypeArgumentsField CP#8
PushConstant CP#2
InstantiateType CP#12
StoreIndexedTOS
PushConstant CP#13
IndirectStaticCall 1, CP#0
PushConstant CP#14
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
ReturnTOS
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
[1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
[2] = Null
[3] = Int 4
[4] = Int 0
[5] = String 'Base: '
[6] = Int 1
[7] = Type #lib::Base::T1
[8] = TypeArgumentsField #lib::Base
[9] = Int 2
[10] = String ', '
[11] = Int 3
[12] = Type #lib::Base::T2
[13] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
[14] = StaticICData target 'dart.core::print', arg-desc CP#0
}
] constructor •() → void
: super core::Object::•() {
core::print("Base: ${self::Base::T1}, ${self::Base::T2}");
}
}
class A extends self::Base<core::int, core::String> {
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
Push FP[-6]
PushConstant CP#1
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
ReturnTOS
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
[1] = StaticICData target '#lib::Base::', arg-desc CP#0
[2] = Null
}
] constructor •(core::String s) → void
: super self::Base::•()
;
}
class B<T extends core::Object = dynamic> extends self::Base<core::List<self::B::T>, core::String> {
[@vm.bytecode=
Bytecode {
Entry 1
CheckStack
Push FP[-5]
PushConstant CP#1
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
PushConstant CP#3
CreateArrayTOS
StoreLocal r0
Push r0
PushConstant CP#4
PushConstant CP#5
StoreIndexedTOS
Push r0
PushConstant CP#6
Push FP[-5]
LoadTypeArgumentsField CP#8
PushConstant CP#2
InstantiateType CP#7
StoreIndexedTOS
PushConstant CP#9
IndirectStaticCall 1, CP#0
PushConstant CP#10
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
ReturnTOS
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
[1] = StaticICData target '#lib::Base::', arg-desc CP#0
[2] = Null
[3] = Int 2
[4] = Int 0
[5] = String 'B: '
[6] = Int 1
[7] = Type #lib::B::T
[8] = TypeArgumentsField #lib::B
[9] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
[10] = StaticICData target 'dart.core::print', arg-desc CP#0
}
] constructor •() → void
: super self::Base::•() {
core::print("B: ${self::B::T}");
}
}
class C extends core::Object {
[@vm.bytecode=
Bytecode {
Entry 1
CheckStack
Push FP[-6]
PushConstant CP#1
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
PushConstant CP#3
CreateArrayTOS
StoreLocal r0
Push r0
PushConstant CP#4
PushConstant CP#5
StoreIndexedTOS
Push r0
PushConstant CP#6
Push FP[-5]
StoreIndexedTOS
PushConstant CP#7
IndirectStaticCall 1, CP#0
PushConstant CP#8
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
ReturnTOS
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
[1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
[2] = Null
[3] = Int 2
[4] = Int 0
[5] = String 'C: '
[6] = Int 1
[7] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
[8] = StaticICData target 'dart.core::print', arg-desc CP#0
}
] constructor •(core::String s) → void
: super core::Object::•() {
core::print("C: ${s}");
}
}
class E<K extends core::Object = dynamic, V extends core::Object = dynamic> extends core::Object {
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
Push FP[-5]
PushConstant CP#1
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
ReturnTOS
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
[1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
[2] = Null
}
] synthetic constructor •() → void
: super core::Object::•()
;
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
Push FP[-5]
LoadTypeArgumentsField CP#0
PushConstant CP#2
IndirectStaticCall 1, CP#1
ReturnTOS
PushConstant CP#3
ReturnTOS
}
ConstantPool {
[0] = TypeArgumentsField #lib::E
[1] = ArgDesc num-args 1, num-type-args 0, names []
[2] = StaticICData target 'dart.core::Map::', arg-desc CP#1
[3] = Null
}
] method test_reuse1() → dynamic
return core::Map::•<self::E::K, self::E::V>();
}
class F<K extends core::Object = dynamic, V extends core::Object = dynamic> extends self::E<core::String, core::List<self::F::V>> {
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
Push FP[-5]
PushConstant CP#1
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
ReturnTOS
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
[1] = StaticICData target '#lib::E::', arg-desc CP#0
[2] = Null
}
] synthetic constructor •() → void
: super self::E::•()
;
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
Push FP[-5]
LoadTypeArgumentsField CP#0
PushConstant CP#2
IndirectStaticCall 1, CP#1
ReturnTOS
PushConstant CP#3
ReturnTOS
}
ConstantPool {
[0] = TypeArgumentsField #lib::F
[1] = ArgDesc num-args 1, num-type-args 0, names []
[2] = StaticICData target 'dart.core::Map::', arg-desc CP#1
[3] = Null
}
] method test_reuse2() → dynamic
return core::Map::•<core::String, core::List<self::F::V>>();
}
class G<K extends core::Object = dynamic, V extends core::Object = dynamic> extends core::Object {
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
Push FP[-5]
PushConstant CP#1
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
ReturnTOS
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
[1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
[2] = Null
}
] constructor •() → void
: super core::Object::•()
;
[@vm.bytecode=
Bytecode {
Entry 1
CheckStack
Push FP[-5]
PushConstant CP#1
InstantiateTypeArgumentsTOS 0, CP#2
PushConstant CP#0
AllocateT
StoreLocal r0
Push r0
PushConstant CP#4
IndirectStaticCall 1, CP#3
Drop1
ReturnTOS
PushConstant CP#1
ReturnTOS
}
ConstantPool {
[0] = Class #lib::H
[1] = Null
[2] = TypeArgumentsForInstanceAllocation #lib::H [dart.core::String, #lib::G::test_factory::K, #lib::G::test_factory::V]
[3] = ArgDesc num-args 1, num-type-args 0, names []
[4] = StaticICData target '#lib::H::', arg-desc CP#3
}
] static factory test_factory<K extends core::Object = dynamic, V extends core::Object = dynamic>() → self::G<self::G::test_factory::K, self::G::test_factory::V>
return new self::H::•<core::String, self::G::test_factory::K, self::G::test_factory::V>();
}
class H<P1 extends core::Object = dynamic, P2 extends core::Object = dynamic, P3 extends core::Object = dynamic> extends self::G<self::H::P2, self::H::P3> {
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
Push FP[-5]
PushConstant CP#1
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
ReturnTOS
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
[1] = StaticICData target '#lib::G::', arg-desc CP#0
[2] = Null
}
] synthetic constructor •() → void
: super self::G::•()
;
}
class I extends core::Object {
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
Push FP[-6]
PushConstant CP#1
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
ReturnTOS
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
[1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
[2] = Null
}
] constructor •(dynamic param) → void
: super core::Object::•()
;
[@vm.bytecode=
Bytecode {
EntryOptional 1, 0, 1
LoadConstant r1, CP#0
LoadConstant r1, CP#1
Frame 1
CheckStack
Allocate CP#2
StoreLocal r2
Push r2
Push r1
PushConstant CP#4
IndirectStaticCall 2, CP#3
Drop1
ReturnTOS
PushConstant CP#1
ReturnTOS
}
ConstantPool {
[0] = String 'param'
[1] = Null
[2] = Class #lib::I
[3] = ArgDesc num-args 2, num-type-args 0, names []
[4] = StaticICData target '#lib::I::', arg-desc CP#3
}
] static factory test_factory2({dynamic param = null}) → self::I
return new self::I::•(param);
}
class J extends core::Object {
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
Push FP[-5]
NativeCall CP#0
ReturnTOS
}
ConstantPool {
[0] = NativeEntry agent_J
}
] @_in::ExternalName::•("agent_J")
external static factory •() → self::J;
}
abstract class K<A extends core::Object = dynamic, B extends core::Object = dynamic> extends core::Object {
[@vm.bytecode=
Bytecode {
Entry 1
CheckStack
Push FP[-5]
PushConstant CP#0
AllocateT
StoreLocal r0
Push r0
PushConstant CP#2
IndirectStaticCall 1, CP#1
Drop1
ReturnTOS
PushConstant CP#3
ReturnTOS
}
ConstantPool {
[0] = Class #lib::TestTypeArgReuse
[1] = ArgDesc num-args 1, num-type-args 0, names []
[2] = StaticICData target '#lib::TestTypeArgReuse::', arg-desc CP#1
[3] = Null
}
] static factory •<A extends core::Object = dynamic, B extends core::Object = dynamic>() → self::K<self::K::•::A, self::K::•::B>
return new self::TestTypeArgReuse::•<self::K::•::A, self::K::•::B>();
}
class TestTypeArgReuse<P extends core::Object = dynamic, Q extends core::Object = dynamic> extends self::Base<self::TestTypeArgReuse::P, self::TestTypeArgReuse::Q> implements self::K<self::TestTypeArgReuse::P, self::TestTypeArgReuse::Q> {
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
Push FP[-5]
PushConstant CP#1
IndirectStaticCall 1, CP#0
Drop1
PushConstant CP#2
ReturnTOS
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
[1] = StaticICData target '#lib::Base::', arg-desc CP#0
[2] = Null
}
] synthetic constructor •() → void
: super self::Base::•()
;
}
[@vm.bytecode=
Bytecode {
Entry 1
CheckStack
Allocate CP#0
StoreLocal r0
Push r0
PushConstant CP#1
PushConstant CP#3
IndirectStaticCall 2, CP#2
Drop1
ReturnTOS
PushConstant CP#4
ReturnTOS
}
ConstantPool {
[0] = Class #lib::C
[1] = String 'hello'
[2] = ArgDesc num-args 2, num-type-args 0, names []
[3] = StaticICData target '#lib::C::', arg-desc CP#2
[4] = Null
}
]static method foo1() → dynamic
return new self::C::•("hello");
[@vm.bytecode=
Bytecode {
Entry 1
CheckStack
PushConstant CP#1
PushConstant CP#0
AllocateT
StoreLocal r0
Push r0
PushConstant CP#2
PushConstant CP#4
IndirectStaticCall 2, CP#3
Drop1
Drop1
PushConstant CP#6
PushConstant CP#5
AllocateT
StoreLocal r0
Push r0
PushConstant CP#8
IndirectStaticCall 1, CP#7
Drop1
Drop1
PushConstant CP#9
ReturnTOS
}
ConstantPool {
[0] = Class #lib::A
[1] = TypeArgumentsForInstanceAllocation #lib::A []
[2] = String 'hi'
[3] = ArgDesc num-args 2, num-type-args 0, names []
[4] = StaticICData target '#lib::A::', arg-desc CP#3
[5] = Class #lib::B
[6] = TypeArgumentsForInstanceAllocation #lib::B [dart.core::int]
[7] = ArgDesc num-args 1, num-type-args 0, names []
[8] = StaticICData target '#lib::B::', arg-desc CP#7
[9] = Null
}
]static method foo2() → void {
new self::A::•("hi");
new self::B::•<core::int>();
}
[@vm.bytecode=
Bytecode {
Entry 2
CheckStack
CheckFunctionTypeArgs 1, 0
PushConstant CP#1
Push r0
InstantiateTypeArgumentsTOS 0, CP#2
PushConstant CP#0
AllocateT
StoreLocal r1
Push r1
PushConstant CP#4
IndirectStaticCall 1, CP#3
Drop1
Drop1
PushConstant CP#1
ReturnTOS
}
ConstantPool {
[0] = Class #lib::B
[1] = Null
[2] = TypeArgumentsForInstanceAllocation #lib::B [dart.core::List<#lib::foo3::T>]
[3] = ArgDesc num-args 1, num-type-args 0, names []
[4] = StaticICData target '#lib::B::', arg-desc CP#3
}
]static method foo3<T extends core::Object = dynamic>() → void {
new self::B::•<core::List<self::foo3::T>>();
}
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
PushConstant CP#0
PushConstant CP#2
IndirectStaticCall 1, CP#1
Drop1
PushConstant CP#3
ReturnTOS
}
ConstantPool {
[0] = TypeArgumentsForInstanceAllocation #lib::G [dart.core::int, dart.core::List<dart.core::String>]
[1] = ArgDesc num-args 1, num-type-args 0, names []
[2] = StaticICData target '#lib::G::test_factory', arg-desc CP#1
[3] = Null
}
]static method foo4() → void {
self::G::test_factory<core::int, core::List<core::String>>();
}
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
PushConstant CP#0
PushConstant CP#2
IndirectStaticCall 1, CP#1
Drop1
PushConstant CP#0
PushConstant CP#3
PushConstant CP#5
IndirectStaticCall 2, CP#4
Drop1
PushConstant CP#0
ReturnTOS
}
ConstantPool {
[0] = Null
[1] = ArgDesc num-args 1, num-type-args 0, names []
[2] = StaticICData target '#lib::I::test_factory2', arg-desc CP#1
[3] = Int 42
[4] = ArgDesc num-args 2, num-type-args 0, names [param]
[5] = StaticICData target '#lib::I::test_factory2', arg-desc CP#4
}
]static method foo5() → void {
self::I::test_factory2();
self::I::test_factory2(param: 42);
}
[@vm.bytecode=
Bytecode {
Entry 0
CheckStack
PushConstant CP#1
IndirectStaticCall 0, CP#0
Drop1
PushConstant CP#2
IndirectStaticCall 0, CP#0
Drop1
PushConstant CP#3
PushConstant CP#5
IndirectStaticCall 1, CP#4
Drop1
PushConstant CP#6
ReturnTOS
}
ConstantPool {
[0] = ArgDesc num-args 0, num-type-args 0, names []
[1] = StaticICData target '#lib::foo1', arg-desc CP#0
[2] = StaticICData target '#lib::foo2', arg-desc CP#0
[3] = TypeArgs [dart.core::String]
[4] = ArgDesc num-args 0, num-type-args 1, names []
[5] = StaticICData target '#lib::foo3', arg-desc CP#4
[6] = Null
}
]static method main() → dynamic {
self::foo1();
self::foo2();
self::foo3<core::String>();
}