[vm/kernel/bytecode] Add library reference and invocation kind to ConstantICData

Library reference is added for private names in order to resolve them correctly.
Invocation kind byte supersedes VM-specific name mangling and makes
ConstantICData more uniform with ConstantStaticICData.

Change-Id: I66542356209d98b3d0cf0e6b8eb19bda052c6b7e
Reviewed-on: https://dart-review.googlesource.com/57485
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
This commit is contained in:
Alexander Markov 2018-05-31 00:53:21 +00:00 committed by commit-bot@chromium.org
parent a53b585498
commit 377eb52f5a
8 changed files with 88 additions and 67 deletions

View file

@ -5620,6 +5620,7 @@ abstract class BinarySink {
void writeCanonicalNameReference(CanonicalName name);
void writeStringReference(String str);
void writeName(Name node);
void writeDartType(DartType type);
void writeNode(Node node);
@ -5646,6 +5647,7 @@ abstract class BinarySource {
CanonicalName readCanonicalNameReference();
String readStringReference();
Name readName();
DartType readDartType();
FunctionNode readFunctionNode();

View file

@ -57,18 +57,19 @@ type ConstantArgDesc extends ConstantPoolEntry {
List<StringReference> names;
}
type ConstantICData extends ConstantPoolEntry {
Byte tag = 7;
StringReference targetName;
ConstantIndex argDesc;
}
enum InvocationKind {
method, // x.foo(...) or foo(...)
getter, // x.foo
setter // x.foo = ...
}
type ConstantICData extends ConstantPoolEntry {
Byte tag = 7;
Byte invocationKind; // Index in InvocationKind enum.
Name targetName;
ConstantIndex argDesc;
}
type ConstantStaticICData extends ConstantPoolEntry {
Byte tag = 8;
Byte invocationKind; // Index in InvocationKind enum.
@ -442,28 +443,46 @@ class ConstantArgDesc extends ConstantPoolEntry {
listEquals(this.argNames, other.argNames);
}
enum InvocationKind { method, getter, setter }
String _invocationKindToString(InvocationKind kind) {
switch (kind) {
case InvocationKind.method:
return '';
case InvocationKind.getter:
return 'get ';
case InvocationKind.setter:
return 'set ';
}
throw 'Unexpected InvocationKind $kind';
}
class ConstantICData extends ConstantPoolEntry {
final String targetName;
final InvocationKind invocationKind;
final Name targetName;
final int argDescConstantIndex;
ConstantICData(this.targetName, this.argDescConstantIndex);
ConstantICData(
this.invocationKind, this.targetName, this.argDescConstantIndex);
@override
ConstantTag get tag => ConstantTag.kICData;
@override
void writeValueToBinary(BinarySink sink) {
sink.writeStringReference(targetName);
sink.writeByte(invocationKind.index);
sink.writeName(targetName);
sink.writeUInt30(argDescConstantIndex);
}
ConstantICData.readFromBinary(BinarySource source)
: targetName = source.readStringReference(),
: invocationKind = InvocationKind.values[source.readByte()],
targetName = source.readName(),
argDescConstantIndex = source.readUInt();
@override
String toString() =>
'ICData target-name \'$targetName\', arg-desc CP#$argDescConstantIndex';
String toString() => 'ICData ${_invocationKindToString(invocationKind)}'
'target-name \'$targetName\', arg-desc CP#$argDescConstantIndex';
// ConstantICData entries are created per call site and should not be merged,
// so ConstantICData class uses identity [hashCode] and [operator ==].
@ -475,8 +494,6 @@ class ConstantICData extends ConstantPoolEntry {
bool operator ==(other) => identical(this, other);
}
enum InvocationKind { method, getter, setter }
class ConstantStaticICData extends ConstantPoolEntry {
final InvocationKind invocationKind;
final Reference _reference;
@ -508,11 +525,7 @@ class ConstantStaticICData extends ConstantPoolEntry {
argDescConstantIndex = source.readUInt();
@override
String toString() =>
'StaticICData ' +
(invocationKind == InvocationKind.getter
? 'get '
: (invocationKind == InvocationKind.setter ? 'set ' : '')) +
String toString() => 'StaticICData ${_invocationKindToString(invocationKind)}'
'target \'$target\', arg-desc CP#$argDescConstantIndex';
// ConstantStaticICData entries are created per call site and should not be

View file

@ -644,14 +644,6 @@ const Map<Opcode, Format> BytecodeFormats = const {
// Should match constant in runtime/vm/stack_frame_dbc.h.
const int kParamEndSlotFromFp = 4;
// Prefix used to distinguish getters in ICData target names.
// Should match constant in runtime/vm/object.cc.
const String kGetterPrefix = 'get:';
// Prefix used to distinguish setters in ICData target names.
// Should match constant in runtime/vm/object.cc.
const String kSetterPrefix = 'set:';
enum SpecialIndex {
exception,
stackTrace,

View file

@ -155,6 +155,14 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
Class get closureClass =>
_closureClass ??= libraryIndex.getClass('dart:core', '_Closure');
Procedure _objectInstanceOf;
Procedure get objectInstanceOf => _objectInstanceOf ??=
libraryIndex.getMember('dart:core', 'Object', '_instanceOf');
Procedure _objectAs;
Procedure get objectAs =>
_objectAs ??= libraryIndex.getMember('dart:core', 'Object', '_as');
Field _closureInstantiatorTypeArguments;
Field get closureInstantiatorTypeArguments =>
_closureInstantiatorTypeArguments ??= libraryIndex.getMember(
@ -422,7 +430,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
}
asm.emitPushConstant(cp.add(new ConstantType(type)));
final argDescIndex = cp.add(new ConstantArgDesc(4));
final icdataIndex = cp.add(new ConstantICData('_instanceOf', argDescIndex));
final icdataIndex = cp.add(new ConstantICData(
InvocationKind.method, objectInstanceOf.name, argDescIndex));
asm.emitInstanceCall1(4, icdataIndex);
}
@ -770,7 +779,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
final typeIndex = cp.add(new ConstantType(node.type));
asm.emitPushConstant(typeIndex);
final argDescIndex = cp.add(new ConstantArgDesc(4));
final icdataIndex = cp.add(new ConstantICData('_as', argDescIndex));
final icdataIndex = cp.add(
new ConstantICData(InvocationKind.method, objectAs.name, argDescIndex));
asm.emitInstanceCall1(4, icdataIndex);
}
@ -1000,8 +1010,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
// TODO(alexmarkov): fast path smi ops
final argDescIndex =
cp.add(new ConstantArgDesc.fromArguments(args, hasReceiver: true));
final icdataIndex =
cp.add(new ConstantICData(node.name.name, argDescIndex));
final icdataIndex = cp.add(
new ConstantICData(InvocationKind.method, node.name, argDescIndex));
// TODO(alexmarkov): figure out when generate InstanceCall2 (2 checked arguments).
asm.emitInstanceCall1(
args.positional.length + args.named.length + 1, icdataIndex);
@ -1012,7 +1022,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
node.receiver.accept(this);
final argDescIndex = cp.add(new ConstantArgDesc(1));
final icdataIndex = cp.add(
new ConstantICData('$kGetterPrefix${node.name.name}', argDescIndex));
new ConstantICData(InvocationKind.getter, node.name, argDescIndex));
asm.emitInstanceCall1(1, icdataIndex);
}
@ -1024,7 +1034,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
asm.emitStoreLocal(temp);
final argDescIndex = cp.add(new ConstantArgDesc(2));
final icdataIndex = cp.add(
new ConstantICData('$kSetterPrefix${node.name.name}', argDescIndex));
new ConstantICData(InvocationKind.setter, node.name, argDescIndex));
asm.emitInstanceCall1(2, icdataIndex);
asm.emitDrop1();
asm.emitPush(temp);
@ -1356,8 +1366,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
asm.emitInstanceCall1(
1,
cp.add(new ConstantICData(
'$kGetterPrefix$kIterator', cp.add(new ConstantArgDesc(1)))));
cp.add(new ConstantICData(InvocationKind.getter, new Name(kIterator),
cp.add(new ConstantArgDesc(1)))));
final iteratorTemp = locals.tempIndexInFrame(node);
asm.emitPopLocal(iteratorTemp);
@ -1369,8 +1379,10 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
asm.emitCheckStack();
asm.emitPush(iteratorTemp);
asm.emitInstanceCall1(1,
cp.add(new ConstantICData(kMoveNext, cp.add(new ConstantArgDesc(1)))));
asm.emitInstanceCall1(
1,
cp.add(new ConstantICData(InvocationKind.method, new Name(kMoveNext),
cp.add(new ConstantArgDesc(1)))));
_genJumpIfFalse(/* negated = */ false, done);
_enterScope(node);
@ -1380,8 +1392,8 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
asm.emitPush(iteratorTemp);
asm.emitInstanceCall1(
1,
cp.add(new ConstantICData(
'$kGetterPrefix$kCurrent', cp.add(new ConstantArgDesc(1)))));
cp.add(new ConstantICData(InvocationKind.getter, new Name(kCurrent),
cp.add(new ConstantArgDesc(1)))));
_genStoreVar(node.variable);
@ -1509,7 +1521,9 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
asm.emitPush(temp);
_genPushConstExpr(expr);
asm.emitInstanceCall2(
2, cp.add(new ConstantICData('==', equalsArgDesc)));
2,
cp.add(new ConstantICData(
InvocationKind.method, new Name('=='), equalsArgDesc)));
_genJumpIfTrue(/* negated = */ false, caseLabel);
}
}

