|
2 | 2 | // for details. All rights reserved. Use of this source code is governed by a |
3 | 3 | // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
|
| 5 | +import 'dart:typed_data'; |
| 6 | + |
5 | 7 | import 'package:kernel/ast.dart'; |
6 | 8 | import 'package:kernel/core_types.dart'; |
7 | 9 | import 'package:kernel/type_algebra.dart' |
@@ -69,8 +71,7 @@ class Constants { |
69 | 71 | final Translator translator; |
70 | 72 | final Map<Constant, ConstantInfo> constantInfo = {}; |
71 | 73 | final Map<Constant, ConstantInfo> dynamicModuleConstantInfo = {}; |
72 | | - w.DataSegmentBuilder? oneByteStringSegment; |
73 | | - w.DataSegmentBuilder? twoByteStringSegment; |
| 74 | + w.DataSegmentBuilder? int32Segment; |
74 | 75 | late final ClassInfo typeInfo = translator.classInfo[translator.typeClass]!; |
75 | 76 |
|
76 | 77 | final Map<DartType, InstanceConstant> _loweredTypeConstants = {}; |
@@ -673,6 +674,37 @@ class ConstantCreator extends ConstantVisitor<ConstantInfo?> |
673 | 674 | return createConstant(constant, w.RefType.def(arrayType, nullable: false), |
674 | 675 | lazy: lazy, (b) { |
675 | 676 | if (tooLargeForArrayNewFixed) { |
| 677 | + // We use WasmArray<WasmI32> for some RTT data structures. Those arrays |
| 678 | + // can get rather large and cross the 10k limit. |
| 679 | + // |
| 680 | + // If so, we prefer to initialize the array from data section over |
| 681 | + // emitting a *lot* of code to store individual array elements. |
| 682 | + // |
| 683 | + // This can be a little bit larger than individual array stores, but the |
| 684 | + // data section will compress better, so for app.wasm.gz it'a a win and |
| 685 | + // will cause much faster validation & faster initialization. |
| 686 | + if (arrayType.elementType.type == w.NumType.i32) { |
| 687 | + // Initialize array contents from passive data segment. |
| 688 | + final w.DataSegmentBuilder segment = |
| 689 | + constants.int32Segment ??= targetModule.dataSegments.define(); |
| 690 | + |
| 691 | + final field = translator.wasmI32Value.fieldReference; |
| 692 | + |
| 693 | + final list = Uint32List(elements.length); |
| 694 | + for (int i = 0; i < list.length; ++i) { |
| 695 | + // The constant is a `const WasmI32 {WasmI32._value: <XXX>}` |
| 696 | + final constant = elements[i] as InstanceConstant; |
| 697 | + assert(constant.classNode == translator.wasmI32Class); |
| 698 | + list[i] = (constant.fieldValues[field] as IntConstant).value; |
| 699 | + } |
| 700 | + final offset = segment.length; |
| 701 | + segment.append(list.buffer.asUint8List()); |
| 702 | + b.i32_const(offset); |
| 703 | + b.i32_const(elements.length); |
| 704 | + b.array_new_data(arrayType, segment); |
| 705 | + return; |
| 706 | + } |
| 707 | + |
676 | 708 | // We will initialize the array with one of the elements (using |
677 | 709 | // `array.new`) and update the fields. |
678 | 710 | // |
|
0 commit comments