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