Refactor MethodDebugInfo (input of DWARF writer).

Do not pass CompiledMethod pointer through since it is only available
during AOT compile but not during JIT compile or at runtime. Creating
mock CompiledMethod just pass data is proving increasingly tricky, so
copy the fields that we need to MethodDebugInfo instead.

Change-Id: I820297b41e769fcac488c0ff2d2ea0492bb13ed8
diff --git a/compiler/debug/elf_compilation_unit.h b/compiler/debug/elf_compilation_unit.h
index f725f45..b1d89eb 100644
--- a/compiler/debug/elf_compilation_unit.h
+++ b/compiler/debug/elf_compilation_unit.h
@@ -27,8 +27,9 @@
 struct ElfCompilationUnit {
   std::vector<const MethodDebugInfo*> methods;
   size_t debug_line_offset = 0;
-  uintptr_t low_pc = std::numeric_limits<uintptr_t>::max();
-  uintptr_t high_pc = 0;
+  bool is_code_address_text_relative;  // Is the address offset from start of .text section?
+  uint64_t code_address = std::numeric_limits<uint64_t>::max();
+  uint64_t code_end = 0;
 };
 
 }  // namespace debug
diff --git a/compiler/debug/elf_debug_frame_writer.h b/compiler/debug/elf_debug_frame_writer.h
index f6d9b16..badbd93 100644
--- a/compiler/debug/elf_debug_frame_writer.h
+++ b/compiler/debug/elf_debug_frame_writer.h
@@ -200,8 +200,8 @@
       sorted_method_infos.begin(),
       sorted_method_infos.end(),
       [](const MethodDebugInfo* lhs, const MethodDebugInfo* rhs) {
-        ArrayRef<const uint8_t> l = lhs->compiled_method->GetCFIInfo();
-        ArrayRef<const uint8_t> r = rhs->compiled_method->GetCFIInfo();
+        ArrayRef<const uint8_t> l = lhs->cfi;
+        ArrayRef<const uint8_t> r = rhs->cfi;
         return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
       });
 
