[vm] Fix to ensure positions from CSMs in precompiled are as expected.

Token positions in the CodeSourceMap are converted to line
numbers (or kNoSourcePos if no line number) in precompiled mode.
Fix the reader so that it uses kNoSource as the initial position
in precompiled mode instead of kDartPrologue.

This conversion never happens to token positions in PcDescriptors
objects, so we should never treat a position coming from them (i.e.,
via GetTokenIndexForPC) as a line.

Bug: https://github.com/dart-lang/sdk/issues/44492

TEST=Run on debug precomp trybot to verify fixed.

Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try
Change-Id: Ib4d4be94240997b8bcd6b134b786e82d77875a21
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/176246
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index e75d702..6d6ef31 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -437,7 +437,7 @@
 
   int32_t current_pc_offset = 0;
   function_stack->Add(&root_);
-  token_positions->Add(CodeSourceMapBuilder::kInitialPosition);
+  token_positions->Add(InitialPosition());
 
   while (stream.PendingBytes() > 0) {
     uint8_t opcode = stream.Read<uint8_t>();
@@ -459,7 +459,7 @@
         int32_t func = stream.Read<int32_t>();
         function_stack->Add(
             &Function::Handle(Function::RawCast(functions_.At(func))));
-        token_positions->Add(CodeSourceMapBuilder::kInitialPosition);
+        token_positions->Add(InitialPosition());
         break;
       }
       case CodeSourceMapBuilder::kPopFunction: {
@@ -603,7 +603,7 @@
 
   int32_t current_pc_offset = 0;
   function_stack.Add(&root_);
-  token_positions.Add(CodeSourceMapBuilder::kInitialPosition);
+  token_positions.Add(InitialPosition());
 
   THR_Print("Source positions for function '%s' {\n",
             root_.ToFullyQualifiedCString());
@@ -630,7 +630,7 @@
         int32_t func = stream.Read<int32_t>();
         function_stack.Add(
             &Function::Handle(Function::RawCast(functions_.At(func))));
-        token_positions.Add(CodeSourceMapBuilder::kInitialPosition);
+        token_positions.Add(InitialPosition());
         break;
       }
       case CodeSourceMapBuilder::kPopFunction: {
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index bb2f773..8bc6350 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -292,6 +292,16 @@
   intptr_t GetNullCheckNameIndexAt(int32_t pc_offset);
 
  private:
+  static const TokenPosition& InitialPosition() {
+    if (FLAG_precompiled_mode) {
+      // In precompiled mode, the CodeSourceMap stores lines instead of
+      // real token positions and uses kNoSourcePos for no line information.
+      return TokenPosition::kNoSource;
+    } else {
+      return CodeSourceMapBuilder::kInitialPosition;
+    }
+  }
+
   // Reads a TokenPosition value from a CSM, handling the different encoding for
   // when non-symbolic stack traces are enabled.
   static TokenPosition ReadPosition(ReadStream* stream);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 70d603b..8b790ce 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -24223,8 +24223,9 @@
 static void PrintSymbolicStackFrame(Zone* zone,
                                     BaseTextBuffer* buffer,
                                     const Function& function,
-                                    TokenPosition token_pos,
-                                    intptr_t frame_index) {
+                                    TokenPosition token_pos_or_line,
+                                    intptr_t frame_index,
+                                    bool is_line = false) {
   ASSERT(!function.IsNull());
   const auto& script = Script::Handle(zone, function.script());
   const char* function_name = function.QualifiedUserVisibleNameCString();
@@ -24240,14 +24241,14 @@
 
   intptr_t line = -1;
   intptr_t column = -1;
-  if (FLAG_precompiled_mode) {
-    ASSERT(token_pos.IsNoSource() || token_pos.IsReal());
-    if (token_pos.IsReal()) {
-      line = token_pos.Pos();
+  if (is_line) {
+    ASSERT(token_pos_or_line.IsNoSource() || token_pos_or_line.IsReal());
+    if (token_pos_or_line.IsReal()) {
+      line = token_pos_or_line.Pos();
     }
   } else {
     ASSERT(!script.IsNull());
-    script.GetTokenLocation(token_pos, &line, &column);
+    script.GetTokenLocation(token_pos_or_line, &line, &column);
   }
   PrintSymbolicStackFrameIndex(buffer, frame_index);
   PrintSymbolicStackFrameBody(buffer, function_name, url, line, column);
@@ -24401,7 +24402,8 @@
         for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) {
           const auto& inlined = *inlined_functions[j];
           auto const pos = inlined_token_positions[j];
-          PrintSymbolicStackFrame(zone, &buffer, inlined, pos, frame_index);
+          PrintSymbolicStackFrame(zone, &buffer, inlined, pos, frame_index,
+                                  /*is_line=*/FLAG_precompiled_mode);
           frame_index++;
         }
         continue;