Version 2.14.0-45.0.dev
Merge commit '6730b12edc9393566f5a3edee145c17c93ebf85e' into 'dev'
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 9ad6e5b..59b0c0d 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -178,6 +178,15 @@
}
/**
+ * Checks whether the Iterable [actual] is not empty.
+ */
+ static void isNotEmpty(Iterable actual, [String reason = ""]) {
+ if (actual.isNotEmpty) return;
+ String msg = _getMessage(reason);
+ _fail("Expect.isNotEmpty(actual: <$actual>$msg) fails.");
+ }
+
+ /**
* Checks whether the expected and actual values are identical
* (using `identical`).
*/
diff --git a/runtime/tests/vm/dart/use_code_comments_flag_test.dart b/runtime/tests/vm/dart/use_code_comments_flag_test.dart
new file mode 100644
index 0000000..cc3968c
--- /dev/null
+++ b/runtime/tests/vm/dart/use_code_comments_flag_test.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2021, 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 is ensuring that the flag for --code-comments given at
+// AOT compile-time will be used at runtime (irrespective if other values were
+// passed to the runtime).
+
+import "dart:async";
+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 and dart_bootstrap not available on the test device.
+ }
+
+ await withTempDir('code-comments-test', (String tempDir) async {
+ final script = path.join(sdkDir, 'pkg/kernel/bin/dump.dart');
+ final scriptDill = path.join(tempDir, 'kernel_dump.dill');
+
+ // Compile script to Kernel IR.
+ await run(genKernel, <String>[
+ '--aot',
+ '--platform=$platformDill',
+ '-o',
+ scriptDill,
+ script,
+ ]);
+
+ // Run the AOT compiler with/without code comments.
+ final scriptCommentedSnapshot = path.join(tempDir, 'comments.snapshot');
+ final scriptUncommentedSnapshot =
+ path.join(tempDir, 'no_comments.snapshot');
+ await Future.wait(<Future>[
+ run(genSnapshot, <String>[
+ '--code-comments',
+ '--snapshot-kind=app-aot-elf',
+ '--elf=$scriptCommentedSnapshot',
+ scriptDill,
+ ]),
+ run(genSnapshot, <String>[
+ '--no-code-comments',
+ '--snapshot-kind=app-aot-elf',
+ '--elf=$scriptUncommentedSnapshot',
+ scriptDill,
+ ]),
+ ]);
+
+ // Run the AOT compiled script with code comments enabled.
+ final commentsOut1 = path.join(tempDir, 'comments-out1.txt');
+ final commentsOut2 = path.join(tempDir, 'comments-out2.txt');
+ await Future.wait(<Future>[
+ run(aotRuntime, <String>[
+ '--code-comments',
+ scriptCommentedSnapshot,
+ scriptDill,
+ commentsOut1,
+ ]),
+ run(aotRuntime, <String>[
+ '--no-code-comments',
+ scriptCommentedSnapshot,
+ scriptDill,
+ commentsOut2,
+ ]),
+ ]);
+
+ // Run the AOT compiled script with code comments disabled.
+ final uncommentedOut1 = path.join(tempDir, 'uncommented-out1.txt');
+ final uncommentedOut2 = path.join(tempDir, 'uncommented-out2.txt');
+ await Future.wait(<Future>[
+ run(aotRuntime, <String>[
+ '--code-comments',
+ scriptUncommentedSnapshot,
+ scriptDill,
+ uncommentedOut1,
+ ]),
+ run(aotRuntime, <String>[
+ '--no-code-comments',
+ scriptUncommentedSnapshot,
+ scriptDill,
+ uncommentedOut2,
+ ]),
+ ]);
+
+ // Ensure we got the same result each time.
+ final output = await File(commentsOut1).readAsString();
+ Expect.equals(output, await File(commentsOut2).readAsString());
+ Expect.equals(output, await File(uncommentedOut1).readAsString());
+ Expect.equals(output, await File(uncommentedOut2).readAsString());
+ });
+}
diff --git a/runtime/tests/vm/dart/use_resolve_dwarf_paths_flag_test.dart b/runtime/tests/vm/dart/use_resolve_dwarf_paths_flag_test.dart
new file mode 100644
index 0000000..30d90d5
--- /dev/null
+++ b/runtime/tests/vm/dart/use_resolve_dwarf_paths_flag_test.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2021, 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 checks that --resolve-dwarf-paths outputs absolute and relative
+// paths in DWARF information.
+
+// OtherResources=use_dwarf_stack_traces_flag_program.dart
+
+import "dart:async";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:native_stack_traces/native_stack_traces.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 and dart_bootstrap not available on the test device.
+ }
+
+ // These are the tools we need to be available to run on a given platform:
+ if (!await testExecutable(genSnapshot)) {
+ throw "Cannot run test as $genSnapshot not available";
+ }
+ if (!await testExecutable(aotRuntime)) {
+ throw "Cannot run test as $aotRuntime not available";
+ }
+ if (!File(platformDill).existsSync()) {
+ throw "Cannot run test as $platformDill does not exist";
+ }
+
+ await withTempDir('dwarf-flag-test', (String tempDir) async {
+ final cwDir = path.dirname(Platform.script.toFilePath());
+ final script = path.join(cwDir, 'use_dwarf_stack_traces_flag_program.dart');
+ final scriptDill = path.join(tempDir, 'flag_program.dill');
+
+ // Compile script to Kernel IR.
+ await run(genKernel, <String>[
+ '--aot',
+ '--platform=$platformDill',
+ '-o',
+ scriptDill,
+ script,
+ ]);
+
+ final scriptDwarfSnapshot = path.join(tempDir, 'dwarf.so');
+ await run(genSnapshot, <String>[
+ '--resolve-dwarf-paths',
+ '--dwarf-stack-traces-mode',
+ '--snapshot-kind=app-aot-elf',
+ '--elf=$scriptDwarfSnapshot',
+ scriptDill,
+ ]);
+
+ // Run the resulting Dwarf-AOT compiled script.
+ final dwarfTrace = await runError(aotRuntime, <String>[
+ scriptDwarfSnapshot,
+ scriptDill,
+ ]);
+
+ final tracePCOffsets = collectPCOffsets(dwarfTrace);
+
+ // Check that translating the DWARF stack trace (without internal frames)
+ // matches the symbolic stack trace.
+ final dwarf = Dwarf.fromFile(scriptDwarfSnapshot);
+ Expect.isNotNull(dwarf);
+ checkDwarfInfo(dwarf!, tracePCOffsets);
+ });
+}
+
+void checkDwarfInfo(Dwarf dwarf, Iterable<PCOffset> offsets) {
+ final filenames = <String>{};
+ for (final offset in offsets) {
+ final callInfo = offset.callInfoFrom(dwarf);
+ Expect.isNotNull(callInfo);
+ Expect.isNotEmpty(callInfo!);
+ for (final e in callInfo) {
+ Expect.isTrue(e is DartCallInfo, 'Call is not from the Dart source: $e.');
+ final entry = e as DartCallInfo;
+ var filename = entry.filename;
+ if (!filename.startsWith('/')) {
+ filename = path.join(sdkDir, filename);
+ }
+ if (filenames.add(filename)) {
+ Expect.isTrue(
+ File(filename).existsSync(), 'File $filename does not exist.');
+ }
+ }
+ }
+ print('Checked filenames:');
+ for (final filename in filenames) {
+ print('- ${filename}');
+ }
+ Expect.isNotEmpty(filenames);
+}
diff --git a/runtime/tests/vm/dart_2/use_code_comments_flag_test.dart b/runtime/tests/vm/dart_2/use_code_comments_flag_test.dart
new file mode 100644
index 0000000..cc3968c
--- /dev/null
+++ b/runtime/tests/vm/dart_2/use_code_comments_flag_test.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2021, 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 is ensuring that the flag for --code-comments given at
+// AOT compile-time will be used at runtime (irrespective if other values were
+// passed to the runtime).
+
+import "dart:async";
+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 and dart_bootstrap not available on the test device.
+ }
+
+ await withTempDir('code-comments-test', (String tempDir) async {
+ final script = path.join(sdkDir, 'pkg/kernel/bin/dump.dart');
+ final scriptDill = path.join(tempDir, 'kernel_dump.dill');
+
+ // Compile script to Kernel IR.
+ await run(genKernel, <String>[
+ '--aot',
+ '--platform=$platformDill',
+ '-o',
+ scriptDill,
+ script,
+ ]);
+
+ // Run the AOT compiler with/without code comments.
+ final scriptCommentedSnapshot = path.join(tempDir, 'comments.snapshot');
+ final scriptUncommentedSnapshot =
+ path.join(tempDir, 'no_comments.snapshot');
+ await Future.wait(<Future>[
+ run(genSnapshot, <String>[
+ '--code-comments',
+ '--snapshot-kind=app-aot-elf',
+ '--elf=$scriptCommentedSnapshot',
+ scriptDill,
+ ]),
+ run(genSnapshot, <String>[
+ '--no-code-comments',
+ '--snapshot-kind=app-aot-elf',
+ '--elf=$scriptUncommentedSnapshot',
+ scriptDill,
+ ]),
+ ]);
+
+ // Run the AOT compiled script with code comments enabled.
+ final commentsOut1 = path.join(tempDir, 'comments-out1.txt');
+ final commentsOut2 = path.join(tempDir, 'comments-out2.txt');
+ await Future.wait(<Future>[
+ run(aotRuntime, <String>[
+ '--code-comments',
+ scriptCommentedSnapshot,
+ scriptDill,
+ commentsOut1,
+ ]),
+ run(aotRuntime, <String>[
+ '--no-code-comments',
+ scriptCommentedSnapshot,
+ scriptDill,
+ commentsOut2,
+ ]),
+ ]);
+
+ // Run the AOT compiled script with code comments disabled.
+ final uncommentedOut1 = path.join(tempDir, 'uncommented-out1.txt');
+ final uncommentedOut2 = path.join(tempDir, 'uncommented-out2.txt');
+ await Future.wait(<Future>[
+ run(aotRuntime, <String>[
+ '--code-comments',
+ scriptUncommentedSnapshot,
+ scriptDill,
+ uncommentedOut1,
+ ]),
+ run(aotRuntime, <String>[
+ '--no-code-comments',
+ scriptUncommentedSnapshot,
+ scriptDill,
+ uncommentedOut2,
+ ]),
+ ]);
+
+ // Ensure we got the same result each time.
+ final output = await File(commentsOut1).readAsString();
+ Expect.equals(output, await File(commentsOut2).readAsString());
+ Expect.equals(output, await File(uncommentedOut1).readAsString());
+ Expect.equals(output, await File(uncommentedOut2).readAsString());
+ });
+}
diff --git a/runtime/tests/vm/dart_2/use_resolve_dwarf_paths_flag_test.dart b/runtime/tests/vm/dart_2/use_resolve_dwarf_paths_flag_test.dart
new file mode 100644
index 0000000..8b00996
--- /dev/null
+++ b/runtime/tests/vm/dart_2/use_resolve_dwarf_paths_flag_test.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2021, 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 checks that --resolve-dwarf-paths outputs absolute and relative
+// paths in DWARF information.
+
+// OtherResources=use_dwarf_stack_traces_flag_program.dart
+
+import "dart:async";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:native_stack_traces/native_stack_traces.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 and dart_bootstrap not available on the test device.
+ }
+
+ // These are the tools we need to be available to run on a given platform:
+ if (!await testExecutable(genSnapshot)) {
+ throw "Cannot run test as $genSnapshot not available";
+ }
+ if (!await testExecutable(aotRuntime)) {
+ throw "Cannot run test as $aotRuntime not available";
+ }
+ if (!File(platformDill).existsSync()) {
+ throw "Cannot run test as $platformDill does not exist";
+ }
+
+ await withTempDir('dwarf-flag-test', (String tempDir) async {
+ final cwDir = path.dirname(Platform.script.toFilePath());
+ final script = path.join(cwDir, 'use_dwarf_stack_traces_flag_program.dart');
+ final scriptDill = path.join(tempDir, 'flag_program.dill');
+
+ // Compile script to Kernel IR.
+ await run(genKernel, <String>[
+ '--aot',
+ '--platform=$platformDill',
+ '-o',
+ scriptDill,
+ script,
+ ]);
+
+ final scriptDwarfSnapshot = path.join(tempDir, 'dwarf.so');
+ await run(genSnapshot, <String>[
+ '--resolve-dwarf-paths',
+ '--dwarf-stack-traces-mode',
+ '--snapshot-kind=app-aot-elf',
+ '--elf=$scriptDwarfSnapshot',
+ scriptDill,
+ ]);
+
+ // Run the resulting Dwarf-AOT compiled script.
+ final dwarfTrace = await runError(aotRuntime, <String>[
+ scriptDwarfSnapshot,
+ scriptDill,
+ ]);
+
+ final tracePCOffsets = collectPCOffsets(dwarfTrace);
+
+ // Check that translating the DWARF stack trace (without internal frames)
+ // matches the symbolic stack trace.
+ final dwarf = Dwarf.fromFile(scriptDwarfSnapshot);
+ Expect.isNotNull(dwarf);
+ checkDwarfInfo(dwarf, tracePCOffsets);
+ });
+}
+
+void checkDwarfInfo(Dwarf dwarf, Iterable<PCOffset> offsets) {
+ final filenames = <String>{};
+ for (final offset in offsets) {
+ final callInfo = offset.callInfoFrom(dwarf);
+ Expect.isNotNull(callInfo);
+ Expect.isNotEmpty(callInfo);
+ for (final e in callInfo) {
+ Expect.isTrue(e is DartCallInfo, 'Call is not from the Dart source: $e.');
+ final entry = e as DartCallInfo;
+ var filename = entry.filename;
+ if (!filename.startsWith('/')) {
+ filename = path.join(sdkDir, filename);
+ }
+ if (filenames.add(filename)) {
+ Expect.isTrue(
+ File(filename).existsSync(), 'File $filename does not exist.');
+ }
+ }
+ }
+ print('Checked filenames:');
+ for (final filename in filenames) {
+ print('- ${filename}');
+ }
+ Expect.isNotEmpty(filenames);
+}
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 0ad8406..9107586 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -2492,6 +2492,10 @@
KernelProgramInfo& program_info = KernelProgramInfo::Handle(Z);
const TypedData& null_typed_data = TypedData::Handle(Z);
const KernelProgramInfo& null_info = KernelProgramInfo::Handle(Z);
+#if defined(PRODUCT)
+ auto& str = String::Handle(Z);
+ auto& wsr = WeakSerializationReference::Handle(Z);
+#endif
for (intptr_t i = 0; i < libraries_.Length(); i++) {
lib ^= libraries_.At(i);
@@ -2538,7 +2542,11 @@
program_info.set_classes_cache(Array::null_array());
}
#if defined(PRODUCT)
- script.set_resolved_url(String::null_string());
+ str = script.resolved_url();
+ if (!str.IsNull()) {
+ wsr = WeakSerializationReference::New(str, String::null_string());
+ script.set_resolved_url(wsr);
+ }
#endif // defined(PRODUCT)
script.set_compile_time_constants(Array::null_array());
script.set_line_starts(null_typed_data);
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index d389089..53250c5 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -976,10 +976,6 @@
FLAG_use_field_guards);
ADD_ISOLATE_GROUP_FLAG(use_osr, use_osr, FLAG_use_osr);
}
-#if !defined(PRODUCT)
- buffer.AddString(FLAG_code_comments ? " code-comments"
- : " no-code-comments");
-#endif
// Generated code must match the host architecture and ABI.
#if defined(TARGET_ARCH_ARM)
diff --git a/runtime/vm/dwarf.cc b/runtime/vm/dwarf.cc
index 35df763..f940ef7 100644
--- a/runtime/vm/dwarf.cc
+++ b/runtime/vm/dwarf.cc
@@ -14,6 +14,11 @@
#if defined(DART_PRECOMPILER)
+DEFINE_FLAG(bool,
+ resolve_dwarf_paths,
+ false,
+ "Resolve script URIs to absolute or relative file paths in DWARF");
+
DEFINE_FLAG(charp,
write_code_comments_as_synthetic_source_to,
nullptr,
@@ -718,6 +723,25 @@
}
}
+static constexpr char kResolvedFileRoot[] = "file://";
+static constexpr intptr_t kResolvedFileRootLen = sizeof(kResolvedFileRoot) - 1;
+static constexpr char kResolvedSdkRoot[] = "org-dartlang-sdk:///sdk/";
+static constexpr intptr_t kResolvedSdkRootLen = sizeof(kResolvedSdkRoot) - 1;
+
+static const char* ConvertResolvedURI(const char* str) {
+ const intptr_t len = strlen(str);
+ if (len > kResolvedFileRootLen &&
+ strncmp(str, kResolvedFileRoot, kResolvedFileRootLen) == 0) {
+ return str + kResolvedFileRootLen;
+ }
+ if (len > kResolvedSdkRootLen &&
+ strncmp(str, kResolvedSdkRoot, kResolvedSdkRootLen) == 0) {
+ // Leave "sdk/" as a prefix in the returned path.
+ return str + (kResolvedSdkRootLen - 4);
+ }
+ return nullptr;
+}
+
void Dwarf::WriteLineNumberProgram(DwarfWriteStream* stream) {
// 6.2.4 The Line Number Program Header
@@ -762,8 +786,25 @@
String& uri = String::Handle(zone_);
for (intptr_t i = 0; i < scripts_.length(); i++) {
const Script& script = *(scripts_[i]);
- uri = script.url();
- auto const uri_cstr = Deobfuscate(uri.ToCString());
+ if (FLAG_resolve_dwarf_paths) {
+ uri = script.resolved_url();
+ // Strictly enforce this to catch unresolvable cases.
+ if (uri.IsNull()) {
+ FATAL("no resolved URI for Script %s available", script.ToCString());
+ }
+ } else {
+ uri = script.url();
+ }
+ ASSERT(!uri.IsNull());
+ auto uri_cstr = Deobfuscate(uri.ToCString());
+ if (FLAG_resolve_dwarf_paths) {
+ auto const converted_cstr = ConvertResolvedURI(uri_cstr);
+ // Strictly enforce this to catch inconvertable cases.
+ if (converted_cstr == nullptr) {
+ FATAL("cannot convert resolved URI %s", uri_cstr);
+ }
+ uri_cstr = converted_cstr;
+ }
RELEASE_ASSERT(strlen(uri_cstr) != 0);
stream->string(uri_cstr); // NOLINT
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 59226e1..1aa3e56 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -60,6 +60,7 @@
// automatically included in FLAG_LIST.
// TODO(cskau): Remove causal_async_stacks when deprecated.
#define VM_GLOBAL_FLAG_LIST(P, R, C, D) \
+ P(code_comments, bool, false, "Include comments into code and disassembly.") \
P(dwarf_stack_traces_mode, bool, false, \
"Use --[no-]dwarf-stack-traces instead.") \
P(causal_async_stacks, bool, false, "DEPRECATED: Improved async stacks") \
@@ -98,7 +99,6 @@
"Run optimizing compilation in background") \
P(check_token_positions, bool, false, \
"Check validity of token positions while compiling flow graphs") \
- P(code_comments, bool, false, "Include comments into code and disassembly.") \
P(collect_code, bool, false, "Attempt to GC infrequently used code.") \
P(collect_dynamic_function_names, bool, true, \
"Collects all dynamic function names to identify unique targets") \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index e163b57..1d9e3ce 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -11392,6 +11392,15 @@
}
#endif
+StringPtr Script::resolved_url() const {
+#if defined(DART_PRECOMPILER)
+ return String::RawCast(
+ WeakSerializationReference::Unwrap(untag()->resolved_url()));
+#else
+ return untag()->resolved_url();
+#endif
+}
+
bool Script::HasSource() const {
return untag()->source() != String::null();
}
@@ -11546,9 +11555,15 @@
untag()->set_url(value.ptr());
}
+#if defined(DART_PRECOMPILER)
+void Script::set_resolved_url(const Object& value) const {
+ untag()->set_resolved_url(value.ptr());
+}
+#else
void Script::set_resolved_url(const String& value) const {
untag()->set_resolved_url(value.ptr());
}
+#endif
void Script::set_source(const String& value) const {
untag()->set_source(value.ptr());
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 9ddb727..c39a387 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -4426,7 +4426,7 @@
void set_url(const String& value) const;
// The actual url which was loaded from disk, if provided by the embedder.
- StringPtr resolved_url() const { return untag()->resolved_url(); }
+ StringPtr resolved_url() const;
bool HasSource() const;
StringPtr Source() const;
bool IsPartOfDartColonLibrary() const;
@@ -4526,7 +4526,11 @@
void SetCachedMaxPosition(intptr_t value) const;
#endif // !defined(DART_PRECOMPILED_RUNTIME)
+#if defined(DART_PRECOMPILER)
+ void set_resolved_url(const Object& value) const;
+#else
void set_resolved_url(const String& value) const;
+#endif
void set_source(const String& value) const;
void set_load_timestamp(int64_t value) const;
ArrayPtr debug_positions() const;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index a50a643..f386161 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1486,7 +1486,13 @@
VISIT_FROM(CompressedObjectPtr, url)
COMPRESSED_POINTER_FIELD(StringPtr, url)
+#if defined(DART_PRECOMPILER)
+ // We use WSRs to keep the information available to the DWARF writer
+ // without being actually serialized.
+ COMPRESSED_POINTER_FIELD(ObjectPtr, resolved_url)
+#else
COMPRESSED_POINTER_FIELD(StringPtr, resolved_url)
+#endif
COMPRESSED_POINTER_FIELD(ArrayPtr, compile_time_constants)
COMPRESSED_POINTER_FIELD(TypedDataPtr, line_starts)
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index fe33fb5..8b6fec7 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -2837,15 +2837,18 @@
(instr->Bit(8) == 1) && (instr->Bits(5, 2) == 0)) {
DRegister dn = instr->DnField();
Register rd = instr->RdField();
+ const int32_t src_value = get_register(rd);
+ const int64_t dst_value = get_dregister_bits(dn);
+ int32_t dst_lo = Utils::Low32Bits(dst_value);
+ int32_t dst_hi = Utils::High32Bits(dst_value);
if (instr->Bit(21) == 0) {
- // Format(instr, "vmovd'cond 'dd[0], 'rd");
- SRegister sd = EvenSRegisterOf(dn);
- set_sregister_bits(sd, get_register(rd));
+ // Format(instr, "vmovd'cond 'dn[0], 'rd");
+ dst_lo = src_value;
} else {
- // Format(instr, "vmovd'cond 'dd[1], 'rd");
- SRegister sd = OddSRegisterOf(dn);
- set_sregister_bits(sd, get_register(rd));
+ // Format(instr, "vmovd'cond 'dn[1], 'rd");
+ dst_hi = src_value;
}
+ set_dregister_bits(dn, Utils::LowHighTo64Bits(dst_lo, dst_hi));
} else if ((instr->Bits(20, 4) == 0xf) && (instr->Bit(8) == 0)) {
if (instr->Bits(12, 4) == 0xf) {
// Format(instr, "vmrs'cond APSR, FPSCR");
diff --git a/tools/VERSION b/tools/VERSION
index 0364727..fac5e16 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 44
+PRERELEASE 45
PRERELEASE_PATCH 0
\ No newline at end of file