@@ -212,9 +212,6 @@
   {
     cfi_section->Start();
     const bool is64bit = Is64BitInstructionSet(builder->GetIsa());
-    const Elf_Addr text_address = builder->GetText()->Exists()
-        ? builder->GetText()->GetAddress()
-        : 0;
     const Elf_Addr cfi_address = cfi_section->GetAddress();
     const Elf_Addr cie_address = cfi_address;
     Elf_Addr buffer_address = cfi_address;
@@ -225,9 +222,10 @@
     buffer.clear();
     for (const MethodDebugInfo* mi : sorted_method_infos) {
       if (!mi->deduped) {  // Only one FDE per unique address.
-        ArrayRef<const uint8_t> opcodes = mi->compiled_method->GetCFIInfo();
+        ArrayRef<const uint8_t> opcodes = mi->cfi;
         if (!opcodes.empty()) {
-          const Elf_Addr code_address = text_address + mi->low_pc;
+          const Elf_Addr code_address = mi->code_address +
+              (mi->is_code_address_text_relative ? builder->GetText()->GetAddress() : 0);
           if (format == dwarf::DW_EH_FRAME_FORMAT) {
             binary_search_table.push_back(
                 dchecked_integral_cast<uint32_t>(code_address));
@@ -235,7 +233,7 @@
                 dchecked_integral_cast<uint32_t>(buffer_address));
           }
           WriteFDE(is64bit, cfi_address, cie_address,
-                   code_address, mi->high_pc - mi->low_pc,
+                   code_address, mi->code_size,
                    opcodes, format, buffer_address, &buffer,
                    &patch_locations);
           cfi_section->WriteFully(buffer.data(), buffer.size());
diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h
index bddb054..af74d4c 100644
--- a/compiler/debug/elf_debug_info_writer.h
+++ b/compiler/debug/elf_debug_info_writer.h
@@ -117,17 +117,17 @@
 
   void Write(const ElfCompilationUnit& compilation_unit) {
     CHECK(!compilation_unit.methods.empty());
-    const Elf_Addr text_address = owner_->builder_->GetText()->Exists()
+    const Elf_Addr base_address = compilation_unit.is_code_address_text_relative
         ? owner_->builder_->GetText()->GetAddress()
         : 0;
-    const uintptr_t cu_size = compilation_unit.high_pc - compilation_unit.low_pc;
+    const uint64_t cu_size = compilation_unit.code_end - compilation_unit.code_address;
     using namespace dwarf;  // NOLINT. For easy access to DWARF constants.
 
     info_.StartTag(DW_TAG_compile_unit);
     info_.WriteString(DW_AT_producer, "Android dex2oat");
     info_.WriteData1(DW_AT_language, DW_LANG_Java);
     info_.WriteString(DW_AT_comp_dir, "$JAVA_SRC_ROOT");
-    info_.WriteAddr(DW_AT_low_pc, text_address + compilation_unit.low_pc);
+    info_.WriteAddr(DW_AT_low_pc, base_address + compilation_unit.code_address);
     info_.WriteUdata(DW_AT_high_pc, dchecked_integral_cast<uint32_t>(cu_size));
     info_.WriteSecOffset(DW_AT_stmt_list, compilation_unit.debug_line_offset);
 
@@ -165,8 +165,8 @@
       int start_depth = info_.Depth();
       info_.StartTag(DW_TAG_subprogram);
       WriteName(dex->GetMethodName(dex_method));
-      info_.WriteAddr(DW_AT_low_pc, text_address + mi->low_pc);
-      info_.WriteUdata(DW_AT_high_pc, dchecked_integral_cast<uint32_t>(mi->high_pc-mi->low_pc));
+      info_.WriteAddr(DW_AT_low_pc, base_address + mi->code_address);
+      info_.WriteUdata(DW_AT_high_pc, mi->code_size);
       std::vector<uint8_t> expr_buffer;
       Expression expr(&expr_buffer);
       expr.WriteOpCallFrameCfa();
@@ -176,8 +176,8 @@
       // Decode dex register locations for all stack maps.
       // It might be expensive, so do it just once and reuse the result.
       std::vector<DexRegisterMap> dex_reg_maps;
-      if (mi->IsFromOptimizingCompiler()) {
-        const CodeInfo code_info(mi->compiled_method->GetVmapTable().data());
+      if (mi->code_info != nullptr) {
+        const CodeInfo code_info(mi->code_info);
         StackMapEncoding encoding = code_info.ExtractEncoding();
         for (size_t s = 0; s < code_info.GetNumberOfStackMaps(); ++s) {
           const StackMap& stack_map = code_info.GetStackMapAt(s, encoding);
@@ -200,7 +200,7 @@
           // Write the stack location of the parameter.
           const uint32_t vreg = dex_code->registers_size_ - dex_code->ins_size_ + arg_reg;
           const bool is64bitValue = false;
-          WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.low_pc);
+          WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.code_address);
         }
         arg_reg++;
         info_.EndTag();
@@ -219,7 +219,7 @@
           if (dex_code != nullptr) {
             // Write the stack location of the parameter.
             const uint32_t vreg = dex_code->registers_size_ - dex_code->ins_size_ + arg_reg;
-            WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.low_pc);
+            WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.code_address);
           }
           arg_reg += is64bitValue ? 2 : 1;
           info_.EndTag();
@@ -246,7 +246,7 @@
                              dex_reg_maps,
                              var.reg_,
                              is64bitValue,
-                             compilation_unit.low_pc,
+                             compilation_unit.code_address,
                              var.start_address_,
                              var.end_address_);
             info_.EndTag();
@@ -445,14 +445,14 @@
                         const std::vector<DexRegisterMap>& dex_register_maps,
                         uint16_t vreg,
                         bool is64bitValue,
-                        uint32_t compilation_unit_low_pc,
+                        uint64_t compilation_unit_code_address,
                         uint32_t dex_pc_low = 0,
                         uint32_t dex_pc_high = 0xFFFFFFFF) {
     WriteDebugLocEntry(method_info,
                        dex_register_maps,
                        vreg,
                        is64bitValue,
-                       compilation_unit_low_pc,
+                       compilation_unit_code_address,
                        dex_pc_low,
                        dex_pc_high,
                        owner_->builder_->GetIsa(),
diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h
index 11be4e9..ed26d96 100644
--- a/compiler/debug/elf_debug_line_writer.h
+++ b/compiler/debug/elf_debug_line_writer.h
@@ -53,7 +53,7 @@
   // Returns the number of bytes written.
   size_t WriteCompilationUnit(ElfCompilationUnit& compilation_unit) {
     const bool is64bit = Is64BitInstructionSet(builder_->GetIsa());
-    const Elf_Addr text_address = builder_->GetText()->Exists()
+    const Elf_Addr base_address = compilation_unit.is_code_address_text_relative
         ? builder_->GetText()->GetAddress()
         : 0;
 
@@ -90,37 +90,31 @@
       }
 
       uint32_t prologue_end = std::numeric_limits<uint32_t>::max();
-      ArrayRef<const SrcMapElem> pc2dex_map;
-      std::vector<SrcMapElem> pc2dex_map_from_stack_maps;
-      if (mi->IsFromOptimizingCompiler()) {
+      std::vector<SrcMapElem> pc2dex_map;
+      if (mi->code_info != nullptr) {
         // Use stack maps to create mapping table from pc to dex.
-        const CodeInfo code_info(mi->compiled_method->GetVmapTable().data());
+        const CodeInfo code_info(mi->code_info);
         const StackMapEncoding encoding = code_info.ExtractEncoding();
+        pc2dex_map.reserve(code_info.GetNumberOfStackMaps());
         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);
-          pc2dex_map_from_stack_maps.push_back({pc, dex});
+          pc2dex_map.push_back({pc, dex});
           if (stack_map.HasDexRegisterMap(encoding)) {
             // Guess that the first map with local variables is the end of prologue.
             prologue_end = std::min(prologue_end, pc);
           }
         }
-        std::sort(pc2dex_map_from_stack_maps.begin(),
-                  pc2dex_map_from_stack_maps.end());
-        pc2dex_map = ArrayRef<const SrcMapElem>(pc2dex_map_from_stack_maps);
-      } else {
-        // Use the mapping table provided by the quick compiler.
-        pc2dex_map = mi->compiled_method->GetSrcMappingTable();
-        prologue_end = 0;
+        std::sort(pc2dex_map.begin(), pc2dex_map.end());
       }
 
       if (pc2dex_map.empty()) {
         continue;
       }
 
-      Elf_Addr method_address = text_address + mi->low_pc;
+      Elf_Addr method_address = base_address + mi->code_address;
 
       PositionInfos dex2line_map;
       const DexFile* dex = mi->dex_file;
@@ -226,7 +220,7 @@
         opcodes.AddRow(method_address, 0);
       }
 
