-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[vm] Avoid local labels in assembly snapshots.
Labels starting with L are treated as local by the assembler and cause problems down the line. When targeting ARM64 Mach-O having local labels cause linker to break when trying to generate compact unwinding information with a cryptic error ld: too many compact unwind infos in function <...> This happens because local labels are not seen as function boundaries and multiple .cfi_startproc/.cfi_endproc are mashed into a single function. Fixes flutter/flutter#102281 TEST=runtime/tests/vm/dart{,_2}/no_local_labels_test.dart Change-Id: I0171dc08f49c71ccb1ca02b398e01ac241efd9a8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/241962 Reviewed-by: Daco Harkes <dacoharkes@google.com> Commit-Queue: Slava Egorov <vegorov@google.com>
- Loading branch information
Showing
3 changed files
with
168 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Copyright (c) 2022, 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. | ||
|
||
// This test verifies that assembly snapshot does not contain local labels. | ||
// (labels starting with 'L'). | ||
|
||
import 'dart:io'; | ||
|
||
import 'package:expect/expect.dart'; | ||
import 'package:path/path.dart' as path; | ||
|
||
import 'use_flag_test_helper.dart'; | ||
|
||
main(List<String> args) async { | ||
if (!isAOTRuntime) { | ||
return; // Running in JIT: AOT binaries not available. | ||
} | ||
|
||
if (Platform.isAndroid) { | ||
return; // SDK tree not available on the test device. | ||
} | ||
|
||
// These are the tools we need to be available to run on a given platform: | ||
if (!File(platformDill).existsSync()) { | ||
throw "Cannot run test as $platformDill does not exist"; | ||
} | ||
if (!await testExecutable(genSnapshot)) { | ||
throw "Cannot run test as $genSnapshot not available"; | ||
} | ||
|
||
await withTempDir('no-local-labels-test', (String tempDir) async { | ||
final script = path.join(tempDir, 'program.dart'); | ||
final scriptDill = path.join(tempDir, 'program.dill'); | ||
|
||
await File(script).writeAsString(''' | ||
class Local { | ||
@pragma('vm:never-inline') | ||
void foo() { | ||
} | ||
@pragma('vm:never-inline') | ||
void bar() { | ||
} | ||
} | ||
void main(List<String> args) { | ||
Local()..foo()..bar(); | ||
} | ||
'''); | ||
|
||
// Compile script to Kernel IR. | ||
await run(genKernel, <String>[ | ||
'--aot', | ||
'--platform=$platformDill', | ||
'-o', | ||
scriptDill, | ||
script, | ||
]); | ||
|
||
if (Platform.isWindows) { | ||
return; // No assembly generation on Windows. | ||
} | ||
|
||
final assembly = path.join(tempDir, 'program.S'); | ||
await run(genSnapshot, <String>[ | ||
'--snapshot-kind=app-aot-assembly', | ||
'--assembly=$assembly', | ||
scriptDill, | ||
]); | ||
|
||
final localLabelRe = RegExp(r'^L[a-zA-Z0-9_\.$]*:$', multiLine: true); | ||
final match = localLabelRe.firstMatch(await File(assembly).readAsString()); | ||
if (match != null) { | ||
Expect.isTrue(false, 'unexpected local label found ${match[0]!}'); | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Copyright (c) 2022, 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. | ||
|
||
// This test verifies that assembly snapshot does not contain local labels. | ||
// (labels starting with 'L'). | ||
|
||
// @dart=2.9 | ||
|
||
import 'dart:io'; | ||
|
||
import 'package:expect/expect.dart'; | ||
import 'package:path/path.dart' as path; | ||
|
||
import 'use_flag_test_helper.dart'; | ||
|
||
main(List<String> args) async { | ||
if (!isAOTRuntime) { | ||
return; // Running in JIT: AOT binaries not available. | ||
} | ||
|
||
if (Platform.isAndroid) { | ||
return; // SDK tree not available on the test device. | ||
} | ||
|
||
// These are the tools we need to be available to run on a given platform: | ||
if (!File(platformDill).existsSync()) { | ||
throw "Cannot run test as $platformDill does not exist"; | ||
} | ||
if (!await testExecutable(genSnapshot)) { | ||
throw "Cannot run test as $genSnapshot not available"; | ||
} | ||
|
||
await withTempDir('no-local-labels-test', (String tempDir) async { | ||
final script = path.join(tempDir, 'program.dart'); | ||
final scriptDill = path.join(tempDir, 'program.dill'); | ||
|
||
await File(script).writeAsString(''' | ||
class Local { | ||
@pragma('vm:never-inline') | ||
void foo() { | ||
} | ||
@pragma('vm:never-inline') | ||
void bar() { | ||
} | ||
} | ||
void main(List<String> args) { | ||
Local()..foo()..bar(); | ||
} | ||
'''); | ||
|
||
// Compile script to Kernel IR. | ||
await run(genKernel, <String>[ | ||
'--aot', | ||
'--platform=$platformDill', | ||
'-o', | ||
scriptDill, | ||
script, | ||
]); | ||
|
||
if (Platform.isWindows) { | ||
return; // No assembly generation on Windows. | ||
} | ||
|
||
final assembly = path.join(tempDir, 'program.S'); | ||
await run(genSnapshot, <String>[ | ||
'--snapshot-kind=app-aot-assembly', | ||
'--assembly=$assembly', | ||
scriptDill, | ||
]); | ||
|
||
final localLabelRe = RegExp(r'^L[a-zA-Z0-9_\.$]*:$', multiLine: true); | ||
final match = localLabelRe.firstMatch(await File(assembly).readAsString()); | ||
if (match != null) { | ||
Expect.isTrue(false, 'unexpected local label found ${match[0]}'); | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters