blob: 289819b30f6e91cbb298f383d96ffc2f25f20bd6 [file] [log] [blame]
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:kernel/ast.dart';
class UnboxingInfoMetadata {
static const kBoxed = 0;
static const kUnboxedIntCandidate = 1 << 0;
static const kUnboxedDoubleCandidate = 1 << 1;
static const kUnboxingCandidate =
kUnboxedIntCandidate | kUnboxedDoubleCandidate;
final List<int> unboxedArgsInfo;
int returnInfo;
UnboxingInfoMetadata(int argsLen) : unboxedArgsInfo = [] {
for (int i = 0; i < argsLen; i++) {
unboxedArgsInfo.add(kUnboxingCandidate);
}
returnInfo = kUnboxingCandidate;
}
UnboxingInfoMetadata.readFromBinary(BinarySource source)
: unboxedArgsInfo = List<int>.generate(
source.readUInt(), (_) => source.readByte(),
growable: true),
returnInfo = source.readByte();
// Returns `true` if all arguments as well as the return value have to be
// boxed.
//
// We don't have to write out metadata for fully boxed methods, because this
// is the default.
bool get isFullyBoxed {
if (returnInfo != kBoxed) return false;
for (int argInfo in unboxedArgsInfo) {
if (argInfo != kBoxed) return false;
}
return true;
}
void writeToBinary(BinarySink sink) {
sink.writeUInt30(unboxedArgsInfo.length);
for (int val in unboxedArgsInfo) {
sink.writeByte(val);
}
sink.writeByte(returnInfo);
}
@override
String toString() {
final sb = StringBuffer();
sb.write('(');
for (int i = 0; i < unboxedArgsInfo.length; ++i) {
final argInfo = unboxedArgsInfo[i];
sb.write(_stringifyUnboxingInfo(argInfo));
if (i != (unboxedArgsInfo.length - 1)) {
sb.write(',');
}
}
sb.write(')');
sb.write('->');
sb.write(_stringifyUnboxingInfo(returnInfo));
return sb.toString();
}
static String _stringifyUnboxingInfo(int info) {
if (info == UnboxingInfoMetadata.kUnboxedIntCandidate) {
return 'i';
} else if (info == UnboxingInfoMetadata.kUnboxedDoubleCandidate) {
return 'd';
}
assert(info == 0);
return 'b';
}
}
class UnboxingInfoMetadataRepository
extends MetadataRepository<UnboxingInfoMetadata> {
static const repositoryTag = 'vm.unboxing-info.metadata';
@override
final String tag = repositoryTag;
@override
final Map<TreeNode, UnboxingInfoMetadata> mapping =
<TreeNode, UnboxingInfoMetadata>{};
@override
void writeToBinary(
UnboxingInfoMetadata metadata, Node node, BinarySink sink) {
metadata.writeToBinary(sink);
}
@override
UnboxingInfoMetadata readFromBinary(Node node, BinarySource source) {
return UnboxingInfoMetadata.readFromBinary(source);
}
}