Version 2.17.0-182.0.dev Merge commit '5f0afa0ac45f5c3c3e691803dd2e95d40d91a6a0' into 'dev'
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart index 1350c46..12ae415 100644 --- a/pkg/analysis_server/lib/src/analysis_server.dart +++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -703,8 +703,9 @@ @override void applyFileRemoved(String file) { - sendAnalysisNotificationFlushResults(analysisServer, [file]); - filesToFlush.remove(file); + if (filesToFlush.remove(file)) { + sendAnalysisNotificationFlushResults(analysisServer, [file]); + } } @override
diff --git a/pkg/analysis_server/lib/src/utilities/mocks.dart b/pkg/analysis_server/lib/src/utilities/mocks.dart index bef5102..6ad7371 100644 --- a/pkg/analysis_server/lib/src/utilities/mocks.dart +++ b/pkg/analysis_server/lib/src/utilities/mocks.dart
@@ -23,7 +23,7 @@ StreamController<Response> responseController = StreamController<Response>.broadcast(); StreamController<Notification> notificationController = - StreamController<Notification>(sync: true); + StreamController<Notification>.broadcast(sync: true); Completer<Response>? errorCompleter; List<Response> responsesReceived = []; @@ -35,6 +35,11 @@ MockServerChannel(); + /// Return the broadcast stream of notifications. + Stream<Notification> get notifications { + return notificationController.stream; + } + @override Stream<Request> get requests => requestController.stream;
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart index 3045889..df45776 100644 --- a/pkg/analysis_server/test/analysis_abstract.dart +++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -202,11 +202,7 @@ server = createAnalysisServer(); server.pluginManager = pluginManager; handler = analysisHandler; - // listen for notifications - var notificationStream = serverChannel.notificationController.stream; - notificationStream.listen((Notification notification) { - processNotification(notification); - }); + serverChannel.notifications.listen(processNotification); } @mustCallSuper
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart index 3546ca2..9ac113c 100644 --- a/pkg/analysis_server/test/analysis_server_test.dart +++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -135,10 +135,10 @@ // Track diagnostics that arrive. final errorsByFile = <String, List<AnalysisError>>{}; - channel.notificationController.stream + channel.notifications .where((notification) => notification.event == 'analysis.errors') - .listen((notificaton) { - final params = AnalysisErrorsParams.fromNotification(notificaton); + .listen((notification) { + final params = AnalysisErrorsParams.fromNotification(notification); errorsByFile[params.file] = params.errors; });
diff --git a/pkg/analysis_server/test/client/impl/completion_driver.dart b/pkg/analysis_server/test/client/impl/completion_driver.dart index 63d8ec0..095db29 100644 --- a/pkg/analysis_server/test/client/impl/completion_driver.dart +++ b/pkg/analysis_server/test/client/impl/completion_driver.dart
@@ -84,10 +84,7 @@ required this.supportsAvailableSuggestions, required this.server, }) { - server.serverChannel.notificationController.stream - .listen((Notification notification) { - processNotification(notification); - }); + server.serverChannel.notifications.listen(processNotification); } void addTestFile(String content, {int? offset}) {
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart index fe0da92..21b79b3 100644 --- a/pkg/analysis_server/test/domain_analysis_test.dart +++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -25,6 +25,7 @@ import 'package:test_reflective_loader/test_reflective_loader.dart'; import 'analysis_abstract.dart'; +import 'domain_completion_test.dart'; import 'mocks.dart'; void main() { @@ -44,8 +45,6 @@ String get myPackageTestFilePath => '$myPackageLibPath/test.dart'; - String get workspaceRootPath => '/workspace'; - @override void setUp() { super.setUp(); @@ -347,15 +346,8 @@ @reflectiveTest class AnalysisDomainPubTest extends _AnalysisDomainTest { - String get testFilePath => '$testPackageLibPath/test.dart'; - - String get testPackageLibPath => '$testPackageRootPath/lib'; - - String get testPackageRootPath => '$workspaceRootPath/test'; - - String get workspaceRootPath => '/home'; - Future<void> test_fileSystem_addFile_analysisOptions() async { + deleteTestPackageAnalysisOptionsFile(); var a_path = '$testPackageLibPath/a.dart'; var b_path = '$testPackageLibPath/b.dart'; @@ -389,6 +381,7 @@ } Future<void> test_fileSystem_addFile_analysisOptions_analysis() async { + deleteTestPackageAnalysisOptionsFile(); var a_path = '$testPackageLibPath/a.dart'; var options_path = '$testPackageRootPath/analysis_options.yaml'; @@ -460,16 +453,15 @@ } Future<void> test_fileSystem_addFile_dart_dotFolder() async { - var a_path = '$projectPath/lib/.foo/a.dart'; - var b_path = '$projectPath/lib/b.dart'; + var a_path = '$testPackageLibPath/.foo/a.dart'; + var b_path = '$testPackageLibPath/b.dart'; newFile(b_path, content: r''' import '.foo/a.dart'; void f(A a) {} '''); - await createProject(); - await pumpEventQueue(); + await setRoots(included: [workspaceRootPath], excluded: []); await server.onAnalysisComplete; // We don't have a.dart, so the import cannot be resolved. @@ -489,10 +481,10 @@ } Future<void> test_fileSystem_addFile_dart_excluded() async { - var a_path = '$projectPath/lib/a.dart'; - var b_path = '$projectPath/lib/b.dart'; + var a_path = '$testPackageLibPath/a.dart'; + var b_path = '$testPackageLibPath/b.dart'; - newAnalysisOptionsYamlFile(projectPath, content: r''' + newAnalysisOptionsYamlFile(testPackageRootPath, content: r''' analyzer: exclude: - "**/a.dart" @@ -503,8 +495,7 @@ void f(A a) {} '''); - await createProject(); - await pumpEventQueue(); + await setRoots(included: [workspaceRootPath], excluded: []); await server.onAnalysisComplete; // We don't have a.dart, so the import cannot be resolved. @@ -524,6 +515,7 @@ } Future<void> test_fileSystem_addFile_dotPackagesFile() async { + deleteTestPackageConfigJsonFile(); var aaaLibPath = '/packages/aaa/lib'; var a_path = '$aaaLibPath/a.dart'; @@ -562,12 +554,6 @@ newFile('$testPackageLibPath/a.dart', content: ''); - // Make sure that it is a package. - writePackageConfig( - '$testPackageRootPath/.dart_tool/package_config.json', - PackageConfigFileBuilder(), - ); - await setRoots(included: [workspaceRootPath], excluded: []); // No `fix_data.yaml` to analyze yet. @@ -605,9 +591,9 @@ assertHasErrors(testFilePath); // Write `package_config.json`, recreate analysis contexts. - writePackageConfig( - '$testPackageRootPath/.dart_tool/package_config.json', - PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath), + writeTestPackageConfig( + config: PackageConfigFileBuilder() + ..add(name: 'aaa', rootPath: aaaRootPath), ); await pumpEventQueue(); @@ -857,6 +843,7 @@ } Future<void> test_fileSystem_changeFile_dotPackagesFile() async { + deleteTestPackageConfigJsonFile(); var aaaLibPath = '/packages/aaa/lib'; var a_path = '$aaaLibPath/a.dart'; @@ -898,12 +885,6 @@ newFile('$testPackageLibPath/a.dart', content: ''); - // Make sure that it is a package. - writePackageConfig( - '$testPackageRootPath/.dart_tool/package_config.json', - PackageConfigFileBuilder(), - ); - // This file has an error. newFile(path, content: '0: 1'); @@ -935,12 +916,6 @@ class A {} '''); - // Write the empty file, without `package:aaa`. - writePackageConfig( - '$testPackageRootPath/.dart_tool/package_config.json', - PackageConfigFileBuilder(), - ); - newFile(testFilePath, content: ''' import 'package:aaa/a.dart'; void f(A a) {} @@ -949,13 +924,14 @@ await setRoots(included: [workspaceRootPath], excluded: []); await server.onAnalysisComplete; + // The default `package_config.json` is without `package:aaa`. // We cannot resolve `package:aaa/a.dart` assertHasErrors(testFilePath); // Write `package_config.json`, recreate analysis contexts. - writePackageConfig( - '$testPackageRootPath/.dart_tool/package_config.json', - PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath), + writeTestPackageConfig( + config: PackageConfigFileBuilder() + ..add(name: 'aaa', rootPath: aaaRootPath), ); await pumpEventQueue(); @@ -1090,6 +1066,7 @@ } Future<void> test_fileSystem_deleteFile_dotPackagesFile() async { + deleteTestPackageConfigJsonFile(); var aaaLibPath = '/packages/aaa/lib'; var a_path = '$aaaLibPath/a.dart'; @@ -1130,12 +1107,6 @@ newFile('$testPackageLibPath/a.dart', content: ''); - // Make sure that it is a package. - writePackageConfig( - '$testPackageRootPath/.dart_tool/package_config.json', - PackageConfigFileBuilder(), - ); - // This file has an error. newFile(path, content: '0: 1'); @@ -1161,9 +1132,9 @@ '''); // Write the empty file, without `package:aaa`. - writePackageConfig( - '$testPackageRootPath/.dart_tool/package_config.json', - PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath), + writeTestPackageConfig( + config: PackageConfigFileBuilder() + ..add(name: 'aaa', rootPath: aaaRootPath), ); newFile(testFilePath, content: ''' @@ -1193,6 +1164,7 @@ } Future<void> test_setRoots_dotPackagesFile() async { + deleteTestPackageConfigJsonFile(); var aaaLibPath = '/packages/aaa/lib'; var a_path = '$aaaLibPath/a.dart'; @@ -1373,13 +1345,7 @@ Future<void> test_setRoots_notDartFile_fixDataYaml() async { var path = '$testPackageLibPath/fix_data.yaml'; - // Make sure that it is a package. - writePackageConfig( - '$testPackageRootPath/.dart_tool/package_config.json', - PackageConfigFileBuilder(), - ); - - // So, `lib/fix_data.yaml` will be analyzed. + // `lib/fix_data.yaml` will be analyzed. newFile(path, content: '0: 1'); await setRoots(included: [workspaceRootPath], excluded: []); @@ -1395,9 +1361,9 @@ class A {} '''); - writePackageConfig( - '$testPackageRootPath/.dart_tool/package_config.json', - PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath), + writeTestPackageConfig( + config: PackageConfigFileBuilder() + ..add(name: 'aaa', rootPath: aaaRootPath), ); newFile(testFilePath, content: ''' @@ -1454,8 +1420,7 @@ InstrumentationService.NULL_SERVICE); handler = AnalysisDomainHandler(server); // listen for notifications - var notificationStream = serverChannel.notificationController.stream; - notificationStream.listen((Notification notification) { + serverChannel.notifications.listen((Notification notification) { if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) { var decoded = AnalysisErrorsParams.fromNotification(notification); filesErrors[decoded.file] = decoded.errors; @@ -1763,7 +1728,7 @@ } } -class _AnalysisDomainTest extends AbstractAnalysisTest { +class _AnalysisDomainTest extends PubPackageAnalysisServerTest { final Map<String, List<AnalysisError>> filesErrors = {}; /// The files for which `analysis.flushResults` was received. @@ -1801,10 +1766,6 @@ } } - void writePackageConfig(String path, PackageConfigFileBuilder config) { - newFile(path, content: config.toContent(toUriStr: toUriStr)); - } - void _assertAnalyzedFiles({ required List<String> hasErrors, List<String> noErrors = const [],
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart index 0ecd2f7..37bf033 100644 --- a/pkg/analysis_server/test/domain_completion_test.dart +++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -2951,10 +2951,20 @@ String get workspaceRootPath => '/home'; + void deleteTestPackageAnalysisOptionsFile() { + deleteAnalysisOptionsYamlFile(testPackageRootPath); + } + + void deleteTestPackageConfigJsonFile() { + deletePackageConfigJsonFile(testPackageRootPath); + } + Future<Response> handleRequest(Request request) async { return await serverChannel.sendRequest(request); } + void processNotification(Notification notification) {} + Future<void> setRoots({ required List<String> included, required List<String> excluded, @@ -2988,6 +2998,8 @@ ), ); + serverChannel.notifications.listen(processNotification); + server = AnalysisServer( serverChannel, resourceProvider,
diff --git a/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart index c082771..867272e 100644 --- a/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart +++ b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
@@ -14,6 +14,11 @@ String convertPath(String path) => resourceProvider.convertPath(path); + void deleteAnalysisOptionsYamlFile(String directoryPath) { + var path = join(directoryPath, file_paths.analysisOptionsYaml); + deleteFile(path); + } + void deleteFile(String path) { String convertedPath = convertPath(path); resourceProvider.deleteFile(convertedPath); @@ -24,6 +29,15 @@ resourceProvider.deleteFolder(convertedPath); } + void deletePackageConfigJsonFile(String directoryPath) { + var path = join( + directoryPath, + file_paths.dotDartTool, + file_paths.packageConfigJson, + ); + deleteFile(path); + } + File getFile(String path) { String convertedPath = convertPath(path); return resourceProvider.getFile(convertedPath);
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc index a37565a..3c65323 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -1195,7 +1195,8 @@ // R2 : arguments array. // R3 : current thread. void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) { - READS_RETURN_ADDRESS_FROM_LR(__ Push(LR)); // Marker for the profiler. + // Marker for the profiler. + NOT_IN_PRODUCT(READS_RETURN_ADDRESS_FROM_LR(__ Push(LR))); SPILLS_LR_TO_FRAME(__ EnterFrame((1 << FP) | (1 << LR), 0)); // Push code object to PC marker slot. @@ -1318,7 +1319,7 @@ // Restore the frame pointer and return. RESTORES_LR_FROM_FRAME(__ LeaveFrame((1 << FP) | (1 << LR))); - __ Drop(1); + NOT_IN_PRODUCT(__ Drop(1)); // Drop profiler marker. __ Ret(); }
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc index 6dc4dbe..e32707b 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm64.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -1365,7 +1365,8 @@ // from over-writing Dart frames. __ mov(SP, CSP); __ SetupCSPFromThread(R3); - READS_RETURN_ADDRESS_FROM_LR(__ Push(LR)); // Marker for the profiler. + // Marker for the profiler. + NOT_IN_PRODUCT(READS_RETURN_ADDRESS_FROM_LR(__ Push(LR))); __ EnterFrame(0); // Push code object to PC marker slot. @@ -1488,7 +1489,7 @@ // Restore the frame pointer and C stack pointer and return. __ LeaveFrame(); - __ Drop(1); + NOT_IN_PRODUCT(__ Drop(1)); // Drop profiler marker. __ RestoreCSP(); __ ret(); }
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc index 68b3b4c..52f6ed0 100644 --- a/runtime/vm/compiler/stub_code_compiler_ia32.cc +++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -969,7 +969,7 @@ const intptr_t kArgumentsOffset = 5 * target::kWordSize; const intptr_t kThreadOffset = 6 * target::kWordSize; - __ pushl(Address(ESP, 0)); // Marker for the profiler. + NOT_IN_PRODUCT(__ pushl(Address(ESP, 0))); // Marker for the profiler. __ EnterFrame(0); // Push code object to PC marker slot. @@ -1084,7 +1084,7 @@ // Restore the frame pointer. __ LeaveFrame(); - __ popl(ECX); + NOT_IN_PRODUCT(__ popl(ECX)); // Drop profiler marker. __ ret(); }
diff --git a/runtime/vm/compiler/stub_code_compiler_riscv.cc b/runtime/vm/compiler/stub_code_compiler_riscv.cc index 14dd9f3..f4a17da 100644 --- a/runtime/vm/compiler/stub_code_compiler_riscv.cc +++ b/runtime/vm/compiler/stub_code_compiler_riscv.cc
@@ -1276,7 +1276,7 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) { __ Comment("InvokeDartCodeStub"); - __ PushRegister(RA); // Marker for the profiler. + NOT_IN_PRODUCT(__ PushRegister(RA)); // Marker for the profiler. __ EnterFrame(0); // Push code object to PC marker slot. @@ -1396,7 +1396,7 @@ // Restore the frame pointer and C stack pointer and return. __ LeaveFrame(); - __ Drop(1); + __ NOT_IN_PRODUCT(__ Drop(1)); // Drop profiler marker. __ ret(); }
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc index de42236..0268696 100644 --- a/runtime/vm/compiler/stub_code_compiler_x64.cc +++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -1375,7 +1375,7 @@ // RDX : arguments array. // RCX : current thread. void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) { - __ pushq(Address(RSP, 0)); // Marker for the profiler. + NOT_IN_PRODUCT(__ pushq(Address(RSP, 0))); // Marker for the profiler. __ EnterFrame(0); const Register kTargetReg = CallingConventions::kArg1Reg; @@ -1518,7 +1518,7 @@ // Restore the frame pointer. __ LeaveFrame(); - __ popq(RCX); + NOT_IN_PRODUCT(__ popq(RCX)); // Drop profiler marker. __ ret(); }
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc index 77d6949..7f87db9 100644 --- a/runtime/vm/elf.cc +++ b/runtime/vm/elf.cc
@@ -1373,7 +1373,7 @@ // Multiplier which will be used to scale operands of DW_CFA_offset and // DW_CFA_val_offset. - const intptr_t kDataAlignment = compiler::target::kWordSize; + const intptr_t kDataAlignment = -compiler::target::kWordSize; static const uint8_t DW_EH_PE_pcrel = 0x10; static const uint8_t DW_EH_PE_sdata4 = 0x0b; @@ -1395,12 +1395,20 @@ ConcreteRegister(LINK_REGISTER)); // Return address register dwarf_stream.uleb128(1); // Augmentation size dwarf_stream.u1(DW_EH_PE_pcrel | DW_EH_PE_sdata4); // FDE encoding. - // CFA is FP+0 + // CFA is caller's SP (FP+kCallerSpSlotFromFp*kWordSize) dwarf_stream.u1(Dwarf::DW_CFA_def_cfa); dwarf_stream.uleb128(FP); - dwarf_stream.uleb128(0); + dwarf_stream.uleb128(kCallerSpSlotFromFp * compiler::target::kWordSize); }); + // Emit rule defining that |reg| value is stored at CFA+offset. + const auto cfa_offset = [&](Register reg, intptr_t offset) { + const intptr_t scaled_offset = offset / kDataAlignment; + RELEASE_ASSERT(scaled_offset >= 0); + dwarf_stream.u1(Dwarf::DW_CFA_offset | reg); + dwarf_stream.uleb128(scaled_offset); + }; + // Emit an FDE covering each .text section. for (const auto& portion : text_section->portions()) { ASSERT(portion.symbol_name != nullptr); // Needed for relocations. @@ -1413,27 +1421,17 @@ dwarf_stream.u4(portion.size); // Size. dwarf_stream.u1(0); // Augmentation Data length. - // FP at FP+kSavedCallerPcSlotFromFp*kWordSize - COMPILE_ASSERT(kSavedCallerFpSlotFromFp >= 0); - dwarf_stream.u1(Dwarf::DW_CFA_offset | FP); - dwarf_stream.uleb128(kSavedCallerFpSlotFromFp); + // Caller FP at FP+kSavedCallerPcSlotFromFp*kWordSize, + // where FP is CFA - kCallerSpSlotFromFp*kWordSize. + COMPILE_ASSERT((kSavedCallerFpSlotFromFp - kCallerSpSlotFromFp) <= 0); + cfa_offset(FP, + (kSavedCallerFpSlotFromFp - kCallerSpSlotFromFp) * kWordSize); - // LR at FP+kSavedCallerPcSlotFromFp*kWordSize - COMPILE_ASSERT(kSavedCallerPcSlotFromFp >= 0); - dwarf_stream.u1(Dwarf::DW_CFA_offset | ConcreteRegister(LINK_REGISTER)); - dwarf_stream.uleb128(kSavedCallerPcSlotFromFp); - - // SP is FP+kCallerSpSlotFromFp*kWordSize - COMPILE_ASSERT(kCallerSpSlotFromFp >= 0); - dwarf_stream.u1(Dwarf::DW_CFA_val_offset); -#if defined(TARGET_ARCH_ARM64) - dwarf_stream.uleb128(ConcreteRegister(CSP)); -#elif defined(TARGET_ARCH_ARM) - dwarf_stream.uleb128(SP); -#else -#error "Unsupported .eh_frame architecture" -#endif - dwarf_stream.uleb128(kCallerSpSlotFromFp); + // Caller LR at FP+kSavedCallerPcSlotFromFp*kWordSize, + // where FP is CFA - kCallerSpSlotFromFp*kWordSize + COMPILE_ASSERT((kSavedCallerPcSlotFromFp - kCallerSpSlotFromFp) <= 0); + cfa_offset(ConcreteRegister(LINK_REGISTER), + (kSavedCallerPcSlotFromFp - kCallerSpSlotFromFp) * kWordSize); }); }
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc index 3661d07..4528f28 100644 --- a/runtime/vm/image_snapshot.cc +++ b/runtime/vm/image_snapshot.cc
@@ -1294,97 +1294,31 @@ // CFA = Canonical frame address assembly_stream_->WriteString(".cfi_startproc\n"); -#if defined(TARGET_ARCH_X64) - assembly_stream_->WriteString(".cfi_def_cfa rbp, 0\n"); // CFA is fp+0 - assembly_stream_->WriteString( - ".cfi_offset rbp, 0\n"); // saved fp is *(CFA+0) - assembly_stream_->WriteString( - ".cfi_offset rip, 8\n"); // saved pc is *(CFA+8) - // saved sp is CFA+16 - // Would prefer to use ".cfi_value_offset sp, 16", but this requires gcc - // newer than late 2016. Can't emit .cfi_value_offset using .cfi_scape - // because DW_CFA_val_offset uses scaled operand and we don't know what - // data alignment factor will be choosen by the assembler when emitting CIE. - // DW_CFA_expression 0x10 - // uleb128 register (rsp) 7 (DWARF register number) - // uleb128 size of operation 2 - // DW_OP_plus_uconst 0x23 - // uleb128 addend 16 - assembly_stream_->WriteString(".cfi_escape 0x10, 31, 2, 0x23, 16\n"); + // Below .cfi_def_cfa defines CFA as caller's SP, while .cfi_offset R, offs + // tells unwinder that caller's value of register R is stored at address + // CFA+offs. +#if defined(TARGET_ARCH_X64) + assembly_stream_->WriteString(".cfi_def_cfa rbp, 16\n"); + assembly_stream_->WriteString(".cfi_offset rbp, -16\n"); + assembly_stream_->WriteString(".cfi_offset rip, -8\n"); #elif defined(TARGET_ARCH_ARM64) COMPILE_ASSERT(R29 == FP); COMPILE_ASSERT(R30 == LINK_REGISTER); - assembly_stream_->WriteString(".cfi_def_cfa x29, 0\n"); // CFA is fp+0 - assembly_stream_->WriteString( - ".cfi_offset x29, 0\n"); // saved fp is *(CFA+0) - assembly_stream_->WriteString( - ".cfi_offset x30, 8\n"); // saved pc is *(CFA+8) - // saved sp is CFA+16 - // Would prefer to use ".cfi_value_offset sp, 16", but this requires gcc - // newer than late 2016. Can't emit .cfi_value_offset using .cfi_scape - // because DW_CFA_val_offset uses scaled operand and we don't know what - // data alignment factor will be choosen by the assembler when emitting CIE. -#if defined(DART_TARGET_OS_ANDROID) - // On Android libunwindstack has a bug (b/191113792): it does not push - // CFA value to the expression stack before evaluating expression given - // to DW_CFA_expression. We have to workaround this bug by manually pushing - // CFA (R11) to the stack using DW_OP_breg29 0. - // DW_CFA_expression 0x10 - // uleb128 register (x31) 31 - // uleb128 size of operation 4 - // DW_OP_breg11 0x8d (0x70 + 29) - // sleb128 offset 0 - // DW_OP_plus_uconst 0x23 - // uleb128 addend 16 - assembly_stream_->WriteString(".cfi_escape 0x10, 31, 4, 0x8d, 0, 0x23, 16\n"); -#else - // DW_CFA_expression 0x10 - // uleb128 register (x31) 31 - // uleb128 size of operation 2 - // DW_OP_plus_uconst 0x23 - // uleb128 addend 16 - assembly_stream_->WriteString(".cfi_escape 0x10, 31, 2, 0x23, 16\n"); -#endif - + assembly_stream_->WriteString(".cfi_def_cfa x29, 16\n"); + assembly_stream_->WriteString(".cfi_offset x29, -16\n"); + assembly_stream_->WriteString(".cfi_offset x30, -8\n"); #elif defined(TARGET_ARCH_ARM) #if defined(DART_TARGET_OS_MACOS) || defined(DART_TARGET_OS_MACOS_IOS) COMPILE_ASSERT(FP == R7); - assembly_stream_->WriteString(".cfi_def_cfa r7, 0\n"); // CFA is fp+0 - assembly_stream_->WriteString(".cfi_offset r7, 0\n"); // saved fp is *(CFA+0) + assembly_stream_->WriteString(".cfi_def_cfa r7, 8\n"); + assembly_stream_->WriteString(".cfi_offset r7, -8\n"); #else COMPILE_ASSERT(FP == R11); - assembly_stream_->WriteString(".cfi_def_cfa r11, 0\n"); // CFA is fp+0 - assembly_stream_->WriteString( - ".cfi_offset r11, 0\n"); // saved fp is *(CFA+0) + assembly_stream_->WriteString(".cfi_def_cfa r11, 8\n"); + assembly_stream_->WriteString(".cfi_offset r11, -8\n"); #endif - assembly_stream_->WriteString(".cfi_offset lr, 4\n"); // saved pc is *(CFA+4) - // saved sp is CFA+8 - // Would prefer to use ".cfi_value_offset sp, 16", but this requires gcc - // newer than late 2016. Can't emit .cfi_value_offset using .cfi_scape - // because DW_CFA_val_offset uses scaled operand and we don't know what - // data alignment factor will be choosen by the assembler when emitting CIE. -#if defined(DART_TARGET_OS_ANDROID) - // On Android libunwindstack has a bug (b/191113792): it does not push - // CFA value to the expression stack before evaluating expression given - // to DW_CFA_expression. We have to workaround this bug by manually pushing - // CFA (R11) to the stack using DW_OP_breg11 0. - // DW_CFA_expression 0x10 - // uleb128 register (sp) 13 - // uleb128 size of operation 4 - // DW_OP_breg11 0x7b (0x70 + 11) - // sleb128 offset 0 - // DW_OP_plus_uconst 0x23 - // uleb128 addend 8 - assembly_stream_->WriteString(".cfi_escape 0x10, 31, 4, 0x7b, 0, 0x23, 16\n"); -#else - // DW_CFA_expression 0x10 - // uleb128 register (sp) 13 - // uleb128 size of operation 2 - // DW_OP_plus_uconst 0x23 - // uleb128 addend 8 - assembly_stream_->WriteString(".cfi_escape 0x10, 13, 2, 0x23, 8\n"); -#endif + assembly_stream_->WriteString(".cfi_offset lr, -4\n"); // libunwind on ARM may use .ARM.exidx instead of .debug_frame #if !defined(DART_TARGET_OS_MACOS) && !defined(DART_TARGET_OS_MACOS_IOS)
diff --git a/tools/VERSION b/tools/VERSION index 96ecaf9..81d0e2a 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 2 MINOR 17 PATCH 0 -PRERELEASE 181 +PRERELEASE 182 PRERELEASE_PATCH 0 \ No newline at end of file