|
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:convert'; |
6 |
| -import 'dart:io'; |
7 |
| -import 'dart:async'; |
| 5 | +// This test verifies that vm:align-loops pragma works as expected. |
| 6 | +// |
| 7 | +// * This test should run without crashing in AOT mode. |
| 8 | +// * `align_loops_verify_alignment_test.dart` will AOT compile this test |
| 9 | +// and then verify that [alignedFunction1] and [alignedFunction2] are |
| 10 | +// aligned. |
8 | 11 |
|
9 |
| -import 'package:expect/expect.dart'; |
10 |
| -import 'package:native_stack_traces/elf.dart'; |
11 |
| -import 'package:path/path.dart' as path; |
| 12 | +import 'dart:typed_data'; |
12 | 13 |
|
13 |
| -import 'use_flag_test_helper.dart'; |
| 14 | +// Having a static call to this function verifies that relocation works |
| 15 | +// as expected even when caller needs to be aligned. |
| 16 | +@pragma('vm:never-inline') |
| 17 | +void printOk() { |
| 18 | + print("ok"); |
| 19 | +} |
14 | 20 |
|
15 |
| -void checkAligned(Symbol sym) { |
16 |
| - // We only expect to run this test on X64 Linux. |
17 |
| - final expectedAlignment = 32; |
18 |
| - if ((sym.value & (expectedAlignment - 1)) != 0) { |
19 |
| - throw 'Symbol $sym has value ${sym.value} which is not aligned by ' |
20 |
| - '$expectedAlignment'; |
| 21 | +@pragma('vm:never-inline') |
| 22 | +int foo(Uint8List list) { |
| 23 | + printOk(); |
| 24 | + var result = 0; |
| 25 | + for (var i = 0; i < list.length; i++) { |
| 26 | + result ^= list[i]; |
21 | 27 | }
|
| 28 | + printOk(); |
| 29 | + return result; |
22 | 30 | }
|
23 | 31 |
|
24 |
| -Future<void> testAOT(String dillPath, {bool useAsm = false}) async { |
25 |
| - await withTempDir('align-loops-test-${useAsm ? 'asm' : 'elf'}', |
26 |
| - (String tempDir) async { |
27 |
| - // Generate the snapshot |
28 |
| - final snapshotPath = path.join(tempDir, 'libtest.so'); |
29 |
| - final commonSnapshotArgs = [dillPath]; |
30 |
| - |
31 |
| - if (useAsm) { |
32 |
| - final assemblyPath = path.join(tempDir, 'test.S'); |
33 |
| - |
34 |
| - await run(genSnapshot, <String>[ |
35 |
| - '--snapshot-kind=app-aot-assembly', |
36 |
| - '--assembly=$assemblyPath', |
37 |
| - ...commonSnapshotArgs, |
38 |
| - ]); |
39 |
| - |
40 |
| - await assembleSnapshot(assemblyPath, snapshotPath); |
41 |
| - } else { |
42 |
| - await run(genSnapshot, <String>[ |
43 |
| - '--snapshot-kind=app-aot-elf', |
44 |
| - '--elf=$snapshotPath', |
45 |
| - ...commonSnapshotArgs, |
46 |
| - ]); |
47 |
| - } |
48 |
| - |
49 |
| - print("Snapshot generated at $snapshotPath."); |
50 |
| - |
51 |
| - final elf = Elf.fromFile(snapshotPath)!; |
52 |
| - // The very first symbol should be aligned by 32 bytes because it is |
53 |
| - // the start of the instructions section. |
54 |
| - checkAligned(elf.staticSymbols.first); |
55 |
| - for (var symbol in elf.staticSymbols) { |
56 |
| - if (symbol.name.startsWith('alignedFunction')) { |
57 |
| - checkAligned(symbol); |
58 |
| - } |
59 |
| - } |
60 |
| - }); |
| 32 | +@pragma('vm:never-inline') |
| 33 | +@pragma('vm:align-loops') |
| 34 | +int alignedFunction1(Uint8List list) { |
| 35 | + printOk(); |
| 36 | + var result = 0; |
| 37 | + for (var i = 0; i < list.length; i++) { |
| 38 | + result ^= list[i]; |
| 39 | + } |
| 40 | + printOk(); |
| 41 | + return result; |
61 | 42 | }
|
62 | 43 |
|
63 |
| -void main() async { |
64 |
| - // Only run this test on Linux X64 for simplicity. |
65 |
| - if (!(Platform.isLinux && buildDir.endsWith('X64'))) { |
66 |
| - return; |
| 44 | +@pragma('vm:never-inline') |
| 45 | +int baz(Uint8List list) { |
| 46 | + printOk(); |
| 47 | + var result = 1; |
| 48 | + for (var i = 0; i < list.length; i++) { |
| 49 | + result ^= list[i]; |
67 | 50 | }
|
| 51 | + printOk(); |
| 52 | + return result; |
| 53 | +} |
68 | 54 |
|
69 |
| - await withTempDir('align_loops', (String tempDir) async { |
70 |
| - final testProgram = path.join(sdkDir, 'runtime', 'tests', 'vm', 'dart', |
71 |
| - 'align_loops_test_program.dart'); |
72 |
| - |
73 |
| - final aotDillPath = path.join(tempDir, 'aot_test.dill'); |
74 |
| - await run(genKernel, <String>[ |
75 |
| - '--aot', |
76 |
| - '--platform', |
77 |
| - platformDill, |
78 |
| - ...Platform.executableArguments |
79 |
| - .where((arg) => arg.startsWith('--enable-experiment=')), |
80 |
| - '-o', |
81 |
| - aotDillPath, |
82 |
| - testProgram |
83 |
| - ]); |
| 55 | +@pragma('vm:never-inline') |
| 56 | +@pragma('vm:align-loops') |
| 57 | +int alignedFunction2(Uint8List list) { |
| 58 | + printOk(); |
| 59 | + var result = 2; |
| 60 | + for (var i = 0; i < list.length; i++) { |
| 61 | + result ^= list[i]; |
| 62 | + } |
| 63 | + printOk(); |
| 64 | + return result; |
| 65 | +} |
84 | 66 |
|
85 |
| - await Future.wait([ |
86 |
| - // Test unstripped ELF generation directly. |
87 |
| - testAOT(aotDillPath), |
88 |
| - testAOT(aotDillPath, useAsm: true), |
89 |
| - ]); |
90 |
| - }); |
| 67 | +void main(List<String> args) { |
| 68 | + final v = Uint8List(10); |
| 69 | + foo(v); |
| 70 | + alignedFunction1(v); |
| 71 | + baz(v); |
| 72 | + alignedFunction2(v); |
91 | 73 | }
|
0 commit comments