Get source mapping table from stack maps.

Stack maps contain pc to dex mapping.
Reuse them instead of maintaining separate map.

Change-Id: Iaaec9a6bd2603eace1dfc8f4344087883d88cce3
diff --git a/compiler/elf_writer_debug.cc b/compiler/elf_writer_debug.cc
index 7696b94..c5c0f13 100644
--- a/compiler/elf_writer_debug.cc
+++ b/compiler/elf_writer_debug.cc
@@ -416,6 +416,13 @@
 
     return variable_locations;
   }
+
+  bool IsFromOptimizingCompiler(const MethodDebugInfo* method_info) {
+    return method_info->compiled_method_->GetQuickCode().size() > 0 &&
+           method_info->compiled_method_->GetVmapTable().size() > 0 &&
+           method_info->compiled_method_->GetGcMap().size() == 0 &&
+           method_info->code_item_ != nullptr;
+  }
 }  // namespace
 
 // Helper class to write .debug_info and its supporting sections.
@@ -558,11 +565,7 @@
                           uint32_t dex_pc_low = 0,
                           uint32_t dex_pc_high = 0xFFFFFFFF) {
       using Kind = DexRegisterLocation::Kind;
-      bool is_optimizing = method_info->compiled_method_->GetQuickCode().size() > 0 &&
-                           method_info->compiled_method_->GetVmapTable().size() > 0 &&
-                           method_info->compiled_method_->GetGcMap().size() == 0 &&
-                           method_info->code_item_ != nullptr;
-      if (!is_optimizing) {
+      if (!IsFromOptimizingCompiler(method_info)) {
         return;
       }
 
@@ -940,10 +943,6 @@
         break;
     }
     DebugLineOpCodeWriter<> opcodes(is64bit, code_factor_bits_);
-    opcodes.SetAddress(text_address + compilation_unit.low_pc_);
-    if (dwarf_isa != -1) {
-      opcodes.SetISA(dwarf_isa);
-    }
     for (const MethodDebugInfo* mi : compilation_unit.methods_) {
       // Ignore function if we have already generated line table for the same address.
       // It would confuse the debugger and the DWARF specification forbids it.
@@ -951,6 +950,32 @@
         continue;
       }
 
+      ArrayRef<const SrcMapElem> src_mapping_table;
+      std::vector<SrcMapElem> src_mapping_table_from_stack_maps;
+      if (IsFromOptimizingCompiler(mi)) {
+        // Use stack maps to create mapping table from pc to dex.
+        const CodeInfo code_info(mi->compiled_method_->GetVmapTable().data());
+        const StackMapEncoding encoding = code_info.ExtractEncoding();
+        for (uint32_t s = 0; s < code_info.GetNumberOfStackMaps(); s++) {
+          StackMap stack_map = code_info.GetStackMapAt(s, encoding);
+          DCHECK(stack_map.IsValid());
+          const uint32_t pc = stack_map.GetNativePcOffset(encoding);
+          const int32_t dex = stack_map.GetDexPc(encoding);
+          src_mapping_table_from_stack_maps.push_back({pc, dex});
+        }
+        std::sort(src_mapping_table_from_stack_maps.begin(),
+                  src_mapping_table_from_stack_maps.end());
+        src_mapping_table = ArrayRef<const SrcMapElem>(src_mapping_table_from_stack_maps);
+      } else {
+        // Use the mapping table provided by the quick compiler.
+        src_mapping_table = mi->compiled_method_->GetSrcMappingTable();
+      }
+
+      if (src_mapping_table.empty()) {
+        continue;
+      }
+
+      // Create mapping table from dex to source line.
       struct DebugInfoCallbacks {
         static bool NewPosition(void* ctx, uint32_t address, uint32_t line) {
           auto* context = static_cast<DebugInfoCallbacks*>(ctx);
@@ -972,6 +997,15 @@
                              &debug_info_callbacks);
       }
 
+      if (debug_info_callbacks.dex2line_.empty()) {
+        continue;
+      }
+
+      opcodes.SetAddress(method_address);
+      if (dwarf_isa != -1) {
+        opcodes.SetISA(dwarf_isa);
+      }
+
       // Get and deduplicate directory and filename.
       int file_index = 0;  // 0 - primary source file of the compilation.
       auto& dex_class_def = dex->GetClassDef(mi->class_def_index_);
@@ -1021,7 +1055,7 @@
       const DefaultSrcMap& dex2line_map = debug_info_callbacks.dex2line_;
       if (file_index != 0 && !dex2line_map.empty()) {
         bool first = true;
-        for (SrcMapElem pc2dex : mi->compiled_method_->GetSrcMappingTable()) {
+        for (SrcMapElem pc2dex : src_mapping_table) {
           uint32_t pc = pc2dex.from_;
           int dex_pc = pc2dex.to_;
           auto dex2line = dex2line_map.Find(static_cast<uint32_t>(dex_pc));
@@ -1048,9 +1082,10 @@
         // line 0 - instruction cannot be attributed to any source line.
         opcodes.AddRow(method_address, 0);
       }
+
+      opcodes.AdvancePC(text_address + mi->high_pc_);
+      opcodes.EndSequence();
     }
-    opcodes.AdvancePC(text_address + compilation_unit.high_pc_);
-    opcodes.EndSequence();
     std::vector<uint8_t> buffer;
     buffer.reserve(opcodes.data()->size() + KB);
     size_t offset = builder_->GetDebugLine()->GetSize();
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index 0baa0e3..53d3615 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -246,10 +246,7 @@
         InitLocationsBaseline(current);
       }
       DCHECK(CheckTypeConsistency(current));
-      uintptr_t native_pc_begin = GetAssembler()->CodeSize();
       current->Accept(instruction_visitor);
-      uintptr_t native_pc_end = GetAssembler()->CodeSize();
-      RecordNativeDebugInfo(current->GetDexPc(), native_pc_begin, native_pc_end);
     }
   }
 
