[vm/bytecode] Replace InstanceCall instruction with InterfaceCall and DynamicCall.
Dispatch interface calls via hashtable rather than inline cache.
InterfaceCall doesn't need to take arguments descriptor into account
when doing method lookup.
Change-Id: I30eae6ea638d1d2ad2cf3ff073c653fee3377f31
Reviewed-on: https://dart-review.googlesource.com/c/86106
Reviewed-by: Zach Anderson <zra@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index f937116..eaab503 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -271,9 +271,14 @@
emitWord(_encodeAD(Opcode.kIndirectStaticCall, ra, rd));
}
- void emitInstanceCall(int ra, int rd) {
+ void emitInterfaceCall(int ra, int rd) {
emitSourcePosition();
- emitWord(_encodeAD(Opcode.kInstanceCall, ra, rd));
+ emitWord(_encodeAD(Opcode.kInterfaceCall, ra, rd));
+ }
+
+ void emitDynamicCall(int ra, int rd) {
+ emitSourcePosition();
+ emitWord(_encodeAD(Opcode.kDynamicCall, ra, rd));
}
void emitNativeCall(int rd) {
diff --git a/pkg/vm/lib/bytecode/constant_pool.dart b/pkg/vm/lib/bytecode/constant_pool.dart
index fda38ee..e4c77c1 100644
--- a/pkg/vm/lib/bytecode/constant_pool.dart
+++ b/pkg/vm/lib/bytecode/constant_pool.dart
@@ -169,6 +169,15 @@
PackedObject name;
}
+// Occupies 2 entries in the constant pool.
+type ConstantInterfaceCall extends ConstantPoolEntry {
+ Byte tag = 26;
+ Byte flags(invocationKindBit0, invocationKindBit1);
+ // Where invocationKind is index into InvocationKind.
+ PackedObject targetName;
+ ConstantIndex argDesc;
+}
+
*/
enum ConstantTag {
@@ -198,6 +207,7 @@
kPartialTearOffInstantiation,
kEmptyTypeArguments,
kSymbol,
+ kInterfaceCall,
}
abstract class ConstantPoolEntry {
@@ -271,6 +281,8 @@
return new ConstantEmptyTypeArguments.read(reader);
case ConstantTag.kSymbol:
return new ConstantSymbol.read(reader);
+ case ConstantTag.kInterfaceCall:
+ return new ConstantInterfaceCall.read(reader);
}
throw 'Unexpected constant tag $tag';
}
@@ -1071,6 +1083,50 @@
bool operator ==(other) => other is ConstantSymbol && this.name == other.name;
}
+class ConstantInterfaceCall extends ConstantPoolEntry {
+ final InvocationKind invocationKind;
+ final ObjectHandle targetName;
+ final int argDescConstantIndex;
+
+ ConstantInterfaceCall(
+ this.invocationKind, this.targetName, this.argDescConstantIndex);
+
+ // Reserve 1 extra slot for arguments descriptor, following target name slot.
+ int get numReservedEntries => 1;
+
+ @override
+ ConstantTag get tag => ConstantTag.kInterfaceCall;
+
+ @override
+ void writeValue(BufferedWriter writer) {
+ writer.writeByte(invocationKind.index);
+ writer.writePackedObject(targetName);
+ writer.writePackedUInt30(argDescConstantIndex);
+ }
+
+ ConstantInterfaceCall.read(BufferedReader reader)
+ : invocationKind = InvocationKind.values[reader.readByte()],
+ targetName = reader.readPackedObject(),
+ argDescConstantIndex = reader.readPackedUInt30();
+
+ @override
+ String toString() => 'InterfaceCall '
+ '${_invocationKindToString(invocationKind)}'
+ 'target-name \'$targetName\', arg-desc CP#$argDescConstantIndex';
+
+ @override
+ int get hashCode => _combineHashes(
+ _combineHashes(invocationKind.index, targetName.hashCode),
+ argDescConstantIndex);
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantInterfaceCall &&
+ this.invocationKind == other.invocationKind &&
+ this.targetName == other.targetName &&
+ this.argDescConstantIndex == other.argDescConstantIndex;
+}
+
/// Reserved constant pool entry.
class _ReservedConstantPoolEntry extends ConstantPoolEntry {
const _ReservedConstantPoolEntry();
@@ -1131,6 +1187,23 @@
isSetter: invocationKind == InvocationKind.setter),
argDescCpIndex));
+ int addInterfaceCall(
+ InvocationKind invocationKind, Name targetName, int argDescCpIndex) =>
+ _add(new ConstantInterfaceCall(
+ invocationKind,
+ objectTable.getSelectorNameHandle(targetName,
+ isGetter: invocationKind == InvocationKind.getter,
+ isSetter: invocationKind == InvocationKind.setter),
+ argDescCpIndex));
+
+ int addInstanceCall(
+ InvocationKind invocationKind, Name targetName, int argDescCpIndex,
+ {bool isDynamic: false}) =>
+ isDynamic
+ ? addICData(invocationKind, targetName, argDescCpIndex,
+ isDynamic: true)
+ : addInterfaceCall(invocationKind, targetName, argDescCpIndex);
+
int addStaticField(Field field) =>
_add(new ConstantStaticField(objectTable.getHandle(field)));
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 1092e14..6f7923a 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -82,7 +82,8 @@
// Calls.
kIndirectStaticCall,
- kInstanceCall,
+ kInterfaceCall,
+ kDynamicCall,
kNativeCall,
kReturnTOS,
@@ -235,7 +236,9 @@
Encoding.kT, const [Operand.tgt, Operand.none, Operand.none]),
Opcode.kIndirectStaticCall: const Format(
Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
- Opcode.kInstanceCall: const Format(
+ Opcode.kInterfaceCall: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+ Opcode.kDynamicCall: const Format(
Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
Opcode.kNativeCall: const Format(
Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
@@ -312,7 +315,8 @@
bool isCall(Opcode opcode) {
switch (opcode) {
case Opcode.kIndirectStaticCall:
- case Opcode.kInstanceCall:
+ case Opcode.kInterfaceCall:
+ case Opcode.kDynamicCall:
case Opcode.kNativeCall:
return true;
default:
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 6dd7960..7bd5dc3 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -772,9 +772,9 @@
assert(type.classNode.typeParameters.isEmpty);
asm.emitPushConstant(cp.addType(type));
final argDescIndex = cp.addArgDesc(2);
- final icdataIndex = cp.addICData(
+ final icdataIndex = cp.addInterfaceCall(
InvocationKind.method, objectSimpleInstanceOf.name, argDescIndex);
- asm.emitInstanceCall(2, icdataIndex);
+ asm.emitInterfaceCall(2, icdataIndex);
return;
}
@@ -786,9 +786,9 @@
}
asm.emitPushConstant(cp.addType(type));
final argDescIndex = cp.addArgDesc(4);
- final icdataIndex = cp.addICData(
+ final icdataIndex = cp.addInterfaceCall(
InvocationKind.method, objectInstanceOf.name, argDescIndex);
- asm.emitInstanceCall(4, icdataIndex);
+ asm.emitInterfaceCall(4, icdataIndex);
}
void start(Member node) {
@@ -1945,6 +1945,14 @@
asm.emitBytecode0(opcode);
}
+ void _genInstanceCall(int totalArgCount, int icdataCpIndex, bool isDynamic) {
+ if (isDynamic) {
+ asm.emitDynamicCall(totalArgCount, icdataCpIndex);
+ } else {
+ asm.emitInterfaceCall(totalArgCount, icdataCpIndex);
+ }
+ }
+
@override
visitMethodInvocation(MethodInvocation node) {
final Opcode opcode = recognizedMethods.specializedBytecodeFor(node);
@@ -1953,26 +1961,28 @@
return;
}
final args = node.arguments;
+ final isDynamic = node.interfaceTarget == null;
_genArguments(node.receiver, args);
final argDescIndex = cp.addArgDescByArguments(args, hasReceiver: true);
- final icdataIndex = cp.addICData(
+ final icdataIndex = cp.addInstanceCall(
InvocationKind.method, node.name, argDescIndex,
- isDynamic: node.interfaceTarget == null);
+ isDynamic: isDynamic);
final totalArgCount = args.positional.length +
args.named.length +
1 /* receiver */ +
(args.types.isNotEmpty ? 1 : 0) /* type arguments */;
- asm.emitInstanceCall(totalArgCount, icdataIndex);
+ _genInstanceCall(totalArgCount, icdataIndex, isDynamic);
}
@override
visitPropertyGet(PropertyGet node) {
_generateNode(node.receiver);
+ final isDynamic = node.interfaceTarget == null;
final argDescIndex = cp.addArgDesc(1);
- final icdataIndex = cp.addICData(
+ final icdataIndex = cp.addInstanceCall(
InvocationKind.getter, node.name, argDescIndex,
- isDynamic: node.interfaceTarget == null);
- asm.emitInstanceCall(1, icdataIndex);
+ isDynamic: isDynamic);
+ _genInstanceCall(1, icdataIndex, isDynamic);
}
@override
@@ -1987,11 +1997,12 @@
asm.emitStoreLocal(temp);
}
+ final isDynamic = node.interfaceTarget == null;
final argDescIndex = cp.addArgDesc(2);
- final icdataIndex = cp.addICData(
+ final icdataIndex = cp.addInstanceCall(
InvocationKind.setter, node.name, argDescIndex,
- isDynamic: node.interfaceTarget == null);
- asm.emitInstanceCall(2, icdataIndex);
+ isDynamic: isDynamic);
+ _genInstanceCall(2, icdataIndex, isDynamic);
asm.emitDrop1();
if (hasResult) {
@@ -2402,9 +2413,11 @@
const kMoveNext = 'moveNext'; // Iterator.moveNext
const kCurrent = 'current'; // Iterator.current
- asm.emitInstanceCall(
+ // Front-end inserts implicit cast (type check) which ensures that
+ // result of iterable expression is Iterable<dynamic>.
+ asm.emitInterfaceCall(
1,
- cp.addICData(
+ cp.addInterfaceCall(
InvocationKind.getter, new Name(kIterator), cp.addArgDesc(1)));
final iteratorTemp = locals.tempIndexInFrame(node);
@@ -2436,9 +2449,9 @@
asm.emitPush(iteratorTemp);
}
- asm.emitInstanceCall(
+ asm.emitInterfaceCall(
1,
- cp.addICData(
+ cp.addInterfaceCall(
InvocationKind.method, new Name(kMoveNext), cp.addArgDesc(1)));
_genJumpIfFalse(/* negated = */ false, done);
@@ -2447,9 +2460,9 @@
_genPushContextIfCaptured(node.variable);
asm.emitPush(iteratorTemp);
- asm.emitInstanceCall(
+ asm.emitInterfaceCall(
1,
- cp.addICData(
+ cp.addInterfaceCall(
InvocationKind.getter, new Name(kCurrent), cp.addArgDesc(1)));
_genStoreVar(node.variable);
@@ -2606,9 +2619,9 @@
for (var expr in switchCase.expressions) {
asm.emitPush(temp);
_genPushConstExpr(expr);
- asm.emitInstanceCall(
+ asm.emitInterfaceCall(
2,
- cp.addICData(
+ cp.addInterfaceCall(
InvocationKind.method, new Name('=='), equalsArgDesc));
_genJumpIfTrue(/* negated = */ false, caseLabel);
}
diff --git a/pkg/vm/testcases/bytecode/asserts.dart.expect b/pkg/vm/testcases/bytecode/asserts.dart.expect
index a7706b7..575ae5f 100644
--- a/pkg/vm/testcases/bytecode/asserts.dart.expect
+++ b/pkg/vm/testcases/bytecode/asserts.dart.expect
@@ -33,13 +33,13 @@
CheckStack 0
JumpIfNoAsserts L1
Push FP[-6]
- InstanceCall 1, CP#1
+ DynamicCall 1, CP#1
AssertBoolean 0
JumpIfTrue L1
PushInt 0
PushInt 0
Push FP[-5]
- InstanceCall 1, CP#2
+ DynamicCall 1, CP#2
PushConstant CP#4
IndirectStaticCall 3, CP#3
Drop1
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index db9690f..dc84539 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -7,20 +7,20 @@
Bytecode {
Entry 3
CheckStack 0
- Allocate CP#19
+ Allocate CP#20
StoreLocal r2
Push r2
PushNull
- StoreFieldTOS CP#20
+ StoreFieldTOS CP#21
Push r2
PushNull
- StoreFieldTOS CP#22
+ StoreFieldTOS CP#23
Push r2
- PushConstant CP#24
- StoreFieldTOS CP#25
+ PushConstant CP#25
+ StoreFieldTOS CP#26
Push r2
PushConstant CP#0
- StoreFieldTOS CP#27
+ StoreFieldTOS CP#28
Push r2
Push r0
StoreFieldTOS CP#1
@@ -44,25 +44,27 @@
[14] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#13
[15] = Type dynamic
[16] = ArgDesc num-args 3, num-type-args 0, names []
- [17] = ICData target-name 'completeError', arg-desc CP#16
- [18] = EndClosureFunctionScope
- [19] = Class dart:core::_Closure
- [20] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
- [21] = Reserved
- [22] = InstanceField dart:core::_Closure::_function_type_arguments (field)
- [23] = Reserved
- [24] = EmptyTypeArguments
- [25] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
- [26] = Reserved
- [27] = InstanceField dart:core::_Closure::_function (field)
- [28] = Reserved
- [29] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#7
- [30] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#7
- [31] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#7
- [32] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
- [33] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#13
- [34] = ICData get target-name 'get:future', arg-desc CP#7
- [35] = EndClosureFunctionScope
+ [17] = InterfaceCall target-name 'completeError', arg-desc CP#16
+ [18] = Reserved
+ [19] = EndClosureFunctionScope
+ [20] = Class dart:core::_Closure
+ [21] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+ [22] = Reserved
+ [23] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+ [24] = Reserved
+ [25] = EmptyTypeArguments
+ [26] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+ [27] = Reserved
+ [28] = InstanceField dart:core::_Closure::_function (field)
+ [29] = Reserved
+ [30] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#7
+ [31] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#7
+ [32] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#7
+ [33] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
+ [34] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#13
+ [35] = InterfaceCall get target-name 'get:future', arg-desc CP#7
+ [36] = Reserved
+ [37] = EndClosureFunctionScope
}
Closure #lib::asyncInFieldInitializer (field)::<anonymous closure> (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null >
ClosureBytecode {
@@ -109,50 +111,50 @@
PushNull
StoreContextVar 0, 7
Push r0
- Allocate CP#19
+ Allocate CP#20
StoreLocal r3
Push r3
PushNull
- StoreFieldTOS CP#20
+ StoreFieldTOS CP#21
Push r3
PushNull
- StoreFieldTOS CP#22
+ StoreFieldTOS CP#23
Push r3
- PushConstant CP#24
- StoreFieldTOS CP#25
+ PushConstant CP#25
+ StoreFieldTOS CP#26
Push r3
PushConstant CP#9
- StoreFieldTOS CP#27
+ StoreFieldTOS CP#28
Push r3
Push r0
StoreFieldTOS CP#1
StoreContextVar 0, 8
Push r0
LoadContextVar 0, 8
- PushConstant CP#29
+ PushConstant CP#30
IndirectStaticCall 1, CP#7
PopLocal r2
Push r0
Push r0
LoadContextVar 0, 8
- PushConstant CP#30
+ PushConstant CP#31
IndirectStaticCall 1, CP#7
StoreContextVar 0, 3
Push r0
Push r0
LoadContextVar 0, 8
- PushConstant CP#31
+ PushConstant CP#32
IndirectStaticCall 1, CP#7
StoreContextVar 0, 4
- PushConstant CP#32
+ PushConstant CP#33
Push r0
LoadContextVar 0, 8
- PushConstant CP#33
+ PushConstant CP#34
IndirectStaticCall 2, CP#13
Drop1
Push r0
LoadContextVar 0, 1
- InstanceCall 1, CP#34
+ InterfaceCall 1, CP#35
ReturnTOS
}
@@ -233,7 +235,7 @@
LoadContextVar 0, 1
Push r8
Push r9
- InstanceCall 3, CP#17
+ InterfaceCall 3, CP#17
Drop1
Jump L3
L3:
@@ -300,44 +302,44 @@
Push r0
PushNull
StoreContextVar 0, 3
- Allocate CP#13
+ Allocate CP#14
StoreLocal r6
Push r6
PushNull
- StoreFieldTOS CP#14
+ StoreFieldTOS CP#15
Push r6
PushNull
- StoreFieldTOS CP#16
+ StoreFieldTOS CP#17
Push r6
- PushConstant CP#18
- StoreFieldTOS CP#19
+ PushConstant CP#19
+ StoreFieldTOS CP#20
Push r6
PushConstant CP#3
- StoreFieldTOS CP#21
+ StoreFieldTOS CP#22
Push r6
Push r0
StoreFieldTOS CP#5
PopLocal r5
Push r5
- PushConstant CP#23
+ PushConstant CP#24
IndirectStaticCall 1, CP#1
PopLocal r2
Push r5
- PushConstant CP#24
+ PushConstant CP#25
IndirectStaticCall 1, CP#1
PopLocal r3
Push r5
- PushConstant CP#25
+ PushConstant CP#26
IndirectStaticCall 1, CP#1
PopLocal r4
- PushConstant CP#26
- Push r5
PushConstant CP#27
+ Push r5
+ PushConstant CP#28
IndirectStaticCall 2, CP#7
Drop1
Push r0
LoadContextVar 0, 0
- InstanceCall 1, CP#28
+ InterfaceCall 1, CP#29
ReturnTOS
}
ConstantPool {
@@ -352,24 +354,26 @@
[8] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#7
[9] = Type dynamic
[10] = ArgDesc num-args 3, num-type-args 0, names []
- [11] = ICData target-name 'completeError', arg-desc CP#10
- [12] = EndClosureFunctionScope
- [13] = Class dart:core::_Closure
- [14] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
- [15] = Reserved
- [16] = InstanceField dart:core::_Closure::_function_type_arguments (field)
- [17] = Reserved
- [18] = EmptyTypeArguments
- [19] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
- [20] = Reserved
- [21] = InstanceField dart:core::_Closure::_function (field)
- [22] = Reserved
- [23] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#1
- [24] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#1
- [25] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#1
- [26] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
- [27] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#7
- [28] = ICData get target-name 'get:future', arg-desc CP#1
+ [11] = InterfaceCall target-name 'completeError', arg-desc CP#10
+ [12] = Reserved
+ [13] = EndClosureFunctionScope
+ [14] = Class dart:core::_Closure
+ [15] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+ [16] = Reserved
+ [17] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+ [18] = Reserved
+ [19] = EmptyTypeArguments
+ [20] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+ [21] = Reserved
+ [22] = InstanceField dart:core::_Closure::_function (field)
+ [23] = Reserved
+ [24] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#1
+ [25] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#1
+ [26] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#1
+ [27] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
+ [28] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#7
+ [29] = InterfaceCall get target-name 'get:future', arg-desc CP#1
+ [30] = Reserved
}
Closure #lib::foo:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
ClosureBytecode {
@@ -419,7 +423,7 @@
LoadContextVar 0, 0
Push r8
Push r9
- InstanceCall 3, CP#11
+ InterfaceCall 3, CP#11
Drop1
Jump L3
L3:
@@ -497,50 +501,50 @@
PushNull
StoreContextVar 0, 9
Push r0
- Allocate CP#17
+ Allocate CP#19
StoreLocal r3
Push r3
PushNull
- StoreFieldTOS CP#18
- Push r3
- PushNull
StoreFieldTOS CP#20
Push r3
- PushConstant CP#22
- StoreFieldTOS CP#23
+ PushNull
+ StoreFieldTOS CP#22
+ Push r3
+ PushConstant CP#24
+ StoreFieldTOS CP#25
Push r3
PushConstant CP#3
- StoreFieldTOS CP#25
+ StoreFieldTOS CP#27
Push r3
Push r0
StoreFieldTOS CP#5
StoreContextVar 0, 10
Push r0
LoadContextVar 0, 10
- PushConstant CP#27
+ PushConstant CP#29
IndirectStaticCall 1, CP#1
PopLocal r2
Push r0
Push r0
LoadContextVar 0, 10
- PushConstant CP#28
+ PushConstant CP#30
IndirectStaticCall 1, CP#1
StoreContextVar 0, 4
Push r0
Push r0
LoadContextVar 0, 10
- PushConstant CP#29
+ PushConstant CP#31
IndirectStaticCall 1, CP#1
StoreContextVar 0, 5
- PushConstant CP#30
+ PushConstant CP#32
Push r0
LoadContextVar 0, 10
- PushConstant CP#31
+ PushConstant CP#33
IndirectStaticCall 2, CP#10
Drop1
Push r0
LoadContextVar 0, 2
- InstanceCall 1, CP#32
+ InterfaceCall 1, CP#34
ReturnTOS
}
ConstantPool {
@@ -555,28 +559,31 @@
[8] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#7
[9] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#7
[10] = ArgDesc num-args 2, num-type-args 0, names []
- [11] = ICData target-name '+', arg-desc CP#10
- [12] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#10
- [13] = Type dynamic
- [14] = ArgDesc num-args 3, num-type-args 0, names []
- [15] = ICData target-name 'completeError', arg-desc CP#14
- [16] = EndClosureFunctionScope
- [17] = Class dart:core::_Closure
- [18] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
- [19] = Reserved
- [20] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+ [11] = InterfaceCall target-name '+', arg-desc CP#10
+ [12] = Reserved
+ [13] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#10
+ [14] = Type dynamic
+ [15] = ArgDesc num-args 3, num-type-args 0, names []
+ [16] = InterfaceCall target-name 'completeError', arg-desc CP#15
+ [17] = Reserved
+ [18] = EndClosureFunctionScope
+ [19] = Class dart:core::_Closure
+ [20] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
[21] = Reserved
- [22] = EmptyTypeArguments
- [23] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
- [24] = Reserved
- [25] = InstanceField dart:core::_Closure::_function (field)
+ [22] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+ [23] = Reserved
+ [24] = EmptyTypeArguments
+ [25] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
[26] = Reserved
- [27] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#1
- [28] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#1
- [29] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#1
- [30] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
- [31] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#10
- [32] = ICData get target-name 'get:future', arg-desc CP#1
+ [27] = InstanceField dart:core::_Closure::_function (field)
+ [28] = Reserved
+ [29] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#1
+ [30] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#1
+ [31] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#1
+ [32] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
+ [33] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#10
+ [34] = InterfaceCall get target-name 'get:future', arg-desc CP#1
+ [35] = Reserved
}
Closure #lib::simpleAsyncAwait:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
ClosureBytecode {
@@ -657,7 +664,7 @@
Push r4
LoadContextVar 0, 9
Push r1
- InstanceCall 2, CP#11
+ InterfaceCall 2, CP#11
StoreContextVar 0, 3
Jump L4
L4:
@@ -665,7 +672,7 @@
LoadContextVar 0, 2
Push r4
LoadContextVar 0, 3
- PushConstant CP#12
+ PushConstant CP#13
IndirectStaticCall 2, CP#10
Drop1
PushNull
@@ -689,7 +696,7 @@
LoadContextVar 0, 2
Push r8
Push r9
- InstanceCall 3, CP#15
+ InterfaceCall 3, CP#16
Drop1
Jump L5
L5:
@@ -778,50 +785,50 @@
PushNull
StoreContextVar 0, 9
Push r0
- Allocate CP#22
+ Allocate CP#26
StoreLocal r3
Push r3
PushNull
- StoreFieldTOS CP#23
+ StoreFieldTOS CP#27
Push r3
PushNull
- StoreFieldTOS CP#25
+ StoreFieldTOS CP#29
Push r3
- PushConstant CP#27
- StoreFieldTOS CP#28
+ PushConstant CP#31
+ StoreFieldTOS CP#32
Push r3
PushConstant CP#3
- StoreFieldTOS CP#30
+ StoreFieldTOS CP#34
Push r3
Push r0
StoreFieldTOS CP#5
StoreContextVar 0, 10
Push r0
LoadContextVar 0, 10
- PushConstant CP#32
+ PushConstant CP#36
IndirectStaticCall 1, CP#1
PopLocal r2
Push r0
Push r0
LoadContextVar 0, 10
- PushConstant CP#33
+ PushConstant CP#37
IndirectStaticCall 1, CP#1
StoreContextVar 0, 3
Push r0
Push r0
LoadContextVar 0, 10
- PushConstant CP#34
+ PushConstant CP#38
IndirectStaticCall 1, CP#1
StoreContextVar 0, 4
- PushConstant CP#35
+ PushConstant CP#39
Push r0
LoadContextVar 0, 10
- PushConstant CP#36
- IndirectStaticCall 2, CP#14
+ PushConstant CP#40
+ IndirectStaticCall 2, CP#17
Drop1
Push r0
LoadContextVar 0, 1
- InstanceCall 1, CP#37
+ InterfaceCall 1, CP#41
ReturnTOS
}
ConstantPool {
@@ -832,37 +839,42 @@
[4] = Null
[5] = InstanceField dart:core::_Closure::_context (field)
[6] = Reserved
- [7] = ICData get target-name 'get:iterator', arg-desc CP#1
- [8] = ICData target-name 'moveNext', arg-desc CP#1
- [9] = ICData get target-name 'get:current', arg-desc CP#1
- [10] = ArgDesc num-args 0, num-type-args 0, names []
- [11] = StaticICData target '#lib::foo', arg-desc CP#10
- [12] = ArgDesc num-args 4, num-type-args 0, names []
- [13] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#12
- [14] = ArgDesc num-args 2, num-type-args 0, names []
- [15] = ICData target-name '+', arg-desc CP#14
- [16] = ICData target-name '+', arg-desc CP#14
- [17] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#14
- [18] = Type dynamic
- [19] = ArgDesc num-args 3, num-type-args 0, names []
- [20] = ICData target-name 'completeError', arg-desc CP#19
- [21] = EndClosureFunctionScope
- [22] = Class dart:core::_Closure
- [23] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+ [7] = InterfaceCall get target-name 'get:iterator', arg-desc CP#1
+ [8] = Reserved
+ [9] = InterfaceCall target-name 'moveNext', arg-desc CP#1
+ [10] = Reserved
+ [11] = InterfaceCall get target-name 'get:current', arg-desc CP#1
+ [12] = Reserved
+ [13] = ArgDesc num-args 0, num-type-args 0, names []
+ [14] = StaticICData target '#lib::foo', arg-desc CP#13
+ [15] = ArgDesc num-args 4, num-type-args 0, names []
+ [16] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#15
+ [17] = ArgDesc num-args 2, num-type-args 0, names []
+ [18] = InterfaceCall target-name '+', arg-desc CP#17
+ [19] = Reserved
+ [20] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#17
+ [21] = Type dynamic
+ [22] = ArgDesc num-args 3, num-type-args 0, names []
+ [23] = InterfaceCall target-name 'completeError', arg-desc CP#22
[24] = Reserved
- [25] = InstanceField dart:core::_Closure::_function_type_arguments (field)
- [26] = Reserved
- [27] = EmptyTypeArguments
- [28] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
- [29] = Reserved
- [30] = InstanceField dart:core::_Closure::_function (field)
- [31] = Reserved
- [32] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#1
- [33] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#1
- [34] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#1
- [35] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
- [36] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#14
- [37] = ICData get target-name 'get:future', arg-desc CP#1
+ [25] = EndClosureFunctionScope
+ [26] = Class dart:core::_Closure
+ [27] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+ [28] = Reserved
+ [29] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+ [30] = Reserved
+ [31] = EmptyTypeArguments
+ [32] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+ [33] = Reserved
+ [34] = InstanceField dart:core::_Closure::_function (field)
+ [35] = Reserved
+ [36] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#1
+ [37] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#1
+ [38] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#1
+ [39] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
+ [40] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#17
+ [41] = InterfaceCall get target-name 'get:future', arg-desc CP#1
+ [42] = Reserved
}
Closure #lib::loops:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
ClosureBytecode {
@@ -913,7 +925,7 @@
LoadContextParent
LoadContextParent
LoadContextVar 0, 0
- InstanceCall 1, CP#7
+ InterfaceCall 1, CP#7
PopLocal r8
Push r4
Push r8
@@ -923,7 +935,7 @@
Push r4
LoadContextVar 2, 1
StoreLocal r8
- InstanceCall 1, CP#8
+ InterfaceCall 1, CP#9
JumpIfFalse L3
AllocateContext 3, 1
StoreLocal r5
@@ -933,7 +945,7 @@
PopLocal r4
Push r4
Push r8
- InstanceCall 1, CP#9
+ InterfaceCall 1, CP#11
StoreContextVar 3, 0
Push r4
LoadContextParent
@@ -967,8 +979,8 @@
LoadContextParent
Push r4
StoreContextVar 0, 6
- PushConstant CP#11
- IndirectStaticCall 0, CP#10
+ PushConstant CP#14
+ IndirectStaticCall 0, CP#13
Push r4
LoadContextParent
LoadContextParent
@@ -984,8 +996,8 @@
LoadContextParent
LoadContextParent
LoadContextVar 0, 10
- PushConstant CP#13
- IndirectStaticCall 4, CP#12
+ PushConstant CP#16
+ IndirectStaticCall 4, CP#15
PopLocal r10
PushNull
ReturnTOS
@@ -1010,8 +1022,8 @@
LoadContextParent
LoadContextVar 0, 8
Push r1
- InstanceCall 2, CP#15
- InstanceCall 2, CP#16
+ InterfaceCall 2, CP#18
+ InterfaceCall 2, CP#18
StoreContextVar 1, 0
Push r4
LoadContextParent
@@ -1070,8 +1082,8 @@
LoadContextVar 0, 1
Push r4
LoadContextVar 0, 2
- PushConstant CP#17
- IndirectStaticCall 2, CP#14
+ PushConstant CP#20
+ IndirectStaticCall 2, CP#17
Drop1
PushNull
ReturnTOS
@@ -1094,7 +1106,7 @@
LoadContextVar 0, 1
Push r8
Push r9
- InstanceCall 3, CP#20
+ InterfaceCall 3, CP#23
Drop1
Jump L10
L10:
@@ -1205,50 +1217,50 @@
PushNull
StoreContextVar 0, 14
Push r0
- Allocate CP#30
+ Allocate CP#29
StoreLocal r3
Push r3
PushNull
- StoreFieldTOS CP#31
+ StoreFieldTOS CP#30
Push r3
PushNull
- StoreFieldTOS CP#33
+ StoreFieldTOS CP#32
Push r3
- PushConstant CP#35
- StoreFieldTOS CP#36
+ PushConstant CP#34
+ StoreFieldTOS CP#35
Push r3
PushConstant CP#3
- StoreFieldTOS CP#38
+ StoreFieldTOS CP#37
Push r3
Push r0
StoreFieldTOS CP#5
StoreContextVar 0, 15
Push r0
LoadContextVar 0, 15
- PushConstant CP#40
+ PushConstant CP#39
IndirectStaticCall 1, CP#1
PopLocal r2
Push r0
Push r0
LoadContextVar 0, 15
- PushConstant CP#41
+ PushConstant CP#40
IndirectStaticCall 1, CP#1
StoreContextVar 0, 5
Push r0
Push r0
LoadContextVar 0, 15
- PushConstant CP#42
+ PushConstant CP#41
IndirectStaticCall 1, CP#1
StoreContextVar 0, 6
- PushConstant CP#43
+ PushConstant CP#42
Push r0
LoadContextVar 0, 15
- PushConstant CP#44
+ PushConstant CP#43
IndirectStaticCall 2, CP#9
Drop1
Push r0
LoadContextVar 0, 3
- InstanceCall 1, CP#45
+ InterfaceCall 1, CP#44
ReturnTOS
}
ConstantPool {
@@ -1262,42 +1274,42 @@
[7] = ArgDesc num-args 4, num-type-args 0, names []
[8] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#7
[9] = ArgDesc num-args 2, num-type-args 0, names []
- [10] = ICData target-name '+', arg-desc CP#9
- [11] = Type dynamic
- [12] = Type dart:core::Error
- [13] = ICData target-name '_simpleInstanceOf', arg-desc CP#9
- [14] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#7
- [15] = ICData target-name '+', arg-desc CP#9
- [16] = String 'fin'
- [17] = StaticICData target 'dart:core::print', arg-desc CP#1
- [18] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#7
- [19] = ICData target-name '+', arg-desc CP#9
+ [10] = InterfaceCall target-name '+', arg-desc CP#9
+ [11] = Reserved
+ [12] = Type dynamic
+ [13] = Type dart:core::Error
+ [14] = InterfaceCall target-name '_simpleInstanceOf', arg-desc CP#9
+ [15] = Reserved
+ [16] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#7
+ [17] = String 'fin'
+ [18] = StaticICData target 'dart:core::print', arg-desc CP#1
+ [19] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#7
[20] = StaticICData target 'dart:core::print', arg-desc CP#1
[21] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#7
- [22] = ICData target-name '+', arg-desc CP#9
- [23] = StaticICData target 'dart:core::print', arg-desc CP#1
- [24] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#7
- [25] = ICData target-name '+', arg-desc CP#9
- [26] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#9
- [27] = ArgDesc num-args 3, num-type-args 0, names []
- [28] = ICData target-name 'completeError', arg-desc CP#27
- [29] = EndClosureFunctionScope
- [30] = Class dart:core::_Closure
- [31] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
- [32] = Reserved
- [33] = InstanceField dart:core::_Closure::_function_type_arguments (field)
- [34] = Reserved
- [35] = EmptyTypeArguments
- [36] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
- [37] = Reserved
- [38] = InstanceField dart:core::_Closure::_function (field)
- [39] = Reserved
- [40] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#1
- [41] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#1
- [42] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#1
- [43] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
- [44] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#9
- [45] = ICData get target-name 'get:future', arg-desc CP#1
+ [22] = StaticICData target 'dart:core::print', arg-desc CP#1
+ [23] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#7
+ [24] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#9
+ [25] = ArgDesc num-args 3, num-type-args 0, names []
+ [26] = InterfaceCall target-name 'completeError', arg-desc CP#25
+ [27] = Reserved
+ [28] = EndClosureFunctionScope
+ [29] = Class dart:core::_Closure
+ [30] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+ [31] = Reserved
+ [32] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+ [33] = Reserved
+ [34] = EmptyTypeArguments
+ [35] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+ [36] = Reserved
+ [37] = InstanceField dart:core::_Closure::_function (field)
+ [38] = Reserved
+ [39] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#1
+ [40] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#1
+ [41] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#1
+ [42] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
+ [43] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#9
+ [44] = InterfaceCall get target-name 'get:future', arg-desc CP#1
+ [45] = Reserved
}
Closure #lib::tryCatchRethrow:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
ClosureBytecode {
@@ -1380,7 +1392,7 @@
LoadContextParent
LoadContextVar 0, 14
Push r1
- InstanceCall 2, CP#10
+ InterfaceCall 2, CP#10
StoreContextVar 1, 0
Jump L3
Try #2 end:
@@ -1407,8 +1419,8 @@
StoreContextVar 1, 1
Push r4
LoadContextVar 1, 1
- PushConstant CP#12
- InstanceCall 2, CP#13
+ PushConstant CP#13
+ InterfaceCall 2, CP#14
JumpIfFalse L4
Push r4
LoadContextParent
@@ -1441,7 +1453,7 @@
Push r4
LoadContextParent
LoadContextVar 0, 15
- PushConstant CP#14
+ PushConstant CP#16
IndirectStaticCall 4, CP#7
PopLocal r13
PushNull
@@ -1458,7 +1470,7 @@
LoadContextParent
LoadContextVar 0, 14
Push r1
- InstanceCall 2, CP#15
+ InterfaceCall 2, CP#10
StoreContextVar 1, 0
Push r4
LoadContextParent
@@ -1488,8 +1500,8 @@
LoadContextParent
Push r9
StoreContextVar 0, 13
- PushConstant CP#16
PushConstant CP#17
+ PushConstant CP#18
IndirectStaticCall 1, CP#1
Drop1
Push r4
@@ -1517,7 +1529,7 @@
Push r4
LoadContextParent
LoadContextVar 0, 15
- PushConstant CP#18
+ PushConstant CP#19
IndirectStaticCall 4, CP#7
PopLocal r12
PushNull
@@ -1534,7 +1546,7 @@
LoadContextParent
LoadContextVar 0, 14
Push r1
- InstanceCall 2, CP#19
+ InterfaceCall 2, CP#10
StoreContextVar 1, 0
Push r4
LoadContextParent
@@ -1552,7 +1564,7 @@
Push r4
LoadContextVar 0, 10
PopLocal r4
- PushConstant CP#16
+ PushConstant CP#17
PushConstant CP#20
IndirectStaticCall 1, CP#1
Drop1
@@ -1598,7 +1610,7 @@
LoadContextParent
LoadContextVar 0, 14
Push r1
- InstanceCall 2, CP#22
+ InterfaceCall 2, CP#10
StoreContextVar 1, 0
Push r4
LoadContextParent
@@ -1616,8 +1628,8 @@
Push r4
LoadContextVar 0, 10
PopLocal r4
- PushConstant CP#16
- PushConstant CP#23
+ PushConstant CP#17
+ PushConstant CP#22
IndirectStaticCall 1, CP#1
Drop1
Push r4
@@ -1645,7 +1657,7 @@
Push r4
LoadContextParent
LoadContextVar 0, 15
- PushConstant CP#24
+ PushConstant CP#23
IndirectStaticCall 4, CP#7
PopLocal r12
PushNull
@@ -1662,7 +1674,7 @@
LoadContextParent
LoadContextVar 0, 14
Push r1
- InstanceCall 2, CP#25
+ InterfaceCall 2, CP#10
StoreContextVar 1, 0
Push r4
LoadContextParent
@@ -1678,7 +1690,7 @@
LoadContextVar 0, 3
Push r4
LoadContextVar 0, 4
- PushConstant CP#26
+ PushConstant CP#24
IndirectStaticCall 2, CP#9
Drop1
PushNull
@@ -1702,7 +1714,7 @@
LoadContextVar 0, 3
Push r8
Push r9
- InstanceCall 3, CP#28
+ InterfaceCall 3, CP#26
Drop1
Jump L12
L12:
@@ -1795,20 +1807,20 @@
Push r0
PushInt 3
StoreContextVar 0, 1
- Allocate CP#19
+ Allocate CP#20
StoreLocal r3
Push r3
PushNull
- StoreFieldTOS CP#20
+ StoreFieldTOS CP#21
Push r3
PushNull
- StoreFieldTOS CP#22
+ StoreFieldTOS CP#23
Push r3
- PushConstant CP#24
- StoreFieldTOS CP#25
+ PushConstant CP#25
+ StoreFieldTOS CP#26
Push r3
PushConstant CP#0
- StoreFieldTOS CP#27
+ StoreFieldTOS CP#28
Push r3
Push r0
StoreFieldTOS CP#1
@@ -1834,25 +1846,27 @@
[14] = ArgDesc num-args 2, num-type-args 0, names []
[15] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#14
[16] = ArgDesc num-args 3, num-type-args 0, names []
- [17] = ICData target-name 'completeError', arg-desc CP#16
- [18] = EndClosureFunctionScope
- [19] = Class dart:core::_Closure
- [20] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
- [21] = Reserved
- [22] = InstanceField dart:core::_Closure::_function_type_arguments (field)
- [23] = Reserved
- [24] = EmptyTypeArguments
- [25] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
- [26] = Reserved
- [27] = InstanceField dart:core::_Closure::_function (field)
- [28] = Reserved
- [29] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#4
- [30] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#4
- [31] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#4
- [32] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
- [33] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#14
- [34] = ICData get target-name 'get:future', arg-desc CP#4
- [35] = EndClosureFunctionScope
+ [17] = InterfaceCall target-name 'completeError', arg-desc CP#16
+ [18] = Reserved
+ [19] = EndClosureFunctionScope
+ [20] = Class dart:core::_Closure
+ [21] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+ [22] = Reserved
+ [23] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+ [24] = Reserved
+ [25] = EmptyTypeArguments
+ [26] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+ [27] = Reserved
+ [28] = InstanceField dart:core::_Closure::_function (field)
+ [29] = Reserved
+ [30] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#4
+ [31] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#4
+ [32] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#4
+ [33] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
+ [34] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#14
+ [35] = InterfaceCall get target-name 'get:future', arg-desc CP#4
+ [36] = Reserved
+ [37] = EndClosureFunctionScope
}
Closure #lib::closure::nested () -> dart:async::Future < dart:core::int >
ClosureBytecode {
@@ -1896,50 +1910,50 @@
PushNull
StoreContextVar 1, 7
Push r0
- Allocate CP#19
+ Allocate CP#20
StoreLocal r3
Push r3
PushNull
- StoreFieldTOS CP#20
+ StoreFieldTOS CP#21
Push r3
PushNull
- StoreFieldTOS CP#22
+ StoreFieldTOS CP#23
Push r3
- PushConstant CP#24
- StoreFieldTOS CP#25
+ PushConstant CP#25
+ StoreFieldTOS CP#26
Push r3
PushConstant CP#6
- StoreFieldTOS CP#27
+ StoreFieldTOS CP#28
Push r3
Push r0
StoreFieldTOS CP#1
StoreContextVar 1, 8
Push r0
LoadContextVar 1, 8
- PushConstant CP#29
+ PushConstant CP#30
IndirectStaticCall 1, CP#4
PopLocal r2
Push r0
Push r0
LoadContextVar 1, 8
- PushConstant CP#30
+ PushConstant CP#31
IndirectStaticCall 1, CP#4
StoreContextVar 1, 2
Push r0
Push r0
LoadContextVar 1, 8
- PushConstant CP#31
+ PushConstant CP#32
IndirectStaticCall 1, CP#4
StoreContextVar 1, 3
- PushConstant CP#32
+ PushConstant CP#33
Push r0
LoadContextVar 1, 8
- PushConstant CP#33
+ PushConstant CP#34
IndirectStaticCall 2, CP#14
Drop1
Push r0
LoadContextVar 1, 0
- InstanceCall 1, CP#34
+ InterfaceCall 1, CP#35
ReturnTOS
}
@@ -2092,7 +2106,7 @@
LoadContextVar 1, 0
Push r8
Push r9
- InstanceCall 3, CP#17
+ InterfaceCall 3, CP#17
Drop1
Jump L5
L5:
@@ -2182,50 +2196,50 @@
PushNull
StoreContextVar 0, 7
Push r0
- Allocate CP#17
+ Allocate CP#19
StoreLocal r3
Push r3
PushNull
- StoreFieldTOS CP#18
- Push r3
- PushNull
StoreFieldTOS CP#20
Push r3
- PushConstant CP#22
- StoreFieldTOS CP#23
+ PushNull
+ StoreFieldTOS CP#22
+ Push r3
+ PushConstant CP#24
+ StoreFieldTOS CP#25
Push r3
PushConstant CP#3
- StoreFieldTOS CP#25
+ StoreFieldTOS CP#27
Push r3
Push r0
StoreFieldTOS CP#5
StoreContextVar 0, 8
Push r0
LoadContextVar 0, 8
- PushConstant CP#27
+ PushConstant CP#29
IndirectStaticCall 1, CP#1
PopLocal r2
Push r0
Push r0
LoadContextVar 0, 8
- PushConstant CP#28
+ PushConstant CP#30
IndirectStaticCall 1, CP#1
StoreContextVar 0, 3
Push r0
Push r0
LoadContextVar 0, 8
- PushConstant CP#29
+ PushConstant CP#31
IndirectStaticCall 1, CP#1
StoreContextVar 0, 4
- PushConstant CP#30
+ PushConstant CP#32
Push r0
LoadContextVar 0, 8
- PushConstant CP#31
+ PushConstant CP#33
IndirectStaticCall 2, CP#9
Drop1
Push r0
LoadContextVar 0, 1
- InstanceCall 1, CP#32
+ InterfaceCall 1, CP#34
ReturnTOS
}
ConstantPool {
@@ -2239,29 +2253,32 @@
[7] = ArgDesc num-args 4, num-type-args 0, names []
[8] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#7
[9] = ArgDesc num-args 2, num-type-args 0, names []
- [10] = ICData target-name '==', arg-desc CP#9
- [11] = ArgDesc num-args 3, num-type-args 0, names []
- [12] = StaticICData target 'dart:core::_AssertionError::_throwNew', arg-desc CP#11
- [13] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#9
- [14] = Type dynamic
- [15] = ICData target-name 'completeError', arg-desc CP#11
- [16] = EndClosureFunctionScope
- [17] = Class dart:core::_Closure
- [18] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
- [19] = Reserved
- [20] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+ [10] = InterfaceCall target-name '==', arg-desc CP#9
+ [11] = Reserved
+ [12] = ArgDesc num-args 3, num-type-args 0, names []
+ [13] = StaticICData target 'dart:core::_AssertionError::_throwNew', arg-desc CP#12
+ [14] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#9
+ [15] = Type dynamic
+ [16] = InterfaceCall target-name 'completeError', arg-desc CP#12
+ [17] = Reserved
+ [18] = EndClosureFunctionScope
+ [19] = Class dart:core::_Closure
+ [20] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
[21] = Reserved
- [22] = EmptyTypeArguments
- [23] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
- [24] = Reserved
- [25] = InstanceField dart:core::_Closure::_function (field)
+ [22] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+ [23] = Reserved
+ [24] = EmptyTypeArguments
+ [25] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
[26] = Reserved
- [27] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#1
- [28] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#1
- [29] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#1
- [30] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
- [31] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#9
- [32] = ICData get target-name 'get:future', arg-desc CP#1
+ [27] = InstanceField dart:core::_Closure::_function (field)
+ [28] = Reserved
+ [29] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#1
+ [30] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#1
+ [31] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#1
+ [32] = TypeArgumentsForInstanceAllocation dart:async::Future [dynamic]
+ [33] = StaticICData target 'dart:async::Future::microtask (constructor)', arg-desc CP#9
+ [34] = InterfaceCall get target-name 'get:future', arg-desc CP#1
+ [35] = Reserved
}
Closure #lib::testAssert:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
ClosureBytecode {
@@ -2313,14 +2330,14 @@
JumpIfNoAsserts L2
Push r1
PushInt 42
- InstanceCall 2, CP#10
+ InterfaceCall 2, CP#10
AssertBoolean 0
JumpIfTrue L2
PushInt 0
PushInt 0
PushNull
- PushConstant CP#12
- IndirectStaticCall 3, CP#11
+ PushConstant CP#13
+ IndirectStaticCall 3, CP#12
Drop1
L2:
Push r4
@@ -2332,7 +2349,7 @@
LoadContextVar 0, 1
Push r4
LoadContextVar 0, 2
- PushConstant CP#13
+ PushConstant CP#14
IndirectStaticCall 2, CP#9
Drop1
PushNull
@@ -2356,7 +2373,7 @@
LoadContextVar 0, 1
Push r8
Push r9
- InstanceCall 3, CP#15
+ InterfaceCall 3, CP#16
Drop1
Jump L5
L5:
diff --git a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
index 5b7b1bf..ed981f0 100644
--- a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
+++ b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
@@ -308,7 +308,7 @@
JumpIfFalse L3
PushConstant CP#1
PushStatic CP#1
- InstanceCall 1, CP#3
+ DynamicCall 1, CP#3
StoreStaticTOS CP#0
L3:
PushConstant CP#0
@@ -402,8 +402,8 @@
Entry 0
CheckStack 0
Push FP[-5]
- InstanceCall 1, CP#1
- PushConstant CP#2
+ InterfaceCall 1, CP#1
+ PushConstant CP#3
IndirectStaticCall 1, CP#0
Drop1
PushNull
@@ -411,8 +411,9 @@
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
- [1] = ICData target-name 'toString', arg-desc CP#0
- [2] = StaticICData target '#lib::_printString', arg-desc CP#0
+ [1] = InterfaceCall target-name 'toString', arg-desc CP#0
+ [2] = Reserved
+ [3] = StaticICData target '#lib::_printString', arg-desc CP#0
}
]static method _print(dynamic arg) → void {
self::_printString(arg.{core::Object::toString}());
@@ -474,13 +475,13 @@
PushConstant CP#0
PushStatic CP#0
PushConstant CP#1
- InstanceCall 2, CP#3
+ InterfaceCall 2, CP#3
AssertBoolean 0
JumpIfTrue L1
PushConstant CP#0
PushStatic CP#0
- PushConstant CP#4
- InstanceCall 2, CP#5
+ PushConstant CP#5
+ InterfaceCall 2, CP#3
AssertBoolean 0
PopLocal r1
Jump L2
@@ -493,7 +494,7 @@
PushConstant CP#0
PushStatic CP#0
PushConstant CP#6
- InstanceCall 2, CP#7
+ InterfaceCall 2, CP#3
AssertBoolean 0
PopLocal r0
Jump L4
@@ -505,35 +506,35 @@
JumpIfFalse L5
PushConstant CP#0
PushStatic CP#0
- PushConstant CP#9
- IndirectStaticCall 1, CP#8
+ PushConstant CP#8
+ IndirectStaticCall 1, CP#7
ReturnTOS
L5:
- PushConstant CP#11
- IndirectStaticCall 0, CP#10
+ PushConstant CP#10
+ IndirectStaticCall 0, CP#9
PushNull
PushConstant CP#0
PushStatic CP#0
- PushConstant CP#12
+ PushConstant CP#11
IndirectStaticCall 2, CP#2
- InstanceCall 2, CP#13
+ InterfaceCall 2, CP#12
ReturnTOS
}
ConstantPool {
[0] = StaticField #lib::_rawScript (field)
[1] = String 'http:'
[2] = ArgDesc num-args 2, num-type-args 0, names []
- [3] = ICData target-name 'startsWith', arg-desc CP#2
- [4] = String 'https:'
- [5] = ICData target-name 'startsWith', arg-desc CP#2
+ [3] = InterfaceCall target-name 'startsWith', arg-desc CP#2
+ [4] = Reserved
+ [5] = String 'https:'
[6] = String 'file:'
- [7] = ICData target-name 'startsWith', arg-desc CP#2
- [8] = ArgDesc num-args 1, num-type-args 0, names []
- [9] = StaticICData target 'dart:core::Uri::parse', arg-desc CP#8
- [10] = ArgDesc num-args 0, num-type-args 0, names []
- [11] = StaticICData target 'dart:core::Uri::get:base', arg-desc CP#10
- [12] = StaticICData target 'dart:core::_Uri::file (constructor)', arg-desc CP#2
- [13] = ICData target-name 'resolveUri', arg-desc CP#2
+ [7] = ArgDesc num-args 1, num-type-args 0, names []
+ [8] = StaticICData target 'dart:core::Uri::parse', arg-desc CP#7
+ [9] = ArgDesc num-args 0, num-type-args 0, names []
+ [10] = StaticICData target 'dart:core::Uri::get:base', arg-desc CP#9
+ [11] = StaticICData target 'dart:core::_Uri::file (constructor)', arg-desc CP#2
+ [12] = InterfaceCall target-name 'resolveUri', arg-desc CP#2
+ [13] = Reserved
}
]static method _scriptUri() → core::Uri {
if(self::_rawScript.{core::String::startsWith}("http:") || self::_rawScript.{core::String::startsWith}("https:") || self::_rawScript.{core::String::startsWith}("file:")) {
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
index cf8425c..f801084 100644
--- a/pkg/vm/testcases/bytecode/closures.dart.expect
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -213,11 +213,11 @@
PopLocal r3
PushConstant CP#44
Push r3
- InstanceCall 2, CP#45
+ DynamicCall 2, CP#45
Drop1
PushConstant CP#46
Push r3
- InstanceCall 2, CP#47
+ DynamicCall 2, CP#47
Drop1
PushNull
ReturnTOS
@@ -319,11 +319,11 @@
PopLocal r3
PushConstant CP#38
Push r3
- InstanceCall 2, CP#40
+ DynamicCall 2, CP#40
Drop1
PushConstant CP#41
Push r3
- InstanceCall 2, CP#42
+ DynamicCall 2, CP#42
Drop1
PushNull
ReturnTOS
@@ -376,7 +376,7 @@
StoreFieldTOS CP#1
PopLocal r3
Push r3
- InstanceCall 1, CP#36
+ DynamicCall 1, CP#36
Drop1
PushNull
ReturnTOS
@@ -522,69 +522,69 @@
Push r0
PushInt 3
StoreContextVar 0, 2
- Allocate CP#10
+ Allocate CP#11
StoreLocal r4
Push r4
PushNull
- StoreFieldTOS CP#11
+ StoreFieldTOS CP#12
Push r4
PushNull
- StoreFieldTOS CP#13
+ StoreFieldTOS CP#14
Push r4
- PushConstant CP#15
- StoreFieldTOS CP#16
+ PushConstant CP#16
+ StoreFieldTOS CP#17
Push r4
PushConstant CP#0
- StoreFieldTOS CP#18
+ StoreFieldTOS CP#19
Push r4
Push r0
StoreFieldTOS CP#1
PopLocal r3
Push r3
PushInt 10
- InstanceCall 2, CP#24
+ DynamicCall 2, CP#25
Drop1
Push r3
PushInt 11
- InstanceCall 2, CP#25
+ DynamicCall 2, CP#26
Drop1
Push r2
- PushConstant CP#26
- IndirectStaticCall 1, CP#7
- Drop1
- Push r0
- LoadContextVar 0, 2
PushConstant CP#27
IndirectStaticCall 1, CP#7
Drop1
Push r0
- LoadContextVar 0, 1
+ LoadContextVar 0, 2
PushConstant CP#28
IndirectStaticCall 1, CP#7
Drop1
Push r0
+ LoadContextVar 0, 1
+ PushConstant CP#29
+ IndirectStaticCall 1, CP#7
+ Drop1
+ Push r0
PushInt 42
StoreContextVar 0, 3
- Allocate CP#10
+ Allocate CP#11
StoreLocal r3
Push r3
PushNull
- StoreFieldTOS CP#11
+ StoreFieldTOS CP#12
Push r3
PushNull
- StoreFieldTOS CP#13
+ StoreFieldTOS CP#14
Push r3
- PushConstant CP#15
- StoreFieldTOS CP#16
+ PushConstant CP#16
+ StoreFieldTOS CP#17
Push r3
- PushConstant CP#29
- StoreFieldTOS CP#18
+ PushConstant CP#30
+ StoreFieldTOS CP#19
Push r3
Push r0
StoreFieldTOS CP#1
PopLocal r2
Push r2
- InstanceCall 1, CP#32
+ DynamicCall 1, CP#34
Drop1
PushNull
ReturnTOS
@@ -598,31 +598,33 @@
[5] = SubtypeTestCache
[6] = ClosureFunction 1
[7] = ArgDesc num-args 1, num-type-args 0, names []
- [8] = ICData get target-name 'get:foo', arg-desc CP#7
- [9] = EndClosureFunctionScope
- [10] = Class dart:core::_Closure
- [11] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
- [12] = Reserved
- [13] = InstanceField dart:core::_Closure::_function_type_arguments (field)
- [14] = Reserved
- [15] = EmptyTypeArguments
- [16] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
- [17] = Reserved
- [18] = InstanceField dart:core::_Closure::_function (field)
- [19] = Reserved
- [20] = ICData dynamic target-name 'call', arg-desc CP#7
- [21] = StaticICData target 'dart:core::print', arg-desc CP#7
- [22] = EndClosureFunctionScope
- [23] = ArgDesc num-args 2, num-type-args 0, names []
- [24] = ICData dynamic target-name 'call', arg-desc CP#23
- [25] = ICData dynamic target-name 'call', arg-desc CP#23
- [26] = StaticICData target 'dart:core::print', arg-desc CP#7
+ [8] = InterfaceCall get target-name 'get:foo', arg-desc CP#7
+ [9] = Reserved
+ [10] = EndClosureFunctionScope
+ [11] = Class dart:core::_Closure
+ [12] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+ [13] = Reserved
+ [14] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+ [15] = Reserved
+ [16] = EmptyTypeArguments
+ [17] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+ [18] = Reserved
+ [19] = InstanceField dart:core::_Closure::_function (field)
+ [20] = Reserved
+ [21] = ICData dynamic target-name 'call', arg-desc CP#7
+ [22] = StaticICData target 'dart:core::print', arg-desc CP#7
+ [23] = EndClosureFunctionScope
+ [24] = ArgDesc num-args 2, num-type-args 0, names []
+ [25] = ICData dynamic target-name 'call', arg-desc CP#24
+ [26] = ICData dynamic target-name 'call', arg-desc CP#24
[27] = StaticICData target 'dart:core::print', arg-desc CP#7
[28] = StaticICData target 'dart:core::print', arg-desc CP#7
- [29] = ClosureFunction 2
- [30] = ICData set target-name 'set:foo', arg-desc CP#23
- [31] = EndClosureFunctionScope
- [32] = ICData dynamic target-name 'call', arg-desc CP#7
+ [29] = StaticICData target 'dart:core::print', arg-desc CP#7
+ [30] = ClosureFunction 2
+ [31] = InterfaceCall set target-name 'set:foo', arg-desc CP#24
+ [32] = Reserved
+ [33] = EndClosureFunctionScope
+ [34] = ICData dynamic target-name 'call', arg-desc CP#7
}
Closure #lib::B::topLevel::<anonymous closure> (dart:core::int y) -> dart:core::Null
ClosureBytecode {
@@ -663,30 +665,30 @@
Push r0
PushInt 4
StoreContextVar 1, 1
- Allocate CP#10
+ Allocate CP#11
StoreLocal r2
Push r2
PushNull
- StoreFieldTOS CP#11
+ StoreFieldTOS CP#12
Push r2
PushNull
- StoreFieldTOS CP#13
+ StoreFieldTOS CP#14
Push r2
- PushConstant CP#15
- StoreFieldTOS CP#16
+ PushConstant CP#16
+ StoreFieldTOS CP#17
Push r2
PushConstant CP#6
- StoreFieldTOS CP#18
+ StoreFieldTOS CP#19
Push r2
Push r0
StoreFieldTOS CP#1
PopLocal r3
Push r3
- InstanceCall 1, CP#20
+ DynamicCall 1, CP#21
Drop1
Push r0
LoadContextVar 1, 1
- PushConstant CP#21
+ PushConstant CP#22
IndirectStaticCall 1, CP#7
Drop1
L1:
@@ -714,7 +716,7 @@
Push r0
LoadContextParent
LoadContextVar 0, 0
- InstanceCall 1, CP#8
+ InterfaceCall 1, CP#8
Push r0
LoadContextVar 1, 0
AddInt
@@ -735,7 +737,7 @@
LoadContextVar 0, 0
Push r0
LoadContextVar 0, 3
- InstanceCall 2, CP#30
+ InterfaceCall 2, CP#31
Drop1
PushNull
ReturnTOS
@@ -855,7 +857,7 @@
Push r3
Push r0
StoreFieldTOS CP#5
- InstanceCall 2, CP#18
+ InterfaceCall 2, CP#18
Drop1
Push r4
Allocate CP#8
@@ -870,12 +872,12 @@
PushConstant CP#13
StoreFieldTOS CP#14
Push r3
- PushConstant CP#19
+ PushConstant CP#20
StoreFieldTOS CP#16
Push r3
Push r0
StoreFieldTOS CP#5
- InstanceCall 2, CP#24
+ InterfaceCall 2, CP#18
Drop1
Push r0
CloneContext 1, 1
@@ -919,13 +921,13 @@
[15] = Reserved
[16] = InstanceField dart:core::_Closure::_function (field)
[17] = Reserved
- [18] = ICData target-name 'add', arg-desc CP#1
- [19] = ClosureFunction 1
- [20] = Type dart:core::int
- [21] = String 'ii'
- [22] = SubtypeTestCache
- [23] = EndClosureFunctionScope
- [24] = ICData target-name 'add', arg-desc CP#1
+ [18] = InterfaceCall target-name 'add', arg-desc CP#1
+ [19] = Reserved
+ [20] = ClosureFunction 1
+ [21] = Type dart:core::int
+ [22] = String 'ii'
+ [23] = SubtypeTestCache
+ [24] = EndClosureFunctionScope
}
Closure #lib::C::testForLoop::<anonymous closure> () -> dart:core::int
ClosureBytecode {
@@ -952,11 +954,11 @@
LoadFieldTOS CP#5
PopLocal r0
Push FP[-5]
- PushConstant CP#20
- PushNull
- PushNull
PushConstant CP#21
- AssertAssignable 1, CP#22
+ PushNull
+ PushNull
+ PushConstant CP#22
+ AssertAssignable 1, CP#23
Drop1
Push r0
Push FP[-5]
@@ -985,43 +987,43 @@
Entry 5
CheckStack 0
Push FP[-5]
- InstanceCall 1, CP#1
+ InterfaceCall 1, CP#1
PopLocal r2
L2:
CheckStack 1
Push r2
- InstanceCall 1, CP#2
+ InterfaceCall 1, CP#3
JumpIfFalse L1
AllocateContext 0, 1
PopLocal r0
Push r0
Push r2
- InstanceCall 1, CP#3
+ InterfaceCall 1, CP#5
StoreContextVar 0, 0
- Allocate CP#8
+ Allocate CP#11
StoreLocal r4
Push r4
PushNull
- StoreFieldTOS CP#9
+ StoreFieldTOS CP#12
Push r4
PushNull
- StoreFieldTOS CP#11
- Push r4
- PushConstant CP#13
StoreFieldTOS CP#14
Push r4
- PushConstant CP#4
- StoreFieldTOS CP#16
+ PushConstant CP#16
+ StoreFieldTOS CP#17
+ Push r4
+ PushConstant CP#7
+ StoreFieldTOS CP#19
Push r4
Push r0
- StoreFieldTOS CP#5
+ StoreFieldTOS CP#8
PopLocal r3
Push r3
- InstanceCall 1, CP#18
+ DynamicCall 1, CP#21
Drop1
Push r0
LoadContextVar 0, 0
- PushConstant CP#19
+ PushConstant CP#22
IndirectStaticCall 1, CP#0
Drop1
Push r0
@@ -1034,32 +1036,35 @@
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
- [1] = ICData get target-name 'get:iterator', arg-desc CP#0
- [2] = ICData target-name 'moveNext', arg-desc CP#0
- [3] = ICData get target-name 'get:current', arg-desc CP#0
- [4] = ClosureFunction 0
- [5] = InstanceField dart:core::_Closure::_context (field)
+ [1] = InterfaceCall get target-name 'get:iterator', arg-desc CP#0
+ [2] = Reserved
+ [3] = InterfaceCall target-name 'moveNext', arg-desc CP#0
+ [4] = Reserved
+ [5] = InterfaceCall get target-name 'get:current', arg-desc CP#0
[6] = Reserved
- [7] = EndClosureFunctionScope
- [8] = Class dart:core::_Closure
- [9] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
- [10] = Reserved
- [11] = InstanceField dart:core::_Closure::_function_type_arguments (field)
- [12] = Reserved
- [13] = EmptyTypeArguments
- [14] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+ [7] = ClosureFunction 0
+ [8] = InstanceField dart:core::_Closure::_context (field)
+ [9] = Reserved
+ [10] = EndClosureFunctionScope
+ [11] = Class dart:core::_Closure
+ [12] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+ [13] = Reserved
+ [14] = InstanceField dart:core::_Closure::_function_type_arguments (field)
[15] = Reserved
- [16] = InstanceField dart:core::_Closure::_function (field)
- [17] = Reserved
- [18] = ICData dynamic target-name 'call', arg-desc CP#0
- [19] = StaticICData target 'dart:core::print', arg-desc CP#0
+ [16] = EmptyTypeArguments
+ [17] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+ [18] = Reserved
+ [19] = InstanceField dart:core::_Closure::_function (field)
+ [20] = Reserved
+ [21] = ICData dynamic target-name 'call', arg-desc CP#0
+ [22] = StaticICData target 'dart:core::print', arg-desc CP#0
}
Closure #lib::C::testForInLoop::<anonymous closure> () -> dart:core::Null
ClosureBytecode {
EntryFixed 1, 3
CheckStack 0
Push FP[-5]
- LoadFieldTOS CP#5
+ LoadFieldTOS CP#8
PopLocal r0
Push r0
Push r0
@@ -1202,7 +1207,7 @@
PopLocal r2
Push r2
PushInt 3
- InstanceCall 2, CP#18
+ DynamicCall 2, CP#18
Drop1
Push r0
LoadContextVar 0, 0
@@ -1359,20 +1364,20 @@
PushConstant CP#4
IndirectStaticCall 1, CP#3
Drop1
- InstanceCall 2, CP#6
+ InterfaceCall 2, CP#6
Drop1
- PushConstant CP#7
+ PushConstant CP#8
PushConstant CP#2
PushConstant CP#1
AllocateT
StoreLocal r0
Push r0
- PushConstant CP#8
+ PushConstant CP#9
IndirectStaticCall 1, CP#3
Drop1
- InstanceCall 2, CP#9
+ InterfaceCall 2, CP#6
Drop1
- PushConstant CP#7
+ PushConstant CP#8
PushConstant CP#10
PushConstant CP#1
AllocateT
@@ -1381,7 +1386,7 @@
PushConstant CP#11
IndirectStaticCall 1, CP#3
Drop1
- InstanceCall 2, CP#12
+ InterfaceCall 2, CP#6
Drop1
PushNull
ReturnTOS
@@ -1393,13 +1398,12 @@
[3] = ArgDesc num-args 1, num-type-args 0, names []
[4] = StaticICData target '#lib::A::'' (constructor)', arg-desc CP#3
[5] = ArgDesc num-args 1, num-type-args 2, names []
- [6] = ICData target-name 'foo', arg-desc CP#5
- [7] = TypeArgs [dart:core::List < #lib::C3 >, dart:core::List < #lib::C4 >]
- [8] = StaticICData target '#lib::A::'' (constructor)', arg-desc CP#3
- [9] = ICData target-name 'foo', arg-desc CP#5
+ [6] = InterfaceCall target-name 'foo', arg-desc CP#5
+ [7] = Reserved
+ [8] = TypeArgs [dart:core::List < #lib::C3 >, dart:core::List < #lib::C4 >]
+ [9] = StaticICData target '#lib::A::'' (constructor)', arg-desc CP#3
[10] = TypeArgumentsForInstanceAllocation #lib::A [dart:core::List < #lib::C1 >, dart:core::List < #lib::C2 >]
[11] = StaticICData target '#lib::A::'' (constructor)', arg-desc CP#3
- [12] = ICData target-name 'foo', arg-desc CP#5
}
]static method callA() → void {
new self::A::•<self::C1, self::C2>().{self::A::foo}<self::C3, self::C4>();
diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect
index 233eed7..4649642 100644
--- a/pkg/vm/testcases/bytecode/literals.dart.expect
+++ b/pkg/vm/testcases/bytecode/literals.dart.expect
@@ -483,15 +483,15 @@
Push r0
PushInt 1
Push FP[-5]
- InstanceCall 1, CP#7
+ InterfaceCall 1, CP#7
StoreIndexedTOS
Push r0
PushInt 2
- PushConstant CP#8
- StoreIndexedTOS
PushConstant CP#9
- IndirectStaticCall 2, CP#1
+ StoreIndexedTOS
PushConstant CP#10
+ IndirectStaticCall 2, CP#1
+ PushConstant CP#11
IndirectStaticCall 1, CP#3
Drop1
PushNull
@@ -505,10 +505,11 @@
[4] = StaticICData target 'dart:core::print', arg-desc CP#3
[5] = TypeArgs [dart:core::String]
[6] = String 'a'
- [7] = ICData target-name 'toString', arg-desc CP#3
- [8] = String 'b'
- [9] = StaticICData target 'dart:core::List::_fromLiteral (constructor)', arg-desc CP#1
- [10] = StaticICData target 'dart:core::print', arg-desc CP#3
+ [7] = InterfaceCall target-name 'toString', arg-desc CP#3
+ [8] = Reserved
+ [9] = String 'b'
+ [10] = StaticICData target 'dart:core::List::_fromLiteral (constructor)', arg-desc CP#1
+ [11] = StaticICData target 'dart:core::print', arg-desc CP#3
}
]static method test_list_literal(core::int a) → void {
core::print(<core::int>[1, a, 3]);
@@ -561,29 +562,29 @@
Push r1
PushInt 2
Push FP[-6]
- InstanceCall 1, CP#8
+ InterfaceCall 1, CP#8
StoreIndexedTOS
Push r1
PushInt 3
PushInt 3
StoreIndexedTOS
- PushConstant CP#9
- IndirectStaticCall 2, CP#2
PushConstant CP#10
- IndirectStaticCall 1, CP#4
- Drop1
- PushNull
- Push r0
- InstantiateTypeArgumentsTOS 0, CP#11
- PushConstant CP#12
- PushConstant CP#13
IndirectStaticCall 2, CP#2
- PushConstant CP#14
+ PushConstant CP#11
IndirectStaticCall 1, CP#4
Drop1
PushNull
Push r0
- InstantiateTypeArgumentsTOS 0, CP#15
+ InstantiateTypeArgumentsTOS 0, CP#12
+ PushConstant CP#13
+ PushConstant CP#14
+ IndirectStaticCall 2, CP#2
+ PushConstant CP#15
+ IndirectStaticCall 1, CP#4
+ Drop1
+ PushNull
+ Push r0
+ InstantiateTypeArgumentsTOS 0, CP#16
PushConstant CP#1
PushInt 2
CreateArrayTOS
@@ -596,9 +597,9 @@
PushInt 1
PushInt 4
StoreIndexedTOS
- PushConstant CP#16
- IndirectStaticCall 2, CP#2
PushConstant CP#17
+ IndirectStaticCall 2, CP#2
+ PushConstant CP#18
IndirectStaticCall 1, CP#4
Drop1
PushNull
@@ -613,16 +614,17 @@
[5] = StaticICData target 'dart:core::print', arg-desc CP#4
[6] = TypeArgs [dart:core::String, dart:core::int]
[7] = String 'foo'
- [8] = ICData target-name 'toString', arg-desc CP#4
- [9] = StaticICData target 'dart:core::Map::_fromLiteral (constructor)', arg-desc CP#2
- [10] = StaticICData target 'dart:core::print', arg-desc CP#4
- [11] = TypeArgs [dart:core::String, #lib::test_map_literal::TypeParam/0]
- [12] = List type-arg dynamic, entries CP# []
- [13] = StaticICData target 'dart:core::Map::_fromLiteral (constructor)', arg-desc CP#2
- [14] = StaticICData target 'dart:core::print', arg-desc CP#4
- [15] = TypeArgs [#lib::test_map_literal::TypeParam/0, dart:core::int]
- [16] = StaticICData target 'dart:core::Map::_fromLiteral (constructor)', arg-desc CP#2
- [17] = StaticICData target 'dart:core::print', arg-desc CP#4
+ [8] = InterfaceCall target-name 'toString', arg-desc CP#4
+ [9] = Reserved
+ [10] = StaticICData target 'dart:core::Map::_fromLiteral (constructor)', arg-desc CP#2
+ [11] = StaticICData target 'dart:core::print', arg-desc CP#4
+ [12] = TypeArgs [dart:core::String, #lib::test_map_literal::TypeParam/0]
+ [13] = List type-arg dynamic, entries CP# []
+ [14] = StaticICData target 'dart:core::Map::_fromLiteral (constructor)', arg-desc CP#2
+ [15] = StaticICData target 'dart:core::print', arg-desc CP#4
+ [16] = TypeArgs [#lib::test_map_literal::TypeParam/0, dart:core::int]
+ [17] = StaticICData target 'dart:core::Map::_fromLiteral (constructor)', arg-desc CP#2
+ [18] = StaticICData target 'dart:core::print', arg-desc CP#4
}
]static method test_map_literal<T extends core::Object = dynamic>(core::int a, core::int b, self::test_map_literal::T c) → void {
core::print(<core::int, core::int>{1: a, b: 2});
diff --git a/pkg/vm/testcases/bytecode/loops.dart.expect b/pkg/vm/testcases/bytecode/loops.dart.expect
index b3714bd..4fbdb3b 100644
--- a/pkg/vm/testcases/bytecode/loops.dart.expect
+++ b/pkg/vm/testcases/bytecode/loops.dart.expect
@@ -14,13 +14,13 @@
CheckStack 1
Push r1
Push FP[-5]
- InstanceCall 1, CP#1
+ InterfaceCall 1, CP#1
CompareIntLt
JumpIfFalse L1
Push r0
Push FP[-5]
Push r1
- InstanceCall 2, CP#3
+ InterfaceCall 2, CP#4
AddInt
PopLocal r0
Push r1
@@ -35,9 +35,11 @@
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
- [1] = ICData get target-name 'get:length', arg-desc CP#0
- [2] = ArgDesc num-args 2, num-type-args 0, names []
- [3] = ICData target-name '[]', arg-desc CP#2
+ [1] = InterfaceCall get target-name 'get:length', arg-desc CP#0
+ [2] = Reserved
+ [3] = ArgDesc num-args 2, num-type-args 0, names []
+ [4] = InterfaceCall target-name '[]', arg-desc CP#3
+ [5] = Reserved
}
]static method test_for(core::List<core::int> list) → core::int {
core::int sum = 0;
@@ -62,7 +64,7 @@
JumpIfFalse L1
Push r1
Push FP[-5]
- InstanceCall 1, CP#1
+ InterfaceCall 1, CP#1
CompareIntGe
JumpIfFalse L2
Jump L1
@@ -70,7 +72,7 @@
Push r0
Push FP[-5]
Push r1
- InstanceCall 2, CP#3
+ InterfaceCall 2, CP#4
AddInt
PopLocal r0
Push r1
@@ -85,9 +87,11 @@
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
- [1] = ICData get target-name 'get:length', arg-desc CP#0
- [2] = ArgDesc num-args 2, num-type-args 0, names []
- [3] = ICData target-name '[]', arg-desc CP#2
+ [1] = InterfaceCall get target-name 'get:length', arg-desc CP#0
+ [2] = Reserved
+ [3] = ArgDesc num-args 2, num-type-args 0, names []
+ [4] = InterfaceCall target-name '[]', arg-desc CP#3
+ [5] = Reserved
}
]static method test_for_break(core::List<core::int> list) → core::int {
core::int sum = 0;
@@ -113,7 +117,7 @@
CheckStack 1
Push r1
Push FP[-5]
- InstanceCall 1, CP#1
+ InterfaceCall 1, CP#1
CompareIntLt
JumpIfFalse L1
Push r1
@@ -125,7 +129,7 @@
Push r0
Push FP[-5]
Push r1
- InstanceCall 2, CP#3
+ InterfaceCall 2, CP#4
AddInt
PopLocal r0
L3:
@@ -141,9 +145,11 @@
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
- [1] = ICData get target-name 'get:length', arg-desc CP#0
- [2] = ArgDesc num-args 2, num-type-args 0, names []
- [3] = ICData target-name '[]', arg-desc CP#2
+ [1] = InterfaceCall get target-name 'get:length', arg-desc CP#0
+ [2] = Reserved
+ [3] = ArgDesc num-args 2, num-type-args 0, names []
+ [4] = InterfaceCall target-name '[]', arg-desc CP#3
+ [5] = Reserved
}
]static method test_for_continue(core::List<core::int> list) → core::int {
core::int sum = 0;
@@ -169,7 +175,7 @@
CheckStack 1
Push r1
Push FP[-5]
- InstanceCall 1, CP#1
+ InterfaceCall 1, CP#1
CompareIntLt
JumpIfFalse L1
Push r0
@@ -182,7 +188,7 @@
StoreLocal r1
PopLocal r3
Push r2
- InstanceCall 2, CP#3
+ InterfaceCall 2, CP#4
AddInt
PopLocal r0
Jump L2
@@ -192,9 +198,11 @@
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
- [1] = ICData get target-name 'get:length', arg-desc CP#0
- [2] = ArgDesc num-args 2, num-type-args 0, names []
- [3] = ICData target-name '[]', arg-desc CP#2
+ [1] = InterfaceCall get target-name 'get:length', arg-desc CP#0
+ [2] = Reserved
+ [3] = ArgDesc num-args 2, num-type-args 0, names []
+ [4] = InterfaceCall target-name '[]', arg-desc CP#3
+ [5] = Reserved
}
]static method test_while(core::List<core::int> list) → core::int {
core::int sum = 0;
@@ -217,7 +225,7 @@
Push r0
Push FP[-5]
Push r1
- InstanceCall 2, CP#1
+ InterfaceCall 2, CP#1
AddInt
PopLocal r0
Push r1
@@ -226,7 +234,7 @@
PopLocal r1
Push r1
Push FP[-5]
- InstanceCall 1, CP#3
+ InterfaceCall 1, CP#4
CompareIntLt
JumpIfTrue L1
Push r0
@@ -234,9 +242,11 @@
}
ConstantPool {
[0] = ArgDesc num-args 2, num-type-args 0, names []
- [1] = ICData target-name '[]', arg-desc CP#0
- [2] = ArgDesc num-args 1, num-type-args 0, names []
- [3] = ICData get target-name 'get:length', arg-desc CP#2
+ [1] = InterfaceCall target-name '[]', arg-desc CP#0
+ [2] = Reserved
+ [3] = ArgDesc num-args 1, num-type-args 0, names []
+ [4] = InterfaceCall get target-name 'get:length', arg-desc CP#3
+ [5] = Reserved
}
]static method test_do_while(core::List<core::int> list) → core::int {
core::int sum = 0;
@@ -255,15 +265,15 @@
PushInt 0
PopLocal r0
Push FP[-5]
- InstanceCall 1, CP#1
+ InterfaceCall 1, CP#1
PopLocal r1
L2:
CheckStack 1
Push r1
- InstanceCall 1, CP#2
+ InterfaceCall 1, CP#3
JumpIfFalse L1
Push r1
- InstanceCall 1, CP#3
+ InterfaceCall 1, CP#5
PopLocal r2
Push r0
Push r2
@@ -276,9 +286,12 @@
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
- [1] = ICData get target-name 'get:iterator', arg-desc CP#0
- [2] = ICData target-name 'moveNext', arg-desc CP#0
- [3] = ICData get target-name 'get:current', arg-desc CP#0
+ [1] = InterfaceCall get target-name 'get:iterator', arg-desc CP#0
+ [2] = Reserved
+ [3] = InterfaceCall target-name 'moveNext', arg-desc CP#0
+ [4] = Reserved
+ [5] = InterfaceCall get target-name 'get:current', arg-desc CP#0
+ [6] = Reserved
}
]static method test_for_in(core::List<core::int> list) → core::int {
core::int sum = 0;
@@ -296,15 +309,15 @@
PushInt 42
PopLocal r1
Push FP[-5]
- InstanceCall 1, CP#1
+ InterfaceCall 1, CP#1
PopLocal r2
L2:
CheckStack 1
Push r2
- InstanceCall 1, CP#2
+ InterfaceCall 1, CP#3
JumpIfFalse L1
Push r2
- InstanceCall 1, CP#3
+ InterfaceCall 1, CP#5
PopLocal r3
Push r3
PopLocal r1
@@ -319,9 +332,12 @@
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
- [1] = ICData get target-name 'get:iterator', arg-desc CP#0
- [2] = ICData target-name 'moveNext', arg-desc CP#0
- [3] = ICData get target-name 'get:current', arg-desc CP#0
+ [1] = InterfaceCall get target-name 'get:iterator', arg-desc CP#0
+ [2] = Reserved
+ [3] = InterfaceCall target-name 'moveNext', arg-desc CP#0
+ [4] = Reserved
+ [5] = InterfaceCall get target-name 'get:current', arg-desc CP#0
+ [6] = Reserved
}
]static method test_for_in_with_outer_var(core::List<core::int> list) → core::int {
core::int sum = 0;
diff --git a/pkg/vm/testcases/bytecode/super_calls.dart.expect b/pkg/vm/testcases/bytecode/super_calls.dart.expect
index 9ee6e1e..346cd8a 100644
--- a/pkg/vm/testcases/bytecode/super_calls.dart.expect
+++ b/pkg/vm/testcases/bytecode/super_calls.dart.expect
@@ -132,7 +132,7 @@
PushConstant CP#2
IndirectStaticCall 1, CP#1
PushConstant CP#3
- InstanceCall 3, CP#5
+ DynamicCall 3, CP#5
ReturnTOS
}
ConstantPool {
@@ -347,7 +347,7 @@
PushConstant CP#7
IndirectStaticCall 2, CP#6
PushConstant CP#8
- InstanceCall 3, CP#10
+ DynamicCall 3, CP#10
ReturnTOS
}
ConstantPool {
diff --git a/pkg/vm/testcases/bytecode/switch.dart.expect b/pkg/vm/testcases/bytecode/switch.dart.expect
index fe265d6..93301c3 100644
--- a/pkg/vm/testcases/bytecode/switch.dart.expect
+++ b/pkg/vm/testcases/bytecode/switch.dart.expect
@@ -12,15 +12,15 @@
PopLocal r1
Push r1
PushInt 1
- InstanceCall 2, CP#1
+ InterfaceCall 2, CP#1
JumpIfTrue L1
Push r1
PushInt 2
- InstanceCall 2, CP#2
+ InterfaceCall 2, CP#1
JumpIfTrue L2
Push r1
PushInt 3
- InstanceCall 2, CP#3
+ InterfaceCall 2, CP#1
JumpIfTrue L3
Jump L4
L1:
@@ -41,9 +41,8 @@
}
ConstantPool {
[0] = ArgDesc num-args 2, num-type-args 0, names []
- [1] = ICData target-name '==', arg-desc CP#0
- [2] = ICData target-name '==', arg-desc CP#0
- [3] = ICData target-name '==', arg-desc CP#0
+ [1] = InterfaceCall target-name '==', arg-desc CP#0
+ [2] = Reserved
}
]static method foo1(core::int x) → core::int {
core::int y;
@@ -80,27 +79,27 @@
PopLocal r1
Push r1
PushInt 1
- InstanceCall 2, CP#1
+ InterfaceCall 2, CP#1
JumpIfTrue L1
Push r1
PushInt 2
- InstanceCall 2, CP#2
+ InterfaceCall 2, CP#1
JumpIfTrue L1
Push r1
PushInt 3
- InstanceCall 2, CP#3
+ InterfaceCall 2, CP#1
JumpIfTrue L1
Push r1
PushInt 4
- InstanceCall 2, CP#4
+ InterfaceCall 2, CP#1
JumpIfTrue L2
Push r1
PushInt 5
- InstanceCall 2, CP#5
+ InterfaceCall 2, CP#1
JumpIfTrue L2
Push r1
PushInt 6
- InstanceCall 2, CP#6
+ InterfaceCall 2, CP#1
JumpIfTrue L2
Jump L3
L1:
@@ -120,12 +119,8 @@
}
ConstantPool {
[0] = ArgDesc num-args 2, num-type-args 0, names []
- [1] = ICData target-name '==', arg-desc CP#0
- [2] = ICData target-name '==', arg-desc CP#0
- [3] = ICData target-name '==', arg-desc CP#0
- [4] = ICData target-name '==', arg-desc CP#0
- [5] = ICData target-name '==', arg-desc CP#0
- [6] = ICData target-name '==', arg-desc CP#0
+ [1] = InterfaceCall target-name '==', arg-desc CP#0
+ [2] = Reserved
}
]static method foo2(core::int x) → core::int {
core::int y;
@@ -165,27 +160,27 @@
PopLocal r1
Push r1
PushInt 1
- InstanceCall 2, CP#1
+ InterfaceCall 2, CP#1
JumpIfTrue L1
Push r1
PushInt 2
- InstanceCall 2, CP#2
+ InterfaceCall 2, CP#1
JumpIfTrue L1
Push r1
PushInt 3
- InstanceCall 2, CP#3
+ InterfaceCall 2, CP#1
JumpIfTrue L1
Push r1
PushInt 4
- InstanceCall 2, CP#4
+ InterfaceCall 2, CP#1
JumpIfTrue L2
Push r1
PushInt 5
- InstanceCall 2, CP#5
+ InterfaceCall 2, CP#1
JumpIfTrue L2
Push r1
PushInt 6
- InstanceCall 2, CP#6
+ InterfaceCall 2, CP#1
JumpIfTrue L2
Jump L3
L1:
@@ -205,12 +200,8 @@
}
ConstantPool {
[0] = ArgDesc num-args 2, num-type-args 0, names []
- [1] = ICData target-name '==', arg-desc CP#0
- [2] = ICData target-name '==', arg-desc CP#0
- [3] = ICData target-name '==', arg-desc CP#0
- [4] = ICData target-name '==', arg-desc CP#0
- [5] = ICData target-name '==', arg-desc CP#0
- [6] = ICData target-name '==', arg-desc CP#0
+ [1] = InterfaceCall target-name '==', arg-desc CP#0
+ [2] = Reserved
}
]static method foo3(core::int x) → core::int {
core::int y;
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
index e50ba42..e946fb1 100644
--- a/pkg/vm/testcases/bytecode/try_blocks.dart.expect
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -78,17 +78,17 @@
MoveSpecial stackTrace, r1
Push r0
PushConstant CP#3
- InstanceCall 2, CP#5
+ InterfaceCall 2, CP#5
JumpIfFalse L2
- PushConstant CP#6
PushConstant CP#7
+ PushConstant CP#8
IndirectStaticCall 1, CP#1
Drop1
Jump L1
L2:
Push r0
- PushConstant CP#8
- InstanceCall 2, CP#9
+ PushConstant CP#9
+ InterfaceCall 2, CP#5
JumpIfFalse L3
Push r0
PopLocal r2
@@ -113,7 +113,7 @@
L3:
Push r0
PushConstant CP#13
- InstanceCall 2, CP#14
+ InterfaceCall 2, CP#5
JumpIfFalse L4
Push r0
PopLocal r2
@@ -125,7 +125,7 @@
StoreLocal r4
Push r4
PushInt 0
- PushConstant CP#15
+ PushConstant CP#14
StoreIndexedTOS
Push r4
PushInt 1
@@ -133,15 +133,15 @@
StoreIndexedTOS
Push r4
PushInt 2
- PushConstant CP#16
+ PushConstant CP#15
StoreIndexedTOS
Push r4
PushInt 3
Push r3
StoreIndexedTOS
- PushConstant CP#17
+ PushConstant CP#16
IndirectStaticCall 1, CP#1
- PushConstant CP#18
+ PushConstant CP#17
IndirectStaticCall 1, CP#1
Drop1
Jump L1
@@ -156,7 +156,7 @@
StoreLocal r4
Push r4
PushInt 0
- PushConstant CP#20
+ PushConstant CP#19
StoreIndexedTOS
Push r4
PushInt 1
@@ -164,15 +164,15 @@
StoreIndexedTOS
Push r4
PushInt 2
- PushConstant CP#16
+ PushConstant CP#15
StoreIndexedTOS
Push r4
PushInt 3
Push r3
StoreIndexedTOS
- PushConstant CP#21
+ PushConstant CP#20
IndirectStaticCall 1, CP#1
- PushConstant CP#22
+ PushConstant CP#21
IndirectStaticCall 1, CP#1
Drop1
Jump L1
@@ -181,7 +181,7 @@
ReturnTOS
}
ExceptionsTable {
- try-index 0, outer -1, start 2, end 7, handler 7, needs-stack-trace, types [CP#3, CP#8, CP#13, CP#19]
+ try-index 0, outer -1, start 2, end 7, handler 7, needs-stack-trace, types [CP#3, CP#9, CP#13, CP#18]
}
ConstantPool {
[0] = String 'danger!'
@@ -189,24 +189,23 @@
[2] = StaticICData target 'dart:core::print', arg-desc CP#1
[3] = Type dart:core::TypeError
[4] = ArgDesc num-args 2, num-type-args 0, names []
- [5] = ICData target-name '_simpleInstanceOf', arg-desc CP#4
- [6] = String 'caught type error'
- [7] = StaticICData target 'dart:core::print', arg-desc CP#1
- [8] = Type dart:core::AssertionError
- [9] = ICData target-name '_simpleInstanceOf', arg-desc CP#4
+ [5] = InterfaceCall target-name '_simpleInstanceOf', arg-desc CP#4
+ [6] = Reserved
+ [7] = String 'caught type error'
+ [8] = StaticICData target 'dart:core::print', arg-desc CP#1
+ [9] = Type dart:core::AssertionError
[10] = String 'caught assertion error '
[11] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#1
[12] = StaticICData target 'dart:core::print', arg-desc CP#1
[13] = Type dart:core::Error
- [14] = ICData target-name '_simpleInstanceOf', arg-desc CP#4
- [15] = String 'caught error '
- [16] = String ' '
- [17] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#1
- [18] = StaticICData target 'dart:core::print', arg-desc CP#1
- [19] = Type dynamic
- [20] = String 'caught something '
- [21] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#1
- [22] = StaticICData target 'dart:core::print', arg-desc CP#1
+ [14] = String 'caught error '
+ [15] = String ' '
+ [16] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#1
+ [17] = StaticICData target 'dart:core::print', arg-desc CP#1
+ [18] = Type dynamic
+ [19] = String 'caught something '
+ [20] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#1
+ [21] = StaticICData target 'dart:core::print', arg-desc CP#1
}
]static method testTryCatch2() → dynamic {
try {
@@ -259,7 +258,7 @@
StoreFieldTOS CP#1
PopLocal r4
Push r4
- InstanceCall 1, CP#19
+ DynamicCall 1, CP#19
Drop1
Push r0
LoadContextVar 0, 1
@@ -366,12 +365,13 @@
[27] = StaticICData target 'dart:core::print', arg-desc CP#4
[28] = Type dart:core::Error
[29] = ArgDesc num-args 2, num-type-args 0, names []
- [30] = ICData target-name '_simpleInstanceOf', arg-desc CP#29
- [31] = String 'error '
- [32] = String ', captured stack trace: '
- [33] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#4
- [34] = StaticICData target 'dart:core::print', arg-desc CP#4
- [35] = EndClosureFunctionScope
+ [30] = InterfaceCall target-name '_simpleInstanceOf', arg-desc CP#29
+ [31] = Reserved
+ [32] = String 'error '
+ [33] = String ', captured stack trace: '
+ [34] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#4
+ [35] = StaticICData target 'dart:core::print', arg-desc CP#4
+ [36] = EndClosureFunctionScope
}
Closure #lib::testTryCatch3::foo () -> void
ClosureBytecode {
@@ -436,7 +436,7 @@
MoveSpecial stackTrace, r3
Push r2
PushConstant CP#28
- InstanceCall 2, CP#30
+ InterfaceCall 2, CP#30
JumpIfFalse L2
Push r2
PopLocal r4
@@ -446,7 +446,7 @@
StoreLocal r5
Push r5
PushInt 0
- PushConstant CP#31
+ PushConstant CP#32
StoreIndexedTOS
Push r5
PushInt 1
@@ -454,17 +454,17 @@
StoreIndexedTOS
Push r5
PushInt 2
- PushConstant CP#32
+ PushConstant CP#33
StoreIndexedTOS
Push r5
PushInt 3
Push r0
LoadContextVar 0, 2
StoreIndexedTOS
- PushConstant CP#33
- IndirectStaticCall 1, CP#4
PushConstant CP#34
IndirectStaticCall 1, CP#4
+ PushConstant CP#35
+ IndirectStaticCall 1, CP#4
Drop1
Jump L1
L2:
@@ -704,11 +704,11 @@
PopLocal r2
Push r2
PushInt 1
- InstanceCall 2, CP#1
+ InterfaceCall 2, CP#1
JumpIfTrue L1
Push r2
PushInt 2
- InstanceCall 2, CP#2
+ InterfaceCall 2, CP#1
JumpIfTrue L2
Jump L3
L1:
@@ -748,7 +748,7 @@
StoreFieldTOS CP#9
PopLocal r7
Push r7
- InstanceCall 1, CP#24
+ DynamicCall 1, CP#24
Drop1
Jump L4
Try #1 end:
@@ -811,8 +811,8 @@
}
ConstantPool {
[0] = ArgDesc num-args 2, num-type-args 0, names []
- [1] = ICData target-name '==', arg-desc CP#0
- [2] = ICData target-name '==', arg-desc CP#0
+ [1] = InterfaceCall target-name '==', arg-desc CP#0
+ [2] = Reserved
[3] = String 'before try 1'
[4] = ArgDesc num-args 1, num-type-args 0, names []
[5] = StaticICData target 'dart:core::print', arg-desc CP#4
@@ -950,7 +950,7 @@
IndirectStaticCall 1, CP#3
Drop1
Push r2
- InstanceCall 1, CP#27
+ DynamicCall 1, CP#27
Drop1
Push r3
Push r4
@@ -964,7 +964,7 @@
IndirectStaticCall 1, CP#3
Drop1
Push r2
- InstanceCall 1, CP#29
+ DynamicCall 1, CP#29
Drop1
Push r0
LoadContextParent
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index 43203fc..04a4e32 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -106,23 +106,23 @@
LoadTypeArgumentsField CP#0
PushNull
PushConstant CP#1
- InstanceCall 4, CP#3
+ InterfaceCall 4, CP#3
JumpIfFalse L1
- PushConstant CP#4
- PushConstant CP#6
- IndirectStaticCall 1, CP#5
+ PushConstant CP#5
+ PushConstant CP#7
+ IndirectStaticCall 1, CP#6
Drop1
L1:
Push FP[-5]
Push FP[-6]
LoadTypeArgumentsField CP#0
PushNull
- PushConstant CP#7
- InstanceCall 4, CP#8
+ PushConstant CP#8
+ InterfaceCall 4, CP#3
JumpIfFalse L2
PushConstant CP#9
PushConstant CP#10
- IndirectStaticCall 1, CP#5
+ IndirectStaticCall 1, CP#6
Drop1
L2:
Push FP[-6]
@@ -133,7 +133,7 @@
PushNull
PushConstant CP#12
AssertAssignable 0, CP#13
- InstanceCall 2, CP#15
+ InterfaceCall 2, CP#15
Drop1
PushNull
ReturnTOS
@@ -142,19 +142,20 @@
[0] = TypeArgumentsField #lib::D
[1] = Type #lib::A < #lib::D::TypeParam/0 >
[2] = ArgDesc num-args 4, num-type-args 0, names []
- [3] = ICData target-name '_instanceOf', arg-desc CP#2
- [4] = String '21'
- [5] = ArgDesc num-args 1, num-type-args 0, names []
- [6] = StaticICData target 'dart:core::print', arg-desc CP#5
- [7] = Type #lib::C < dynamic, #lib::D::TypeParam/1, dart:core::List < #lib::D::TypeParam/0 > >
- [8] = ICData target-name '_instanceOf', arg-desc CP#2
+ [3] = InterfaceCall target-name '_instanceOf', arg-desc CP#2
+ [4] = Reserved
+ [5] = String '21'
+ [6] = ArgDesc num-args 1, num-type-args 0, names []
+ [7] = StaticICData target 'dart:core::print', arg-desc CP#6
+ [8] = Type #lib::C < dynamic, #lib::D::TypeParam/1, dart:core::List < #lib::D::TypeParam/0 > >
[9] = String '22'
- [10] = StaticICData target 'dart:core::print', arg-desc CP#5
+ [10] = StaticICData target 'dart:core::print', arg-desc CP#6
[11] = Type dart:core::Map < #lib::D::TypeParam/0, #lib::D::TypeParam/1 >
[12] = String ''
[13] = SubtypeTestCache
[14] = ArgDesc num-args 2, num-type-args 0, names []
- [15] = ICData set target-name 'set:foo', arg-desc CP#14
+ [15] = InterfaceCall set target-name 'set:foo', arg-desc CP#14
+ [16] = Reserved
}
] method foo2(dynamic y) → dynamic {
if(y is self::A<self::D::P>) {
@@ -174,51 +175,52 @@
PushNull
Push r0
PushConstant CP#0
- InstanceCall 4, CP#2
+ InterfaceCall 4, CP#2
JumpIfFalse L1
- PushConstant CP#3
- PushConstant CP#5
- IndirectStaticCall 1, CP#4
+ PushConstant CP#4
+ PushConstant CP#6
+ IndirectStaticCall 1, CP#5
Drop1
L1:
Push FP[-5]
Push FP[-6]
- LoadTypeArgumentsField CP#6
+ LoadTypeArgumentsField CP#7
Push r0
- PushConstant CP#7
- InstanceCall 4, CP#8
+ PushConstant CP#8
+ InterfaceCall 4, CP#2
JumpIfFalse L2
PushConstant CP#9
PushConstant CP#10
- IndirectStaticCall 1, CP#4
+ IndirectStaticCall 1, CP#5
Drop1
L2:
Push FP[-5]
PushConstant CP#11
Push FP[-6]
- LoadTypeArgumentsField CP#6
+ LoadTypeArgumentsField CP#7
Push r0
PushConstant CP#12
AssertAssignable 0, CP#13
- InstanceCall 1, CP#14
+ InterfaceCall 1, CP#14
ReturnTOS
}
ConstantPool {
[0] = Type #lib::A < #lib::D::foo3::TypeParam/0 >
[1] = ArgDesc num-args 4, num-type-args 0, names []
- [2] = ICData target-name '_instanceOf', arg-desc CP#1
- [3] = String '31'
- [4] = ArgDesc num-args 1, num-type-args 0, names []
- [5] = StaticICData target 'dart:core::print', arg-desc CP#4
- [6] = TypeArgumentsField #lib::D
- [7] = Type #lib::C < dart:core::Map < #lib::D::foo3::TypeParam/0, #lib::D::TypeParam/0 >, dart:core::List < #lib::D::foo3::TypeParam/1 >, #lib::D::TypeParam/1 >
- [8] = ICData target-name '_instanceOf', arg-desc CP#1
+ [2] = InterfaceCall target-name '_instanceOf', arg-desc CP#1
+ [3] = Reserved
+ [4] = String '31'
+ [5] = ArgDesc num-args 1, num-type-args 0, names []
+ [6] = StaticICData target 'dart:core::print', arg-desc CP#5
+ [7] = TypeArgumentsField #lib::D
+ [8] = Type #lib::C < dart:core::Map < #lib::D::foo3::TypeParam/0, #lib::D::TypeParam/0 >, dart:core::List < #lib::D::foo3::TypeParam/1 >, #lib::D::TypeParam/1 >
[9] = String '32'
- [10] = StaticICData target 'dart:core::print', arg-desc CP#4
+ [10] = StaticICData target 'dart:core::print', arg-desc CP#5
[11] = Type dart:core::Map < #lib::D::foo3::TypeParam/1, #lib::D::TypeParam/1 >
[12] = String ' in type cast'
[13] = SubtypeTestCache
- [14] = ICData get target-name 'get:values', arg-desc CP#4
+ [14] = InterfaceCall get target-name 'get:values', arg-desc CP#5
+ [15] = Reserved
}
] method foo3<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic>(dynamic z) → dynamic {
if(z is self::A<self::D::foo3::T1>) {
@@ -329,47 +331,49 @@
CheckStack 0
Push FP[-5]
PushConstant CP#0
- InstanceCall 2, CP#2
+ InterfaceCall 2, CP#2
JumpIfFalse L1
- PushConstant CP#3
- PushConstant CP#5
- IndirectStaticCall 1, CP#4
+ PushConstant CP#4
+ PushConstant CP#6
+ IndirectStaticCall 1, CP#5
Drop1
L1:
Push FP[-5]
PushNull
PushNull
- PushConstant CP#6
- InstanceCall 4, CP#8
+ PushConstant CP#7
+ InterfaceCall 4, CP#9
JumpIfFalse L2
- PushConstant CP#9
- PushConstant CP#10
- IndirectStaticCall 1, CP#4
+ PushConstant CP#11
+ PushConstant CP#12
+ IndirectStaticCall 1, CP#5
Drop1
L2:
Push FP[-5]
- PushConstant CP#11
+ PushConstant CP#13
PushNull
PushNull
- PushConstant CP#12
- AssertAssignable 0, CP#13
+ PushConstant CP#14
+ AssertAssignable 0, CP#15
ReturnTOS
}
ConstantPool {
[0] = Type #lib::B
[1] = ArgDesc num-args 2, num-type-args 0, names []
- [2] = ICData target-name '_simpleInstanceOf', arg-desc CP#1
- [3] = String '11'
- [4] = ArgDesc num-args 1, num-type-args 0, names []
- [5] = StaticICData target 'dart:core::print', arg-desc CP#4
- [6] = Type #lib::C < dart:core::int, dart:core::Object, dynamic >
- [7] = ArgDesc num-args 4, num-type-args 0, names []
- [8] = ICData target-name '_instanceOf', arg-desc CP#7
- [9] = String '12'
- [10] = StaticICData target 'dart:core::print', arg-desc CP#4
- [11] = Type #lib::A < dart:core::int >
- [12] = String ' in type cast'
- [13] = SubtypeTestCache
+ [2] = InterfaceCall target-name '_simpleInstanceOf', arg-desc CP#1
+ [3] = Reserved
+ [4] = String '11'
+ [5] = ArgDesc num-args 1, num-type-args 0, names []
+ [6] = StaticICData target 'dart:core::print', arg-desc CP#5
+ [7] = Type #lib::C < dart:core::int, dart:core::Object, dynamic >
+ [8] = ArgDesc num-args 4, num-type-args 0, names []
+ [9] = InterfaceCall target-name '_instanceOf', arg-desc CP#8
+ [10] = Reserved
+ [11] = String '12'
+ [12] = StaticICData target 'dart:core::print', arg-desc CP#5
+ [13] = Type #lib::A < dart:core::int >
+ [14] = String ' in type cast'
+ [15] = SubtypeTestCache
}
]static method foo1(dynamic x) → dynamic {
if(x is self::B) {
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc
index 9102f84..151429a 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.cc
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc
@@ -214,7 +214,8 @@
case KernelBytecode::kLoadConstant:
case KernelBytecode::kPushConstant:
case KernelBytecode::kIndirectStaticCall:
- case KernelBytecode::kInstanceCall:
+ case KernelBytecode::kInterfaceCall:
+ case KernelBytecode::kDynamicCall:
case KernelBytecode::kStoreStaticTOS:
case KernelBytecode::kPushStatic:
case KernelBytecode::kAllocate:
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index 20cb6a0..a5723f9 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -701,7 +701,47 @@
B->Push(call);
}
-void BytecodeFlowGraphBuilder::BuildInstanceCall() {
+void BytecodeFlowGraphBuilder::BuildInterfaceCall() {
+ if (is_generating_interpreter()) {
+ UNIMPLEMENTED(); // TODO(alexmarkov): interpreter
+ }
+
+ const String& name = String::Cast(ConstantAt(DecodeOperandD()).value());
+ ASSERT(name.IsSymbol());
+
+ const Array& arg_desc_array =
+ Array::Cast(ConstantAt(DecodeOperandD(), 1).value());
+ const ArgumentsDescriptor arg_desc(arg_desc_array);
+
+ const intptr_t argc = DecodeOperandA().value();
+ const Token::Kind token_kind =
+ MethodTokenRecognizer::RecognizeTokenKind(name);
+
+ intptr_t checked_argument_count = 1;
+ if ((token_kind != Token::kILLEGAL) ||
+ (name.raw() ==
+ Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()).raw())) {
+ intptr_t argument_count = arg_desc.Count();
+ ASSERT(argument_count <= 2);
+ checked_argument_count = argument_count;
+ }
+
+ const ArgumentArray arguments = GetArguments(argc);
+
+ // TODO(alexmarkov): store interface_target in bytecode and pass it here.
+
+ InstanceCallInstr* call = new (Z) InstanceCallInstr(
+ position_, name, token_kind, arguments, arg_desc.TypeArgsLen(),
+ Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), checked_argument_count,
+ *ic_data_array_, B->GetNextDeoptId());
+
+ // TODO(alexmarkov): add type info - call->SetResultType()
+
+ code_ <<= call;
+ B->Push(call);
+}
+
+void BytecodeFlowGraphBuilder::BuildDynamicCall() {
if (is_generating_interpreter()) {
UNIMPLEMENTED(); // TODO(alexmarkov): interpreter
}
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 55f932f..f24f405 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -344,6 +344,7 @@
kPartialTearOffInstantiation,
kEmptyTypeArguments,
kSymbol,
+ kInterfaceCall,
};
enum InvocationKind {
@@ -618,6 +619,22 @@
Instance::Cast(obj).SetField(*symbol_name_field, name);
obj = H.Canonicalize(Instance::Cast(obj));
} break;
+ case ConstantPoolTag::kInterfaceCall: {
+ helper_->ReadByte(); // TODO(regis): Remove, unneeded.
+ name ^= ReadObject();
+ ASSERT(name.IsSymbol());
+ intptr_t arg_desc_index = helper_->ReadUInt();
+ ASSERT(arg_desc_index < i);
+ array ^= pool.ObjectAt(arg_desc_index);
+ // InterfaceCall constant occupies 2 entries.
+ // The first entry is used for selector name.
+ pool.SetTypeAt(i, ObjectPool::kTaggedObject, ObjectPool::kNotPatchable);
+ pool.SetObjectAt(i, name);
+ ++i;
+ ASSERT(i < obj_count);
+ // The second entry is used for arguments descriptor.
+ obj = array.raw();
+ } break;
default:
UNREACHABLE();
}
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index 67772ab..15506e5 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -271,7 +271,16 @@
// SP[-(1+ArgC)], ..., SP[-1] and argument descriptor PP[D], which
// indicates whether the first argument is a type argument vector.
//
-// - InstanceCall ArgC, D
+// - InterfaceCall ArgC, D
+//
+// Lookup and invoke method using ICData in PP[D]
+// with arguments SP[-(1+ArgC)], ..., SP[-1].
+// Method has to be declared (explicitly or implicitly) in an interface
+// implemented by a receiver, and passed arguments are valid for the
+// interface method declaration.
+// The ICData indicates whether the first argument is a type argument vector.
+//
+// - DynamicCall ArgC, D
//
// Lookup and invoke method using ICData in PP[D]
// with arguments SP[-(1+ArgC)], ..., SP[-1].
@@ -439,7 +448,8 @@
V(JumpIfNull, T, tgt, ___, ___) \
V(JumpIfNotNull, T, tgt, ___, ___) \
V(IndirectStaticCall, A_D, num, num, ___) \
- V(InstanceCall, A_D, num, num, ___) \
+ V(InterfaceCall, A_D, num, num, ___) \
+ V(DynamicCall, A_D, num, num, ___) \
V(NativeCall, D, lit, ___, ___) \
V(ReturnTOS, 0, ___, ___, ___) \
V(AssertAssignable, A_D, num, lit, ___) \
@@ -595,7 +605,8 @@
DART_FORCE_INLINE static bool IsCallOpcode(KBCInstr instr) {
switch (DecodeOpcode(instr)) {
case KernelBytecode::kIndirectStaticCall:
- case KernelBytecode::kInstanceCall:
+ case KernelBytecode::kInterfaceCall:
+ case KernelBytecode::kDynamicCall:
return true;
default:
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index 65a6f0d..23342d3 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -86,7 +86,6 @@
enum {
kTypeArgsLenIndex,
kCountIndex,
-
kPositionalCountIndex,
kFirstNamedEntryIndex,
};
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 1dcd875..23fe586 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -479,6 +479,15 @@
void GCMarker::Prologue() {
isolate_->ReleaseStoreBuffers();
+
+#ifndef DART_PRECOMPILED_RUNTIME
+ if (isolate_->IsMutatorThreadScheduled()) {
+ Interpreter* interpreter = isolate_->mutator_thread()->interpreter();
+ if (interpreter != NULL) {
+ interpreter->MajorGC();
+ }
+ }
+#endif
}
void GCMarker::Epilogue() {
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index 688dfeb..bdfec17 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -499,6 +499,66 @@
return function;
}
+void LookupCache::Clear() {
+ for (intptr_t i = 0; i < kNumEntries; i++) {
+ entries_[i].receiver_cid = kIllegalCid;
+ }
+}
+
+bool LookupCache::Lookup(intptr_t receiver_cid,
+ RawString* function_name,
+ RawFunction** target) const {
+ ASSERT(receiver_cid != kIllegalCid); // Sentinel value.
+
+ const intptr_t hash =
+ receiver_cid ^ reinterpret_cast<intptr_t>(function_name);
+ const intptr_t probe1 = hash & kTableMask;
+ if (entries_[probe1].receiver_cid == receiver_cid &&
+ entries_[probe1].function_name == function_name) {
+ *target = entries_[probe1].target;
+ return true;
+ }
+
+ intptr_t probe2 = (hash >> 3) & kTableMask;
+ if (entries_[probe2].receiver_cid == receiver_cid &&
+ entries_[probe2].function_name == function_name) {
+ *target = entries_[probe2].target;
+ return true;
+ }
+
+ return false;
+}
+
+void LookupCache::Insert(intptr_t receiver_cid,
+ RawString* function_name,
+ RawFunction* target) {
+ // Otherwise we have to clear the cache or rehash on scavenges too.
+ ASSERT(function_name->IsOldObject());
+ ASSERT(target->IsOldObject());
+
+ const intptr_t hash =
+ receiver_cid ^ reinterpret_cast<intptr_t>(function_name);
+ const intptr_t probe1 = hash & kTableMask;
+ if (entries_[probe1].receiver_cid == kIllegalCid) {
+ entries_[probe1].receiver_cid = receiver_cid;
+ entries_[probe1].function_name = function_name;
+ entries_[probe1].target = target;
+ return;
+ }
+
+ const intptr_t probe2 = (hash >> 3) & kTableMask;
+ if (entries_[probe2].receiver_cid == kIllegalCid) {
+ entries_[probe2].receiver_cid = receiver_cid;
+ entries_[probe2].function_name = function_name;
+ entries_[probe2].target = target;
+ return;
+ }
+
+ entries_[probe1].receiver_cid = receiver_cid;
+ entries_[probe1].function_name = function_name;
+ entries_[probe1].target = target;
+}
+
IntrinsicHandler Interpreter::intrinsics_[Interpreter::kIntrinsicCount];
// Synchronization primitives support.
@@ -545,7 +605,7 @@
}
Interpreter::Interpreter()
- : stack_(NULL), fp_(NULL), pp_(NULL), argdesc_(NULL) {
+ : stack_(NULL), fp_(NULL), pp_(NULL), argdesc_(NULL), lookup_cache_() {
// Setup interpreter support first. Some of this information is needed to
// setup the architecture state.
// We allocate the stack here, the size is computed as the sum of
@@ -584,6 +644,8 @@
Interpreter::~Interpreter() {
delete[] stack_;
+ pp_ = NULL;
+ argdesc_ = NULL;
#if defined(DEBUG)
if (trace_file_ != NULL) {
FlushTraceBuffer();
@@ -601,8 +663,10 @@
// Get the active Interpreter for the current isolate.
Interpreter* Interpreter::Current() {
- Interpreter* interpreter = Thread::Current()->interpreter();
+ Thread* thread = Thread::Current();
+ Interpreter* interpreter = thread->interpreter();
if (interpreter == NULL) {
+ TransitionGeneratedToVM transition(thread);
interpreter = new Interpreter();
Thread::Current()->set_interpreter(interpreter);
}
@@ -697,19 +761,6 @@
#endif
}
-void Interpreter::CallRuntime(Thread* thread,
- RawObject** base,
- RawObject** exit_frame,
- uint32_t* pc,
- intptr_t argc_tag,
- RawObject** args,
- RawObject** result,
- uword target) {
- Exit(thread, base, exit_frame, pc);
- NativeArguments native_args(thread, argc_tag, args, result);
- reinterpret_cast<RuntimeFunction>(target)(native_args);
-}
-
// Calling into runtime may trigger garbage collection and relocate objects,
// so all RawObject* pointers become outdated and should not be used across
// runtime calls.
@@ -1171,8 +1222,48 @@
// Handler arguments: arguments to check and an ICData object.
const intptr_t miss_handler_argc = checked_args + 1;
RawObject** exit_frame = miss_handler_args + miss_handler_argc;
- CallRuntime(thread, FP, exit_frame, pc, miss_handler_argc, miss_handler_args,
- result, reinterpret_cast<uword>(handler));
+ Exit(thread, FP, exit_frame, pc);
+ NativeArguments native_args(thread, miss_handler_argc, miss_handler_args,
+ result);
+ handler(native_args);
+}
+
+DART_FORCE_INLINE bool Interpreter::InterfaceCall(Thread* thread,
+ RawString* target_name,
+ RawObject** call_base,
+ RawObject** top,
+ uint32_t** pc,
+ RawObject*** FP,
+ RawObject*** SP) {
+ const intptr_t type_args_len =
+ InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
+ const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
+
+ intptr_t receiver_cid =
+ InterpreterHelpers::GetClassId(call_base[receiver_idx]);
+
+ RawFunction* target;
+ if (UNLIKELY(!lookup_cache_.Lookup(receiver_cid, target_name, &target))) {
+ // Table lookup miss.
+ top[1] = call_base[receiver_idx];
+ top[2] = target_name;
+ top[3] = argdesc_;
+ top[4] = 0; // Result slot.
+
+ Exit(thread, *FP, top + 5, *pc);
+ NativeArguments native_args(thread, 3, /* argv */ top + 1,
+ /* result */ top + 4);
+ DRT_InterpretedInterfaceCallMissHandler(native_args);
+
+ target = static_cast<RawFunction*>(top[4]);
+ target_name = static_cast<RawString*>(top[2]);
+ argdesc_ = static_cast<RawArray*>(top[3]);
+ ASSERT(target->IsFunction());
+ lookup_cache_.Insert(receiver_cid, target_name, target);
+ }
+
+ top[0] = target;
+ return Invoke(thread, call_base, top, pc, FP, SP);
}
DART_FORCE_INLINE bool Interpreter::InstanceCall1(Thread* thread,
@@ -2111,7 +2202,36 @@
}
{
- BYTECODE(InstanceCall, A_D);
+ BYTECODE(InterfaceCall, A_D);
+
+ // Check if single stepping.
+ if (thread->isolate()->single_step()) {
+ Exit(thread, FP, SP + 1, pc);
+ NativeArguments args(thread, 0, NULL, NULL);
+ INVOKE_RUNTIME(DRT_SingleStepHandler, args);
+ }
+
+ {
+ const uint16_t argc = rA;
+ const uint16_t kidx = rD;
+
+ RawObject** call_base = SP - argc + 1;
+ RawObject** call_top = SP + 1;
+
+ InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
+ RawString* target_name = static_cast<RawString*>(LOAD_CONSTANT(kidx));
+ argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+ if (!InterfaceCall(thread, target_name, call_base, call_top, &pc, &FP,
+ &SP)) {
+ HANDLE_EXCEPTION;
+ }
+ }
+
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(DynamicCall, A_D);
// Check if single stepping.
if (thread->isolate()->single_step()) {
diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h
index 4d4fd91..45d476e 100644
--- a/runtime/vm/interpreter.h
+++ b/runtime/vm/interpreter.h
@@ -27,6 +27,36 @@
class RawSubtypeTestCache;
class ObjectPointerVisitor;
+class LookupCache : public ValueObject {
+ public:
+ LookupCache() {
+ ASSERT(Utils::IsPowerOfTwo(sizeof(Entry)));
+ ASSERT(Utils::IsPowerOfTwo(sizeof(kNumEntries)));
+ Clear();
+ }
+
+ void Clear();
+ bool Lookup(intptr_t receiver_cid,
+ RawString* function_name,
+ RawFunction** target) const;
+ void Insert(intptr_t receiver_cid,
+ RawString* function_name,
+ RawFunction* target);
+
+ private:
+ struct Entry {
+ intptr_t receiver_cid;
+ RawString* function_name;
+ RawFunction* target;
+ intptr_t padding;
+ };
+
+ static const intptr_t kNumEntries = 1024;
+ static const intptr_t kTableMask = kNumEntries - 1;
+
+ Entry entries_[kNumEntries];
+};
+
// Interpreter intrinsic handler. It is invoked on entry to the intrinsified
// function via Intrinsic bytecode before the frame is setup.
// If the handler returns true then Intrinsic bytecode works as a return
@@ -97,6 +127,7 @@
}
void VisitObjectPointers(ObjectPointerVisitor* visitor);
+ void MajorGC() { lookup_cache_.Clear(); }
private:
uintptr_t* stack_;
@@ -115,6 +146,8 @@
// call instruction and the function entry.
RawObject* special_[KernelBytecode::kSpecialIndexCount];
+ LookupCache lookup_cache_;
+
static IntrinsicHandler intrinsics_[kIntrinsicCount];
void Exit(Thread* thread,
@@ -122,15 +155,6 @@
RawObject** exit_frame,
uint32_t* pc);
- void CallRuntime(Thread* thread,
- RawObject** base,
- RawObject** exit_frame,
- uint32_t* pc,
- intptr_t argc_tag,
- RawObject** args,
- RawObject** result,
- uword target);
-
bool Invoke(Thread* thread,
RawObject** call_base,
RawObject** call_top,
@@ -164,6 +188,14 @@
RawObject** FP,
RawObject** SP);
+ bool InterfaceCall(Thread* thread,
+ RawString* target_name,
+ RawObject** call_base,
+ RawObject** call_top,
+ uint32_t** pc,
+ RawObject*** FP,
+ RawObject*** SP);
+
bool InstanceCall1(Thread* thread,
RawICData* icdata,
RawObject** call_base,
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 2829c76..2ae6c18 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1618,6 +1618,37 @@
#endif // !defined(TARGET_ARCH_DBC)
}
+// Handles interpreted interface call cache miss.
+// Arg0: receiver
+// Arg1: target name
+// Arg2: arguments descriptor
+// Returns: target function
+// Modifies the instance call table in current interpreter.
+DEFINE_RUNTIME_ENTRY(InterpretedInterfaceCallMissHandler, 3) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ UNREACHABLE();
+#else
+ ASSERT(FLAG_enable_interpreter);
+ const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+ const String& target_name = String::CheckedHandle(zone, arguments.ArgAt(1));
+ const Array& arg_desc = Array::CheckedHandle(zone, arguments.ArgAt(2));
+
+ ArgumentsDescriptor arguments_descriptor(arg_desc);
+ Function& target_function = Function::Handle(
+ zone,
+ Resolver::ResolveDynamic(receiver, target_name, arguments_descriptor));
+
+ // TODO(regis): In order to substitute 'simple_instance_of_function', the 2nd
+ // arg to the call, the type, is needed.
+
+ if (target_function.IsNull()) {
+ target_function = InlineCacheMissHelper(receiver, arg_desc, target_name);
+ }
+ ASSERT(!target_function.IsNull());
+ arguments.SetReturn(target_function);
+#endif
+}
+
// Invoke appropriate noSuchMethod or closure from getter.
// Arg0: receiver
// Arg1: ICData or MegamorphicCache
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index 5bafc0e..fa97c63 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -24,6 +24,7 @@
V(InlineCacheMissHandlerTwoArgs) \
V(StaticCallMissHandlerOneArg) \
V(StaticCallMissHandlerTwoArgs) \
+ V(InterpretedInterfaceCallMissHandler) \
V(Instanceof) \
V(SubtypeCheck) \
V(TypeCheck) \
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index b7a8f14..109ccd4 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -716,15 +716,15 @@
// Only the mutator thread can run Dart code.
if (IsMutatorThread()) {
// The MarkTask, which calls this method, can run on a different thread. We
- // therefore assume the mutator is at a safepoint and we can iterate it's
+ // therefore assume the mutator is at a safepoint and we can iterate its
// stack.
// TODO(vm-team): It would be beneficial to be able to ask the mutator
// thread whether it is in fact blocked at the moment (at a "safepoint") so
- // we can safely iterate it's stack.
+ // we can safely iterate its stack.
//
// Unfortunately we cannot use `this->IsAtSafepoint()` here because that
// will return `false` even though the mutator thread is waiting for mark
- // tasks (which iterate it's stack) to finish.
+ // tasks (which iterate its stack) to finish.
const StackFrameIterator::CrossThreadPolicy cross_thread_policy =
StackFrameIterator::kAllowCrossThreadIteration;