-      opcodes.AdvancePC(text_address + mi->high_pc);
+      opcodes.AdvancePC(method_address + mi->code_size);
       opcodes.EndSequence();
     }
     std::vector<uint8_t> buffer;
diff --git a/compiler/debug/elf_debug_loc_writer.h b/compiler/debug/elf_debug_loc_writer.h
index c321b4b..2d4fff4 100644
--- a/compiler/debug/elf_debug_loc_writer.h
+++ b/compiler/debug/elf_debug_loc_writer.h
@@ -74,8 +74,8 @@
 }
 
 struct VariableLocation {
-  uint32_t low_pc;
-  uint32_t high_pc;
+  uint32_t low_pc;  // Relative to compilation unit.
+  uint32_t high_pc;  // Relative to compilation unit.
   DexRegisterLocation reg_lo;  // May be None if the location is unknown.
   DexRegisterLocation reg_hi;  // Most significant bits of 64-bit value.
 };
@@ -90,19 +90,23 @@
     const std::vector<DexRegisterMap>& dex_register_maps,
     uint16_t vreg,
     bool is64bitValue,
+    uint64_t compilation_unit_code_address,
     uint32_t dex_pc_low,
     uint32_t dex_pc_high) {
   std::vector<VariableLocation> variable_locations;
 
   // Get stack maps sorted by pc (they might not be sorted internally).
-  const CodeInfo code_info(method_info->compiled_method->GetVmapTable().data());
+  const CodeInfo code_info(method_info->code_info);
   const StackMapEncoding encoding = code_info.ExtractEncoding();
   std::map<uint32_t, uint32_t> stack_maps;  // low_pc -> stack_map_index.
   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 low_pc = method_info->low_pc + stack_map.GetNativePcOffset(encoding);
-    DCHECK_LE(low_pc, method_info->high_pc);
+    const uint32_t pc_offset = stack_map.GetNativePcOffset(encoding);
+    DCHECK_LE(pc_offset, method_info->code_size);
+    DCHECK_LE(compilation_unit_code_address, method_info->code_address);
+    const uint32_t low_pc = dchecked_integral_cast<uint32_t>(
+        method_info->code_address + pc_offset - compilation_unit_code_address);
     stack_maps.emplace(low_pc, s);
   }
 
