diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart index f937116aef6..eaab50372c3 100644 --- a/pkg/vm/lib/bytecode/assembler.dart +++ b/pkg/vm/lib/bytecode/assembler.dart @@ -271,9 +271,14 @@ class BytecodeAssembler { 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 fda38eeec90..e4c77c10862 100644 --- a/pkg/vm/lib/bytecode/constant_pool.dart +++ b/pkg/vm/lib/bytecode/constant_pool.dart @@ -169,6 +169,15 @@ type ConstantSymbol extends ConstantPoolEntry { 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 @@ enum ConstantTag { kPartialTearOffInstantiation, kEmptyTypeArguments, kSymbol, + kInterfaceCall, } abstract class ConstantPoolEntry { @@ -271,6 +281,8 @@ abstract class ConstantPoolEntry { 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 @@ class ConstantSymbol extends ConstantPoolEntry { 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 @@ class ConstantPool { 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 1092e1400f1..6f7923a427f 100644 --- a/pkg/vm/lib/bytecode/dbc.dart +++ b/pkg/vm/lib/bytecode/dbc.dart @@ -82,7 +82,8 @@ enum Opcode { // Calls. kIndirectStaticCall, - kInstanceCall, + kInterfaceCall, + kDynamicCall, kNativeCall, kReturnTOS, @@ -235,7 +236,9 @@ const Map BytecodeFormats = const { 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 isThrow(Opcode opcode) => opcode == Opcode.kThrow; 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 6dd79602a7d..7bd5dc3568f 100644 --- a/pkg/vm/lib/bytecode/gen_bytecode.dart +++ b/pkg/vm/lib/bytecode/gen_bytecode.dart @@ -772,9 +772,9 @@ class BytecodeGenerator extends RecursiveVisitor { 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 @@ class BytecodeGenerator extends RecursiveVisitor { } 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 @@ class BytecodeGenerator extends RecursiveVisitor { 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 @@ class BytecodeGenerator extends RecursiveVisitor { 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 @@ class BytecodeGenerator extends RecursiveVisitor { 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 @@ class BytecodeGenerator extends RecursiveVisitor { 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. + asm.emitInterfaceCall( 1, - cp.addICData( + cp.addInterfaceCall( InvocationKind.getter, new Name(kIterator), cp.addArgDesc(1))); final iteratorTemp = locals.tempIndexInFrame(node); @@ -2436,9 +2449,9 @@ class BytecodeGenerator extends RecursiveVisitor { 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 @@ class BytecodeGenerator extends RecursiveVisitor { _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 @@ class BytecodeGenerator extends RecursiveVisitor { 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 a7706b7212e..575ae5fccf2 100644 --- a/pkg/vm/testcases/bytecode/asserts.dart.expect +++ b/pkg/vm/testcases/bytecode/asserts.dart.expect @@ -33,13 +33,13 @@ Bytecode { 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 db9690f82ee..dc8453955b9 100644 --- a/pkg/vm/testcases/bytecode/async.dart.expect +++ b/pkg/vm/testcases/bytecode/async.dart.expect @@ -7,20 +7,20 @@ import "dart:core" as core; 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 @@ ConstantPool { [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):: (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null > ClosureBytecode { @@ -109,50 +111,50 @@ ClosureBytecode { 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 @@ Try #0 handler: LoadContextVar 0, 1 Push r8 Push r9 - InstanceCall 3, CP#17 + InterfaceCall 3, CP#17 Drop1 Jump L3 L3: @@ -300,44 +302,44 @@ Bytecode { 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 @@ ConstantPool { [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 @@ Try #0 handler: LoadContextVar 0, 0 Push r8 Push r9 - InstanceCall 3, CP#11 + InterfaceCall 3, CP#11 Drop1 Jump L3 L3: @@ -497,50 +501,50 @@ Bytecode { 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 @@ ConstantPool { [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 @@ L3: 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 @@ L4: LoadContextVar 0, 2 Push r4 LoadContextVar 0, 3 - PushConstant CP#12 + PushConstant CP#13 IndirectStaticCall 2, CP#10 Drop1 PushNull @@ -689,7 +696,7 @@ Try #0 handler: LoadContextVar 0, 2 Push r8 Push r9 - InstanceCall 3, CP#15 + InterfaceCall 3, CP#16 Drop1 Jump L5 L5: @@ -778,50 +785,50 @@ Bytecode { 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 @@ ConstantPool { [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 @@ L6: LoadContextParent LoadContextParent LoadContextVar 0, 0 - InstanceCall 1, CP#7 + InterfaceCall 1, CP#7 PopLocal r8 Push r4 Push r8 @@ -923,7 +935,7 @@ L5: 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 @@ L5: PopLocal r4 Push r4 Push r8 - InstanceCall 1, CP#9 + InterfaceCall 1, CP#11 StoreContextVar 3, 0 Push r4 LoadContextParent @@ -967,8 +979,8 @@ L5: 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 @@ L5: 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 @@ L4: 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 @@ L9: 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 @@ Try #0 handler: LoadContextVar 0, 1 Push r8 Push r9 - InstanceCall 3, CP#20 + InterfaceCall 3, CP#23 Drop1 Jump L10 L10: @@ -1205,50 +1217,50 @@ Bytecode { 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 @@ ConstantPool { [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 @@ L2: 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 @@ Try #2 handler: 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 @@ L4: Push r4 LoadContextParent LoadContextVar 0, 15 - PushConstant CP#14 + PushConstant CP#16 IndirectStaticCall 4, CP#7 PopLocal r13 PushNull @@ -1458,7 +1470,7 @@ L6: LoadContextParent LoadContextVar 0, 14 Push r1 - InstanceCall 2, CP#15 + InterfaceCall 2, CP#10 StoreContextVar 1, 0 Push r4 LoadContextParent @@ -1488,8 +1500,8 @@ Try #1 handler: 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 @@ Try #1 handler: Push r4 LoadContextParent LoadContextVar 0, 15 - PushConstant CP#18 + PushConstant CP#19 IndirectStaticCall 4, CP#7 PopLocal r12 PushNull @@ -1534,7 +1546,7 @@ L8: LoadContextParent LoadContextVar 0, 14 Push r1 - InstanceCall 2, CP#19 + InterfaceCall 2, CP#10 StoreContextVar 1, 0 Push r4 LoadContextParent @@ -1552,7 +1564,7 @@ L5: 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 @@ L10: LoadContextParent LoadContextVar 0, 14 Push r1 - InstanceCall 2, CP#22 + InterfaceCall 2, CP#10 StoreContextVar 1, 0 Push r4 LoadContextParent @@ -1616,8 +1628,8 @@ L7: 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 @@ L7: Push r4 LoadContextParent LoadContextVar 0, 15 - PushConstant CP#24 + PushConstant CP#23 IndirectStaticCall 4, CP#7 PopLocal r12 PushNull @@ -1662,7 +1674,7 @@ L11: LoadContextParent LoadContextVar 0, 14 Push r1 - InstanceCall 2, CP#25 + InterfaceCall 2, CP#10 StoreContextVar 1, 0 Push r4 LoadContextParent @@ -1678,7 +1690,7 @@ L9: LoadContextVar 0, 3 Push r4 LoadContextVar 0, 4 - PushConstant CP#26 + PushConstant CP#24 IndirectStaticCall 2, CP#9 Drop1 PushNull @@ -1702,7 +1714,7 @@ Try #0 handler: LoadContextVar 0, 3 Push r8 Push r9 - InstanceCall 3, CP#28 + InterfaceCall 3, CP#26 Drop1 Jump L12 L12: @@ -1795,20 +1807,20 @@ Bytecode { 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 @@ ConstantPool { [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 @@ ClosureBytecode { 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 @@ Try #0 handler: LoadContextVar 1, 0 Push r8 Push r9 - InstanceCall 3, CP#17 + InterfaceCall 3, CP#17 Drop1 Jump L5 L5: @@ -2182,50 +2196,50 @@ Bytecode { 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 @@ ConstantPool { [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 @@ L3: 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 @@ L4: LoadContextVar 0, 1 Push r4 LoadContextVar 0, 2 - PushConstant CP#13 + PushConstant CP#14 IndirectStaticCall 2, CP#9 Drop1 PushNull @@ -2356,7 +2373,7 @@ Try #0 handler: 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 5b7b1bf11e7..ed981f0295d 100644 --- a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect +++ b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect @@ -308,7 +308,7 @@ L2: 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 @@ Bytecode { 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 @@ Bytecode { } 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 @@ Bytecode { 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 @@ L2: 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 @@ L4: 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 cf8425ca3f9..f8010848b37 100644 --- a/pkg/vm/testcases/bytecode/closures.dart.expect +++ b/pkg/vm/testcases/bytecode/closures.dart.expect @@ -213,11 +213,11 @@ Bytecode { 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 @@ L2: 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 @@ L2: StoreFieldTOS CP#1 PopLocal r3 Push r3 - InstanceCall 1, CP#36 + DynamicCall 1, CP#36 Drop1 PushNull ReturnTOS @@ -522,69 +522,69 @@ Bytecode { 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 @@ ConstantPool { [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:: (dart:core::int y) -> dart:core::Null ClosureBytecode { @@ -663,30 +665,30 @@ ClosureBytecode { 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 @@ ClosureBytecode { Push r0 LoadContextParent LoadContextVar 0, 0 - InstanceCall 1, CP#8 + InterfaceCall 1, CP#8 Push r0 LoadContextVar 1, 0 AddInt @@ -735,7 +737,7 @@ ClosureBytecode { LoadContextVar 0, 0 Push r0 LoadContextVar 0, 3 - InstanceCall 2, CP#30 + InterfaceCall 2, CP#31 Drop1 PushNull ReturnTOS @@ -855,7 +857,7 @@ L2: 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 @@ L2: 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 @@ ConstantPool { [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:: () -> dart:core::int ClosureBytecode { @@ -952,11 +954,11 @@ ClosureBytecode { 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 @@ Bytecode { 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 @@ L1: } 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:: () -> 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 @@ Bytecode { PopLocal r2 Push r2 PushInt 3 - InstanceCall 2, CP#18 + DynamicCall 2, CP#18 Drop1 Push r0 LoadContextVar 0, 0 @@ -1359,20 +1364,20 @@ Bytecode { 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 @@ Bytecode { PushConstant CP#11 IndirectStaticCall 1, CP#3 Drop1 - InstanceCall 2, CP#12 + InterfaceCall 2, CP#6 Drop1 PushNull ReturnTOS @@ -1393,13 +1398,12 @@ ConstantPool { [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::A::foo}(); diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect index 233eed739b4..46496426256 100644 --- a/pkg/vm/testcases/bytecode/literals.dart.expect +++ b/pkg/vm/testcases/bytecode/literals.dart.expect @@ -483,15 +483,15 @@ Bytecode { 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 @@ ConstantPool { [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([1, a, 3]); @@ -561,29 +562,29 @@ Bytecode { 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 @@ Bytecode { 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 @@ ConstantPool { [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(core::int a, core::int b, self::test_map_literal::T c) → void { core::print({1: a, b: 2}); diff --git a/pkg/vm/testcases/bytecode/loops.dart.expect b/pkg/vm/testcases/bytecode/loops.dart.expect index b3714bd85ad..4fbdb3b28cf 100644 --- a/pkg/vm/testcases/bytecode/loops.dart.expect +++ b/pkg/vm/testcases/bytecode/loops.dart.expect @@ -14,13 +14,13 @@ L2: 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 @@ L1: } 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 list) → core::int { core::int sum = 0; @@ -62,7 +64,7 @@ L3: JumpIfFalse L1 Push r1 Push FP[-5] - InstanceCall 1, CP#1 + InterfaceCall 1, CP#1 CompareIntGe JumpIfFalse L2 Jump L1 @@ -70,7 +72,7 @@ L2: Push r0 Push FP[-5] Push r1 - InstanceCall 2, CP#3 + InterfaceCall 2, CP#4 AddInt PopLocal r0 Push r1 @@ -85,9 +87,11 @@ L1: } 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 list) → core::int { core::int sum = 0; @@ -113,7 +117,7 @@ L4: CheckStack 1 Push r1 Push FP[-5] - InstanceCall 1, CP#1 + InterfaceCall 1, CP#1 CompareIntLt JumpIfFalse L1 Push r1 @@ -125,7 +129,7 @@ L2: Push r0 Push FP[-5] Push r1 - InstanceCall 2, CP#3 + InterfaceCall 2, CP#4 AddInt PopLocal r0 L3: @@ -141,9 +145,11 @@ L1: } 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 list) → core::int { core::int sum = 0; @@ -169,7 +175,7 @@ L2: CheckStack 1 Push r1 Push FP[-5] - InstanceCall 1, CP#1 + InterfaceCall 1, CP#1 CompareIntLt JumpIfFalse L1 Push r0 @@ -182,7 +188,7 @@ L2: StoreLocal r1 PopLocal r3 Push r2 - InstanceCall 2, CP#3 + InterfaceCall 2, CP#4 AddInt PopLocal r0 Jump L2 @@ -192,9 +198,11 @@ L1: } 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 list) → core::int { core::int sum = 0; @@ -217,7 +225,7 @@ L1: Push r0 Push FP[-5] Push r1 - InstanceCall 2, CP#1 + InterfaceCall 2, CP#1 AddInt PopLocal r0 Push r1 @@ -226,7 +234,7 @@ L1: PopLocal r1 Push r1 Push FP[-5] - InstanceCall 1, CP#3 + InterfaceCall 1, CP#4 CompareIntLt JumpIfTrue L1 Push r0 @@ -234,9 +242,11 @@ L1: } 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 list) → core::int { core::int sum = 0; @@ -255,15 +265,15 @@ Bytecode { 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 @@ L1: } 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 list) → core::int { core::int sum = 0; @@ -296,15 +309,15 @@ Bytecode { 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 @@ L1: } 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 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 9ee6e1e94b8..346cd8a9184 100644 --- a/pkg/vm/testcases/bytecode/super_calls.dart.expect +++ b/pkg/vm/testcases/bytecode/super_calls.dart.expect @@ -132,7 +132,7 @@ Bytecode { PushConstant CP#2 IndirectStaticCall 1, CP#1 PushConstant CP#3 - InstanceCall 3, CP#5 + DynamicCall 3, CP#5 ReturnTOS } ConstantPool { @@ -347,7 +347,7 @@ Bytecode { 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 fe265d67112..93301c37c5f 100644 --- a/pkg/vm/testcases/bytecode/switch.dart.expect +++ b/pkg/vm/testcases/bytecode/switch.dart.expect @@ -12,15 +12,15 @@ Bytecode { 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 @@ L4: } 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 @@ Bytecode { 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 @@ L4: } 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 @@ Bytecode { 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 @@ L3: } 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 e50ba42426d..e946fb187f1 100644 --- a/pkg/vm/testcases/bytecode/try_blocks.dart.expect +++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect @@ -78,17 +78,17 @@ Try #0 handler: 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 @@ L2: L3: Push r0 PushConstant CP#13 - InstanceCall 2, CP#14 + InterfaceCall 2, CP#5 JumpIfFalse L4 Push r0 PopLocal r2 @@ -125,7 +125,7 @@ L3: StoreLocal r4 Push r4 PushInt 0 - PushConstant CP#15 + PushConstant CP#14 StoreIndexedTOS Push r4 PushInt 1 @@ -133,15 +133,15 @@ L3: 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 @@ L4: StoreLocal r4 Push r4 PushInt 0 - PushConstant CP#20 + PushConstant CP#19 StoreIndexedTOS Push r4 PushInt 1 @@ -164,15 +164,15 @@ L4: 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 @@ L1: 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 @@ ConstantPool { [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 @@ Try #0 start: 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 @@ ConstantPool { [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 @@ Try #0 handler: 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 @@ Try #0 handler: StoreLocal r5 Push r5 PushInt 0 - PushConstant CP#31 + PushConstant CP#32 StoreIndexedTOS Push r5 PushInt 1 @@ -454,17 +454,17 @@ Try #0 handler: 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 @@ Bytecode { 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 @@ Try #1 start: 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 @@ ExceptionsTable { } 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 @@ Try #0 handler: IndirectStaticCall 1, CP#3 Drop1 Push r2 - InstanceCall 1, CP#27 + DynamicCall 1, CP#27 Drop1 Push r3 Push r4 @@ -964,7 +964,7 @@ L1: 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 43203fc3b48..04a4e323850 100644 --- a/pkg/vm/testcases/bytecode/type_ops.dart.expect +++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect @@ -106,23 +106,23 @@ Bytecode { 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 @@ L2: PushNull PushConstant CP#12 AssertAssignable 0, CP#13 - InstanceCall 2, CP#15 + InterfaceCall 2, CP#15 Drop1 PushNull ReturnTOS @@ -142,19 +142,20 @@ ConstantPool { [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) { @@ -174,51 +175,52 @@ Bytecode { 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(dynamic z) → dynamic { if(z is self::A) { @@ -329,47 +331,49 @@ Bytecode { 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 9102f84e536..151429ae3e0 100644 --- a/runtime/vm/compiler/assembler/disassembler_kbc.cc +++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc @@ -214,7 +214,8 @@ static bool HasLoadFromPool(KBCInstr instr) { 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 20cb6a07f1d..a5723f9673b 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 @@ void BytecodeFlowGraphBuilder::BuildIndirectStaticCall() { 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 55f932f91bf..f24f40581e4 100644 --- a/runtime/vm/compiler/frontend/bytecode_reader.cc +++ b/runtime/vm/compiler/frontend/bytecode_reader.cc @@ -344,6 +344,7 @@ void BytecodeMetadataHelper::ReadConstantPool(const Function& function, kPartialTearOffInstantiation, kEmptyTypeArguments, kSymbol, + kInterfaceCall, }; enum InvocationKind { @@ -618,6 +619,22 @@ void BytecodeMetadataHelper::ReadConstantPool(const Function& function, 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 67772ab3505..15506e51360 100644 --- a/runtime/vm/constants_kbc.h +++ b/runtime/vm/constants_kbc.h @@ -271,7 +271,16 @@ namespace dart { // 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 @@ namespace dart { 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 @@ class KernelBytecode { 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 65a6f0dfd5f..23342d3fa60 100644 --- a/runtime/vm/dart_entry.h +++ b/runtime/vm/dart_entry.h @@ -86,7 +86,6 @@ class ArgumentsDescriptor : public ValueObject { enum { kTypeArgsLenIndex, kCountIndex, - kPositionalCountIndex, kFirstNamedEntryIndex, }; diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc index 1dcd875c6cd..23fe58646a7 100644 --- a/runtime/vm/heap/marker.cc +++ b/runtime/vm/heap/marker.cc @@ -479,6 +479,15 @@ class MarkingWeakVisitor : public HandleVisitor { 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 688dfeb3ccd..bdfec17f057 100644 --- a/runtime/vm/interpreter.cc +++ b/runtime/vm/interpreter.cc @@ -499,6 +499,66 @@ DART_FORCE_INLINE static RawFunction* FrameFunction(RawObject** FP) { 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(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(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 @@ void Interpreter::InitOnce() { } 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() Interpreter::~Interpreter() { delete[] stack_; + pp_ = NULL; + argdesc_ = NULL; #if defined(DEBUG) if (trace_file_ != NULL) { FlushTraceBuffer(); @@ -601,8 +663,10 @@ Interpreter::~Interpreter() { // 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 @@ void Interpreter::Exit(Thread* thread, #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(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 @@ void Interpreter::InlineCacheMiss(int checked_args, // 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(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(top[4]); + target_name = static_cast(top[2]); + argdesc_ = static_cast(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 @@ SwitchDispatch: } { - 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(LOAD_CONSTANT(kidx)); + argdesc_ = static_cast(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 4d4fd917e54..45d476e0ce0 100644 --- a/runtime/vm/interpreter.h +++ b/runtime/vm/interpreter.h @@ -27,6 +27,36 @@ class RawFunction; 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 @@ class Interpreter { } void VisitObjectPointers(ObjectPointerVisitor* visitor); + void MajorGC() { lookup_cache_.Clear(); } private: uintptr_t* stack_; @@ -115,6 +146,8 @@ class Interpreter { // 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 @@ class Interpreter { 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 @@ class Interpreter { 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 2829c768a87..2ae6c1899fe 100644 --- a/runtime/vm/runtime_entry.cc +++ b/runtime/vm/runtime_entry.cc @@ -1618,6 +1618,37 @@ DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) { #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 5bafc0e376a..fa97c63fb53 100644 --- a/runtime/vm/runtime_entry_list.h +++ b/runtime/vm/runtime_entry_list.h @@ -24,6 +24,7 @@ namespace dart { 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 b7a8f140e64..109ccd421b3 100644 --- a/runtime/vm/thread.cc +++ b/runtime/vm/thread.cc @@ -716,15 +716,15 @@ void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor, // 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;