[dart2wasm] Canonicalize boxed constant values

This saves space for the constant values, since the same value will
use the same constant box object, and it avoids runtime allocation of
boxes for literal values that are boxed directly.

New passing tests:

- language/super/bound_closure_test/01
- co19/LanguageFeatures/Patterns/constant_A05_t01
- co19/LibTest/collection/ListBase/ListBase_class_A01_t03
- co19/LibTest/collection/ListBase/ListBase_class_A01_t04
- co19/LibTest/collection/ListBase/ListBase_class_A01_t05
- co19/LibTest/collection/ListBase/ListBase_class_A01_t06
- co19/LibTest/collection/ListMixin/ListMixin_class_A01_t03
- co19/LibTest/collection/ListMixin/ListMixin_class_A01_t04
- co19/LibTest/collection/ListMixin/ListMixin_class_A01_t05
- co19/LibTest/collection/ListMixin/ListMixin_class_A01_t06
- co19/LibTest/core/List/List_all_t03
- co19/LibTest/core/List/List_all_t04
- co19/LibTest/core/List/List_all_t05
- co19/LibTest/core/List/List_all_t06

Change-Id: Id7570a2dd16f02590e722115e4d7168c4a741d99
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/273843
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
This commit is contained in:
Aske Simon Christensen 2022-12-08 22:11:32 +00:00 committed by Commit Queue
parent 5dca4cbd42
commit e38242621d
2 changed files with 48 additions and 28 deletions

View file

@ -2389,20 +2389,23 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
@override
w.ValueType visitBoolLiteral(BoolLiteral node, w.ValueType expectedType) {
b.i32_const(node.value ? 1 : 0);
return w.NumType.i32;
translator.constants.instantiateConstant(
function, b, BoolConstant(node.value), expectedType);
return expectedType;
}
@override
w.ValueType visitIntLiteral(IntLiteral node, w.ValueType expectedType) {
b.i64_const(node.value);
return w.NumType.i64;
translator.constants.instantiateConstant(
function, b, IntConstant(node.value), expectedType);
return expectedType;
}
@override
w.ValueType visitDoubleLiteral(DoubleLiteral node, w.ValueType expectedType) {
b.f64_const(node.value);
return w.NumType.f64;
translator.constants.instantiateConstant(
function, b, DoubleConstant(node.value), expectedType);
return expectedType;
}
@override

View file

@ -204,38 +204,25 @@ class ConstantInstantiator extends ConstantVisitor<w.ValueType> {
return const w.RefType.none(nullable: true);
}
w.ValueType _maybeBox(w.ValueType wasmType, void Function() pushValue) {
if (expectedType is w.RefType) {
ClassInfo info = translator.classInfo[translator.boxedClasses[wasmType]]!;
b.i32_const(info.classId);
pushValue();
b.struct_new(info.struct);
return info.nonNullableType;
} else {
pushValue();
return wasmType;
}
}
@override
w.ValueType visitBoolConstant(BoolConstant constant) {
return _maybeBox(w.NumType.i32, () {
b.i32_const(constant.value ? 1 : 0);
});
if (expectedType is w.RefType) return defaultConstant(constant);
b.i32_const(constant.value ? 1 : 0);
return w.NumType.i32;
}
@override
w.ValueType visitIntConstant(IntConstant constant) {
return _maybeBox(w.NumType.i64, () {
b.i64_const(constant.value);
});
if (expectedType is w.RefType) return defaultConstant(constant);
b.i64_const(constant.value);
return w.NumType.i64;
}
@override
w.ValueType visitDoubleConstant(DoubleConstant constant) {
return _maybeBox(w.NumType.f64, () {
b.f64_const(constant.value);
});
if (expectedType is w.RefType) return defaultConstant(constant);
b.f64_const(constant.value);
return w.NumType.f64;
}
}
@ -296,6 +283,36 @@ class ConstantCreator extends ConstantVisitor<ConstantInfo?> {
@override
ConstantInfo? defaultConstant(Constant constant) => null;
@override
ConstantInfo? visitBoolConstant(BoolConstant constant) {
ClassInfo info = translator.classInfo[translator.boxedBoolClass]!;
return createConstant(constant, info.nonNullableType, (function, b) {
b.i32_const(info.classId);
b.i32_const(constant.value ? 1 : 0);
b.struct_new(info.struct);
});
}
@override
ConstantInfo? visitIntConstant(IntConstant constant) {
ClassInfo info = translator.classInfo[translator.boxedIntClass]!;
return createConstant(constant, info.nonNullableType, (function, b) {
b.i32_const(info.classId);
b.i64_const(constant.value);
b.struct_new(info.struct);
});
}
@override
ConstantInfo? visitDoubleConstant(DoubleConstant constant) {
ClassInfo info = translator.classInfo[translator.boxedDoubleClass]!;
return createConstant(constant, info.nonNullableType, (function, b) {
b.i32_const(info.classId);
b.f64_const(constant.value);
b.struct_new(info.struct);
});
}
@override
ConstantInfo? visitStringConstant(StringConstant constant) {
bool isOneByte = constant.value.codeUnits.every((c) => c <= 255);