@@ -113,8 +117,9 @@
     const StackMap& stack_map = code_info.GetStackMapAt(stack_map_index, encoding);
     auto next_it = it;
     next_it++;
-    const uint32_t high_pc = next_it != stack_maps.end() ? next_it->first
-                                                         : method_info->high_pc;
+    const uint32_t high_pc = next_it != stack_maps.end()
+      ? next_it->first
+      : method_info->code_address + method_info->code_size - compilation_unit_code_address;
     DCHECK_LE(low_pc, high_pc);
     if (low_pc == high_pc) {
       continue;  // Ignore if the address range is empty.
@@ -165,7 +170,7 @@
                                const std::vector<DexRegisterMap>& dex_register_maps,
                                uint16_t vreg,
                                bool is64bitValue,
-                               uint32_t compilation_unit_low_pc,
+                               uint64_t compilation_unit_code_address,
                                uint32_t dex_pc_low,
                                uint32_t dex_pc_high,
                                InstructionSet isa,
@@ -173,7 +178,7 @@
                                std::vector<uint8_t>* debug_loc_buffer,
                                std::vector<uint8_t>* debug_ranges_buffer) {
   using Kind = DexRegisterLocation::Kind;
-  if (!method_info->IsFromOptimizingCompiler()) {
+  if (method_info->code_info == nullptr || dex_register_maps.empty()) {
     return;
   }
 
@@ -182,6 +187,7 @@
       dex_register_maps,
       vreg,
       is64bitValue,
+      compilation_unit_code_address,
       dex_pc_low,
       dex_pc_high);
 
@@ -202,9 +208,8 @@
       const Kind kind = reg_loc.GetKind();
       const int32_t value = reg_loc.GetValue();
       if (kind == Kind::kInStack) {
-        const size_t frame_size = method_info->compiled_method->GetFrameSizeInBytes();
         // The stack offset is relative to SP. Make it relative to CFA.
-        expr.WriteOpFbreg(value - frame_size);
+        expr.WriteOpFbreg(value - method_info->frame_size_in_bytes);
         if (piece == 0 && reg_hi.GetKind() == Kind::kInStack &&
             reg_hi.GetValue() == value + 4) {
           break;  // the high word is correctly implied by the low word.
@@ -249,11 +254,11 @@
 
     if (expr.size() > 0) {
       if (is64bit) {
-        debug_loc.PushUint64(variable_location.low_pc - compilation_unit_low_pc);
-        debug_loc.PushUint64(variable_location.high_pc - compilation_unit_low_pc);
+        debug_loc.PushUint64(variable_location.low_pc);
+        debug_loc.PushUint64(variable_location.high_pc);
       } else {
-        debug_loc.PushUint32(variable_location.low_pc - compilation_unit_low_pc);
-        debug_loc.PushUint32(variable_location.high_pc - compilation_unit_low_pc);
+        debug_loc.PushUint32(variable_location.low_pc);
+        debug_loc.PushUint32(variable_location.high_pc);
       }
       // Write the expression.
       debug_loc.PushUint16(expr.size());
@@ -283,11 +288,11 @@
       high_pc = variable_locations[++i].high_pc;
     }
     if (is64bit) {
-      debug_ranges.PushUint64(low_pc - compilation_unit_low_pc);
-      debug_ranges.PushUint64(high_pc - compilation_unit_low_pc);
+      debug_ranges.PushUint64(low_pc);
+      debug_ranges.PushUint64(high_pc);
     } else {
-      debug_ranges.PushUint32(low_pc - compilation_unit_low_pc);
-      debug_ranges.PushUint32(high_pc - compilation_unit_low_pc);
+      debug_ranges.PushUint32(low_pc);
+      debug_ranges.PushUint32(high_pc);
     }
   }
   // Write end-of-list entry.
diff --git a/compiler/debug/elf_debug_writer.cc b/compiler/debug/elf_debug_writer.cc
index 79069d1..4f2a007 100644
--- a/compiler/debug/elf_debug_writer.cc
+++ b/compiler/debug/elf_debug_writer.cc
@@ -62,8 +62,11 @@
     }
     ElfCompilationUnit& cu = compilation_units.back();
     cu.methods.push_back(&mi);
-    cu.low_pc = std::min(cu.low_pc, mi.low_pc);
-    cu.high_pc = std::max(cu.high_pc, mi.high_pc);
+    // All methods must have the same addressing mode otherwise the min/max below does not work.
+    DCHECK_EQ(cu.methods.front()->is_code_address_text_relative, mi.is_code_address_text_relative);
+    cu.is_code_address_text_relative = mi.is_code_address_text_relative;
+    cu.code_address = std::min(cu.code_address, mi.code_address);
+    cu.code_end = std::max(cu.code_end, mi.code_address + mi.code_size);
     last_source_file = source_file;
   }
 
