Fix DWARF line-number generation for JITed methods.

Don't strip, repack or compress debug-info if explicitly
requested by the developer (using the -g compiler flag).

If enabled, the DWARF debug info has about 1:1 size
overhead relative to JIT code + data.

Bug: 131422204
Test: Check that gdb shows line numbers for JITed method.
Test: Hard-code always-enable generation and run maps.
Change-Id: If06de8ae2317af4d57d84e8a8bfae86a597dd4e4
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index 1957c82..b42e9f2 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -150,7 +150,7 @@
     AddNativeDebugInfoForJit(Thread::Current(),
                              /*code_ptr=*/ nullptr,
                              elf_file,
-                             debug::PackElfFileForJIT,
+                             /*pack*/ nullptr,
                              compiler_options.GetInstructionSet(),
                              compiler_options.GetInstructionSetFeatures());
   }
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index f4bf11d..c799b12 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -1482,7 +1482,7 @@
     AddNativeDebugInfoForJit(Thread::Current(),
                              reinterpret_cast<const void*>(info.code_address),
                              elf_file,
-                             debug::PackElfFileForJIT,
+                             mini_debug_info ? debug::PackElfFileForJIT : nullptr,
                              compiler_options.GetInstructionSet(),
                              compiler_options.GetInstructionSetFeatures());
   }
diff --git a/runtime/jit/debugger_interface.cc b/runtime/jit/debugger_interface.cc
index f522be8..2a5485c 100644
--- a/runtime/jit/debugger_interface.cc
+++ b/runtime/jit/debugger_interface.cc
@@ -299,6 +299,7 @@
   // The number of methods per entry is variable (depending on how many fit in that range).
   constexpr uint32_t kGroupSize = 64 * KB;
 
+  CHECK(pack != nullptr);
   JITCodeEntries packed_entries;
   std::vector<ArrayRef<const uint8_t>> added;
   std::vector<const void*> removed;
@@ -367,7 +368,21 @@
   // Must be done before addition in case the added code_ptr is in the removed set.
   if (!g_jit_removed_entries.empty()) {
     g_compressed_jit_debug_entries.merge(g_uncompressed_jit_debug_entries);
-    RepackEntries(pack, isa, features, /*compress=*/ true, &g_compressed_jit_debug_entries);
+    if (pack != nullptr) {
+      RepackEntries(pack, isa, features, /*compress=*/ true, &g_compressed_jit_debug_entries);
+    } else {
+      // If repacking function is not provided, just remove the individual entries.
+      for (const void* removed_code_ptr : g_jit_removed_entries) {
+        auto it = g_compressed_jit_debug_entries.find(removed_code_ptr);
+        if (it != g_compressed_jit_debug_entries.end()) {
+          DeleteJITCodeEntryInternal(__jit_debug_descriptor,
+                                     __jit_debug_register_code_ptr,
+                                     /*entry=*/ it->second,
+                                     /*free_symfile=*/ true);
+          g_compressed_jit_debug_entries.erase(it);
+        }
+      }
+    }
     g_jit_removed_entries.clear();
     g_jit_num_unpacked_entries = 0;
   }
@@ -397,7 +412,7 @@
 
   // Pack (but don't compress) recent entries - this is cheap and reduces memory use by ~4x.
   // We delay compression until after GC since it is more expensive (and saves further ~4x).
-  if (g_jit_num_unpacked_entries >= kJitMaxUnpackedEntries) {
+  if (g_jit_num_unpacked_entries >= kJitMaxUnpackedEntries && pack != nullptr) {
     RepackEntries(pack, isa, features, /*compress=*/ false, &g_uncompressed_jit_debug_entries);
     g_jit_num_unpacked_entries = 0;
   }
diff --git a/runtime/jit/debugger_interface.h b/runtime/jit/debugger_interface.h
index 19507b0..f84f08d 100644
--- a/runtime/jit/debugger_interface.h
+++ b/runtime/jit/debugger_interface.h
@@ -48,6 +48,8 @@
 
 // Notify native tools (e.g. libunwind) that JIT has compiled a new method.
 // The method will make copy of the passed ELF file (to shrink it to the minimum size).
+// If packing function is provided, ELF files can be merged to save space
+// (however, the merging drops advanced gdb debug-info as it is too complex).
 void AddNativeDebugInfoForJit(Thread* self,
                               const void* code_ptr,
                               const std::vector<uint8_t>& symfile,