View file

@ -628,7 +628,7 @@ ConstantPool {
[13] = ClosureFunction closure2 () → void;
[14] = ICData target-name '+', arg-desc CP#7
[15] = ArgDesc num-args 1, num-type-args 0, names []
[16] = ICData target-name 'get:foo', arg-desc CP#15
[16] = ICData get target-name 'foo', arg-desc CP#15
[17] = ICData target-name '+', arg-desc CP#7
[18] = Null
[19] = EndClosureFunctionScope
@ -648,7 +648,7 @@ ConstantPool {
[33] = StaticICData target 'dart.core::print', arg-desc CP#15
[34] = Int 42
[35] = ClosureFunction <anonymous closure> () → dart.core::Null;
[36] = ICData target-name 'set:foo', arg-desc CP#7
[36] = ICData set target-name 'foo', arg-desc CP#7
[37] = EndClosureFunctionScope
[38] = ICData target-name 'call', arg-desc CP#15
}
@ -1090,11 +1090,11 @@ L1:
}
ConstantPool {
[0] = ArgDesc num-args 1, num-type-args 0, names []
[1] = ICData target-name 'get:iterator', arg-desc CP#0
[1] = ICData get target-name 'iterator', arg-desc CP#0
[2] = ICData target-name 'moveNext', arg-desc CP#0
[3] = Bool true
[4] = ContextOffset parent
[5] = ICData target-name 'get:current', arg-desc CP#0
[5] = ICData get target-name 'current', arg-desc CP#0
[6] = ContextOffset var [0]
[7] = ClosureFunction <anonymous closure> () → dart.core::Null;
[8] = FieldOffset dart.core::_Closure::_context

View file

@ -41,7 +41,7 @@ L1:
ConstantPool {
[0] = Int 0
[1] = ArgDesc num-args 1, num-type-args 0, names []
[2] = ICData target-name 'get:length', arg-desc CP#1
[2] = ICData get target-name 'length', arg-desc CP#1
[3] = ArgDesc num-args 2, num-type-args 0, names []
[4] = ICData target-name '<', arg-desc CP#3
[5] = Bool true
@ -108,7 +108,7 @@ ConstantPool {
[2] = ICData target-name '>=', arg-desc CP#1
[3] = Bool true
[4] = ArgDesc num-args 1, num-type-args 0, names []
[5] = ICData target-name 'get:length', arg-desc CP#4
[5] = ICData get target-name 'length', arg-desc CP#4
[6] = ICData target-name '>=', arg-desc CP#1
[7] = ICData target-name '[]', arg-desc CP#1
[8] = ICData target-name '+', arg-desc CP#1
@ -178,7 +178,7 @@ ConstantPool {
[1] = Int 100
[2] = ArgDesc num-args 1, num-type-args 0, names []
[3] = ICData target-name 'unary-', arg-desc CP#2
[4] = ICData target-name 'get:length', arg-desc CP#2
[4] = ICData get target-name 'length', arg-desc CP#2
[5] = ArgDesc num-args 2, num-type-args 0, names []
[6] = ICData target-name '<', arg-desc CP#5
[7] = Bool true
@ -242,7 +242,7 @@ L1:
ConstantPool {
[0] = Int 0
[1] = ArgDesc num-args 1, num-type-args 0, names []
[2] = ICData target-name 'get:length', arg-desc CP#1
[2] = ICData get target-name 'length', arg-desc CP#1
[3] = ArgDesc num-args 2, num-type-args 0, names []
[4] = ICData target-name '<', arg-desc CP#3
[5] = Bool true
@ -302,7 +302,7 @@ ConstantPool {
[4] = Int 1
[5] = ICData target-name '+', arg-desc CP#1
[6] = ArgDesc num-args 1, num-type-args 0, names []
[7] = ICData target-name 'get:length', arg-desc CP#6
[7] = ICData get target-name 'length', arg-desc CP#6
[8] = ICData target-name '<', arg-desc CP#1
[9] = Bool true
[10] = Null
@ -351,10 +351,10 @@ L1:
ConstantPool {
[0] = Int 0
[1] = ArgDesc num-args 1, num-type-args 0, names []
[2] = ICData target-name 'get:iterator', arg-desc CP#1
[2] = ICData get target-name 'iterator', arg-desc CP#1
[3] = ICData target-name 'moveNext', arg-desc CP#1
[4] = Bool true
[5] = ICData target-name 'get:current', arg-desc CP#1
[5] = ICData get target-name 'current', arg-desc CP#1
[6] = ArgDesc num-args 2, num-type-args 0, names []
[7] = ICData target-name '+', arg-desc CP#6
[8] = Null
@ -406,10 +406,10 @@ ConstantPool {
[0] = Int 0
[1] = Int 42
[2] = ArgDesc num-args 1, num-type-args 0, names []
[3] = ICData target-name 'get:iterator', arg-desc CP#2
[3] = ICData get target-name 'iterator', arg-desc CP#2
[4] = ICData target-name 'moveNext', arg-desc CP#2
[5] = Bool true
[6] = ICData target-name 'get:current', arg-desc CP#2
[6] = ICData get target-name 'current', arg-desc CP#2
[7] = ArgDesc num-args 2, num-type-args 0, names []
[8] = ICData target-name '+', arg-desc CP#7
[9] = Null

View file

@ -204,12 +204,12 @@ ConstantPool {
[3] = Type dart.core::TypeError
[4] = Null
[5] = ArgDesc num-args 4, num-type-args 0, names []
[6] = ICData target-name '_instanceOf', arg-desc CP#5
[6] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#5
[7] = Bool true
[8] = String 'caught type error'
[9] = StaticICData target 'dart.core::print', arg-desc CP#1
[10] = Type dart.core::AssertionError
[11] = ICData target-name '_instanceOf', arg-desc CP#5
[11] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#5
[12] = Int 2
[13] = Int 0
[14] = String 'caught assertion error '
@ -217,7 +217,7 @@ ConstantPool {
[16] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#1
[17] = StaticICData target 'dart.core::print', arg-desc CP#1
[18] = Type dart.core::Error
[19] = ICData target-name '_instanceOf', arg-desc CP#5
[19] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#5
[20] = Int 4
[21] = String 'caught error '
[22] = String ' '
@ -404,7 +404,7 @@ ConstantPool {
[28] = StaticICData target 'dart.core::print', arg-desc CP#7
[29] = Type dart.core::Error
[30] = ArgDesc num-args 4, num-type-args 0, names []
[31] = ICData target-name '_instanceOf', arg-desc CP#30
[31] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#30
[32] = Bool true
[33] = String 'error '
[34] = String ', captured stack trace: '

View file

@ -133,17 +133,17 @@ ConstantPool {
[1] = Null
[2] = Type #lib::A<#lib::D::P>
[3] = ArgDesc num-args 4, num-type-args 0, names []
[4] = ICData target-name '_instanceOf', arg-desc CP#3
[4] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#3
[5] = Bool true
[6] = String '21'
[7] = ArgDesc num-args 1, num-type-args 0, names []
[8] = StaticICData target 'dart.core::print', arg-desc CP#7
[9] = Type #lib::C<dynamic, #lib::D::Q, dart.core::List<#lib::D::P>>
[10] = ICData target-name '_instanceOf', arg-desc CP#3
[10] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#3
[11] = String '22'
[12] = StaticICData target 'dart.core::print', arg-desc CP#7
[13] = ArgDesc num-args 2, num-type-args 0, names []
[14] = ICData target-name 'set:foo', arg-desc CP#13
[14] = ICData set target-name 'foo', arg-desc CP#13
}
] method foo2(dynamic y) → dynamic {
if(y is self::A<self::D::P>) {
@ -201,18 +201,18 @@ ConstantPool {
[0] = TypeArgumentsFieldOffset #lib::D
[1] = Type #lib::A<#lib::D::foo3::T1>
[2] = ArgDesc num-args 4, num-type-args 0, names []
[3] = ICData target-name '_instanceOf', arg-desc CP#2
[3] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#2
[4] = Bool true
[5] = String '31'
[6] = ArgDesc num-args 1, num-type-args 0, names []
[7] = StaticICData target 'dart.core::print', arg-desc CP#6
[8] = Type #lib::C<dart.core::Map<#lib::D::foo3::T1, #lib::D::P>, dart.core::List<#lib::D::foo3::T2>, #lib::D::Q>
[9] = ICData target-name '_instanceOf', arg-desc CP#2
[9] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#2
[10] = String '32'
[11] = StaticICData target 'dart.core::print', arg-desc CP#6
[12] = Type dart.core::Map<#lib::D::foo3::T2, #lib::D::Q>
[13] = ICData target-name '_as', arg-desc CP#2
[14] = ICData target-name 'get:values', arg-desc CP#6
[13] = ICData target-name 'dart.core::_as', arg-desc CP#2
[14] = ICData get target-name 'values', arg-desc CP#6
[15] = Null
}
] method foo3<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic>(dynamic z) → dynamic {
@ -268,17 +268,17 @@ ConstantPool {
[0] = Null
[1] = Type #lib::B
[2] = ArgDesc num-args 4, num-type-args 0, names []
[3] = ICData target-name '_instanceOf', arg-desc CP#2
[3] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#2
[4] = Bool true
[5] = String '11'
[6] = ArgDesc num-args 1, num-type-args 0, names []
[7] = StaticICData target 'dart.core::print', arg-desc CP#6
[8] = Type #lib::C<dart.core::int, dart.core::Object, dynamic>
[9] = ICData target-name '_instanceOf', arg-desc CP#2
[9] = ICData target-name 'dart.core::_instanceOf', arg-desc CP#2
[10] = String '12'
[11] = StaticICData target 'dart.core::print', arg-desc CP#6
[12] = Type #lib::A<dart.core::int>
[13] = ICData target-name '_as', arg-desc CP#2
[13] = ICData target-name 'dart.core::_as', arg-desc CP#2
}
]static method foo1(dynamic x) → dynamic {
if(x is self::B) {