diff --git a/compiler/debug/elf_symtab_writer.h b/compiler/debug/elf_symtab_writer.h
index 41508f4..0a199da 100644
--- a/compiler/debug/elf_symtab_writer.h
+++ b/compiler/debug/elf_symtab_writer.h
@@ -47,12 +47,12 @@
     return;
   }
 
-  // Find all addresses (low_pc) which contain deduped methods.
+  // Find all addresses which contain deduped methods.
   // The first instance of method is not marked deduped_, but the rest is.
-  std::unordered_set<uint32_t> deduped_addresses;
+  std::unordered_set<uint64_t> deduped_addresses;
   for (const MethodDebugInfo& info : method_infos) {
     if (info.deduped) {
-      deduped_addresses.insert(info.low_pc);
+      deduped_addresses.insert(info.code_address);
     }
   }
 
@@ -65,33 +65,25 @@
       continue;  // Add symbol only for the first instance.
     }
     std::string name = PrettyMethod(info.dex_method_index, *info.dex_file, with_signature);
-    if (deduped_addresses.find(info.low_pc) != deduped_addresses.end()) {
+    if (deduped_addresses.find(info.code_address) != deduped_addresses.end()) {
       name += " [DEDUPED]";
     }
     // If we write method names without signature, we might see the same name multiple times.
     size_t name_offset = (name == last_name ? last_name_offset : strtab->Write(name));
 
-    const auto* text = builder->GetText()->Exists() ? builder->GetText() : nullptr;
-    const bool is_relative = (text != nullptr);
-    uint32_t low_pc = info.low_pc;
+    const auto* text = info.is_code_address_text_relative ? builder->GetText() : nullptr;
+    uint64_t address = info.code_address + (text != nullptr ? text->GetAddress() : 0);
     // Add in code delta, e.g., thumb bit 0 for Thumb2 code.
-    low_pc += info.compiled_method->CodeDelta();
-    symtab->Add(name_offset,
-                text,
-                low_pc,
-                is_relative,
-                info.high_pc - info.low_pc,
-                STB_GLOBAL,
-                STT_FUNC);
+    address += CompiledMethod::CodeDelta(info.isa);
+    symtab->Add(name_offset, text, address, info.code_size, STB_GLOBAL, STT_FUNC);
 
     // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2
     // instructions, so that disassembler tools can correctly disassemble.
     // Note that even if we generate just a single mapping symbol, ARM's Streamline
     // requires it to match function symbol.  Just address 0 does not work.
-    if (info.compiled_method->GetInstructionSet() == kThumb2) {
+    if (info.isa == kThumb2) {
       if (!generated_mapping_symbol || !kGenerateSingleArmMappingSymbol) {
-        symtab->Add(strtab->Write("$t"), text, info.low_pc & ~1,
-                    is_relative, 0, STB_LOCAL, STT_NOTYPE);
+        symtab->Add(strtab->Write("$t"), text, address & ~1, 0, STB_LOCAL, STT_NOTYPE);
         generated_mapping_symbol = true;
       }
     }
diff --git a/compiler/debug/method_debug_info.h b/compiler/debug/method_debug_info.h
index bb09f7e..1ccc705 100644
--- a/compiler/debug/method_debug_info.h
+++ b/compiler/debug/method_debug_info.h
@@ -29,18 +29,16 @@
   uint32_t dex_method_index;
   uint32_t access_flags;
   const DexFile::CodeItem* code_item;
+  InstructionSet isa;
   bool deduped;
   bool is_native_debuggable;
-  uintptr_t low_pc;
-  uintptr_t high_pc;
-  CompiledMethod* compiled_method;
-
-  bool IsFromOptimizingCompiler() const {
-    return compiled_method->GetQuickCode().size() > 0 &&
-           compiled_method->GetVmapTable().size() > 0 &&
-           compiled_method->GetGcMap().size() == 0 &&
-           code_item != nullptr;
-  }
+  bool is_optimized;
+  bool is_code_address_text_relative;  // Is the address offset from start of .text section?
+  uint64_t code_address;
+  uint32_t code_size;
+  uint32_t frame_size_in_bytes;
+  const uint8_t* code_info;
+  ArrayRef<const uint8_t> cfi;
 };
 
 }  // namespace debug
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
index 943e2a8..42f4e41 100644
--- a/compiler/elf_builder.h
+++ b/compiler/elf_builder.h
@@ -164,12 +164,6 @@
       }
     }
 