@@ -926,17 +923,6 @@
   stack_map_stream_.FillIn(region);
 }
 
-void CodeGenerator::RecordNativeDebugInfo(uint32_t dex_pc,
-                                          uintptr_t native_pc_begin,
-                                          uintptr_t native_pc_end) {
-  if (compiler_options_.GetGenerateDebugInfo() &&
-      dex_pc != kNoDexPc &&
-      native_pc_begin != native_pc_end) {
-    src_map_.push_back(SrcMapElem({static_cast<uint32_t>(native_pc_begin),
-                                   static_cast<int32_t>(dex_pc)}));
-  }
-}
-
 void CodeGenerator::RecordPcInfo(HInstruction* instruction,
                                  uint32_t dex_pc,
                                  SlowPathCode* slow_path) {
diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h
index 114d97b..eade05d 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -269,8 +269,6 @@
 
   // Record native to dex mapping for a suspend point.  Required by runtime.
   void RecordPcInfo(HInstruction* instruction, uint32_t dex_pc, SlowPathCode* slow_path = nullptr);
-  // Record additional native to dex mappings for native debugging/profiling tools.
-  void RecordNativeDebugInfo(uint32_t dex_pc, uintptr_t native_pc_begin, uintptr_t native_pc_end);
 
   bool CanMoveNullCheckToUser(HNullCheck* null_check);
   void MaybeRecordImplicitNullCheck(HInstruction* instruction);
@@ -452,10 +450,6 @@
   // Copy the result of a call into the given target.
   virtual void MoveFromReturnRegister(Location trg, Primitive::Type type) = 0;
 
-  const ArenaVector<SrcMapElem>& GetSrcMappingTable() const {
-    return src_map_;
-  }
-
  protected:
   // Method patch info used for recording locations of required linker patches and
   // target methods. The target method can be used for various purposes, whether for
@@ -498,7 +492,6 @@
         stats_(stats),
         graph_(graph),
         compiler_options_(compiler_options),
-        src_map_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
         slow_paths_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
         current_slow_path_(nullptr),
         current_block_index_(0),
@@ -616,8 +609,6 @@
   HGraph* const graph_;
   const CompilerOptions& compiler_options_;
 
-  // Native to dex_pc map used for native debugging/profiling tools.
-  ArenaVector<SrcMapElem> src_map_;
   ArenaVector<SlowPathCode*> slow_paths_;
 
   // The current slow path that we're generating code for.
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 4643aed..831b626 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -614,7 +614,7 @@
       codegen->HasEmptyFrame() ? 0 : codegen->GetFrameSize(),
       codegen->GetCoreSpillMask(),
       codegen->GetFpuSpillMask(),
-      ArrayRef<const SrcMapElem>(codegen->GetSrcMappingTable()),
+      ArrayRef<const SrcMapElem>(),
       ArrayRef<const uint8_t>(),  // mapping_table.
       ArrayRef<const uint8_t>(stack_map),
       ArrayRef<const uint8_t>(),  // native_gc_map.
@@ -648,7 +648,7 @@
       codegen->HasEmptyFrame() ? 0 : codegen->GetFrameSize(),
       codegen->GetCoreSpillMask(),
       codegen->GetFpuSpillMask(),
-      ArrayRef<const SrcMapElem>(codegen->GetSrcMappingTable()),
+      ArrayRef<const SrcMapElem>(),
       AlignVectorSize(mapping_table),
       AlignVectorSize(vmap_table),
       AlignVectorSize(gc_map),