-    // Returns true if the section was written to disk.
-    // (Used to check whether we have .text when writing JIT debug info)
-    bool Exists() const {
-      return finished_;
-    }
-
     // Get the location of this section in virtual memory.
     Elf_Addr GetAddress() const {
       CHECK(started_);
@@ -363,16 +357,18 @@
     void Add(Elf_Word name,
              const Section* section,
              Elf_Addr addr,
-             bool is_relative,
              Elf_Word size,
              uint8_t binding,
-             uint8_t type,
-             uint8_t other = 0) {
-      DCHECK(section != nullptr || !is_relative);
-      Elf_Addr abs_addr = addr + (is_relative ? section->GetAddress() : 0);
-      Elf_Word section_index =
-          (section != nullptr) ? section->GetSectionIndex() : static_cast<Elf_Word>(SHN_ABS);
-      Add(name, section_index, abs_addr, size, binding, type, other);
+             uint8_t type) {
+      Elf_Word section_index;
+      if (section != nullptr) {
+        DCHECK_LE(section->GetAddress(), addr);
+        DCHECK_LE(addr, section->GetAddress() + section->GetSize());
+        section_index = section->GetSectionIndex();
+      } else {
+        section_index = static_cast<Elf_Word>(SHN_ABS);
+      }
+      Add(name, section_index, addr, size, binding, type);
     }
 
     void Add(Elf_Word name,
@@ -380,13 +376,12 @@
              Elf_Addr addr,
              Elf_Word size,
              uint8_t binding,
-             uint8_t type,
-             uint8_t other = 0) {
+             uint8_t type) {
       Elf_Sym sym = Elf_Sym();
       sym.st_name = name;
       sym.st_value = addr;
       sym.st_size = size;
-      sym.st_other = other;
+      sym.st_other = 0;
       sym.st_shndx = section_index;
       sym.st_info = (binding << 4) + (type & 0xf);
       CachedSection::Add(&sym, sizeof(sym));
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 50f5aba..2b511fc 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -807,21 +807,27 @@
       }
 
       const CompilerOptions& compiler_options = writer_->compiler_driver_->GetCompilerOptions();
-      if (compiler_options.GenerateAnyDebugInfo()) {
+      // Exclude quickened dex methods (code_size == 0) since they have no native code.
+      if (compiler_options.GenerateAnyDebugInfo() && code_size != 0) {
+        bool has_code_info = method_header->IsOptimized();
         // Record debug information for this function if we are doing that.
-        const uint32_t quick_code_start = quick_code_offset -
-            writer_->oat_header_->GetExecutableOffset() - thumb_offset;
-        writer_->method_info_.push_back(debug::MethodDebugInfo {
-            dex_file_,
-            class_def_index_,
-            it.GetMemberIndex(),
-            it.GetMethodAccessFlags(),
-            it.GetMethodCodeItem(),
-            deduped,
-            compiler_options.GetNativeDebuggable(),
-            quick_code_start,
-            quick_code_start + code_size,
-            compiled_method});
+        debug::MethodDebugInfo info;
+        info.dex_file = dex_file_;
+        info.class_def_index = class_def_index_;
+        info.dex_method_index = it.GetMemberIndex();
+        info.access_flags = it.GetMethodAccessFlags();
+        info.code_item = it.GetMethodCodeItem();
+        info.isa = compiled_method->GetInstructionSet();
+        info.deduped = deduped;
+        info.is_native_debuggable = compiler_options.GetNativeDebuggable();
+        info.is_optimized = method_header->IsOptimized();
+        info.is_code_address_text_relative = true;
+        info.code_address = code_offset - writer_->oat_header_->GetExecutableOffset();
+        info.code_size = code_size;
+        info.frame_size_in_bytes = compiled_method->GetFrameSizeInBytes();
+        info.code_info = has_code_info ? compiled_method->GetVmapTable().data() : nullptr;
+        info.cfi = compiled_method->GetCFIInfo();
+        writer_->method_info_.push_back(info);
       }
 
       if (kIsDebugBuild) {
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 42f22af..47581b1 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -917,35 +917,26 @@
   if (compiler_options.GetGenerateDebugInfo()) {
     const auto* method_header = reinterpret_cast<const OatQuickMethodHeader*>(code);
     const uintptr_t code_address = reinterpret_cast<uintptr_t>(method_header->GetCode());
-    CompiledMethod compiled_method(
-        GetCompilerDriver(),
-        codegen->GetInstructionSet(),
-        ArrayRef<const uint8_t>(code_allocator.GetMemory()),
-        codegen->HasEmptyFrame() ? 0 : codegen->GetFrameSize(),
-        codegen->GetCoreSpillMask(),
-        codegen->GetFpuSpillMask(),
-        ArrayRef<const SrcMapElem>(),
-        ArrayRef<const uint8_t>(),  // mapping_table.
-        ArrayRef<const uint8_t>(stack_map_data, stack_map_size),
-        ArrayRef<const uint8_t>(),  // native_gc_map.
-        ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data()),
-        ArrayRef<const LinkerPatch>());
-    debug::MethodDebugInfo method_debug_info {
-        dex_file,
-        class_def_idx,
-        method_idx,
-        access_flags,
-        code_item,
-        false,  // deduped.
-        compiler_options.GetNativeDebuggable(),
-        code_address,
-        code_address + code_allocator.GetSize(),
-        &compiled_method
-    };
+    debug::MethodDebugInfo info;
+    info.dex_file = dex_file;
+    info.class_def_index = class_def_idx;
+    info.dex_method_index = method_idx;
+    info.access_flags = access_flags;
+    info.code_item = code_item;
+    info.isa = codegen->GetInstructionSet();
+    info.deduped = false;
+    info.is_native_debuggable = compiler_options.GetNativeDebuggable();
+    info.is_optimized = true;
+    info.is_code_address_text_relative = false;
+    info.code_address = code_address;
+    info.code_size = code_allocator.GetSize();
+    info.frame_size_in_bytes = method_header->GetFrameSizeInBytes();
+    info.code_info = stack_map_size == 0 ? nullptr : stack_map_data;
+    info.cfi = ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data());
     ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForMethod(
         GetCompilerDriver()->GetInstructionSet(),
         GetCompilerDriver()->GetInstructionSetFeatures(),
-        method_debug_info);
+        info);
     CreateJITCodeEntryForAddress(code_address,
                                  std::unique_ptr<const uint8_t[]>(elf_file.data()),
                                  elf_file.size());
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 6c6c807..285803c 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -177,8 +177,13 @@
       uint64_t symbol_value = code_offset - oat_file_->GetOatHeader().GetExecutableOffset();
       // Specifying 0 as the symbol size means that the symbol lasts until the next symbol or until
       // the end of the section in case of the last symbol.
-      builder_->GetSymTab()->Add(name_offset, builder_->GetText(), symbol_value,
-          /* is_relative */ true, /* size */ 0, STB_GLOBAL, STT_FUNC);
+      builder_->GetSymTab()->Add(
+          name_offset,
+          builder_->GetText(),
+          builder_->GetText()->GetAddress() + symbol_value,
+          /* size */ 0,
+          STB_GLOBAL,
+          STT_FUNC);
     }
   }
 
@@ -330,9 +335,15 @@
       }
 
       int name_offset = builder_->GetStrTab()->Write(pretty_name);
-      builder_->GetSymTab()->Add(name_offset, builder_->GetText(),
-          oat_method.GetCodeOffset() - oat_file_->GetOatHeader().GetExecutableOffset(),
-          true, oat_method.GetQuickCodeSize(), STB_GLOBAL, STT_FUNC);
+      uint64_t address = oat_method.GetCodeOffset() -
+                         oat_file_->GetOatHeader().GetExecutableOffset() +
+                         builder_->GetText()->GetAddress();
+      builder_->GetSymTab()->Add(name_offset,
+                                 builder_->GetText(),
+                                 address,
+                                 oat_method.GetQuickCodeSize(),
+                                 STB_GLOBAL,
+                                 STT_FUNC);
     }
   }