Use malloc for mutable addrmaps
authorTom Tromey <tom@tromey.com>
Sat, 16 Apr 2022 16:12:49 +0000 (10:12 -0600)
committerTom Tromey <tom@tromey.com>
Sun, 12 Jun 2022 16:49:48 +0000 (10:49 -0600)
Mutable addrmaps currently require an obstack.  This was probably done
to avoid having to call splay_tree_delete, but examination of the code
shows that all mutable obstacks have a limited lifetime -- now it's
simple to treat them as ordinary C++ objects, in some cases
stack-allocating them, and have a destructor to make the needed call.
This patch implements this change.

gdb/addrmap.c
gdb/addrmap.h
gdb/buildsym.c
gdb/buildsym.h
gdb/dwarf2/read.c

index 51a6c676ec63d3ce2af26757c2afb87c47a7cef9..06f3a831df9ee498955da348f1882e6615c6bb4c 100644 (file)
@@ -102,11 +102,11 @@ addrmap_fixed::foreach (addrmap_foreach_fn fn)
 \f
 /* Mutable address maps.  */
 
-/* Allocate a copy of CORE_ADDR in the obstack.  */
+/* Allocate a copy of CORE_ADDR.  */
 splay_tree_key
 addrmap_mutable::allocate_key (CORE_ADDR addr)
 {
-  CORE_ADDR *key = XOBNEW (obstack, CORE_ADDR);
+  CORE_ADDR *key = XNEW (CORE_ADDR);
 
   *key = addr;
   return (splay_tree_key) key;
@@ -325,42 +325,6 @@ addrmap_mutable::foreach (addrmap_foreach_fn fn)
 }
 
 
-void *
-addrmap_mutable::splay_obstack_alloc (int size, void *closure)
-{
-  struct addrmap_mutable *map = (struct addrmap_mutable *) closure;
-  splay_tree_node n;
-
-  /* We should only be asked to allocate nodes and larger things.
-     (If, at some point in the future, this is no longer true, we can
-     just round up the size to sizeof (*n).)  */
-  gdb_assert (size >= sizeof (*n));
-
-  if (map->free_nodes)
-    {
-      n = map->free_nodes;
-      map->free_nodes = n->right;
-      return n;
-    }
-  else
-    return obstack_alloc (map->obstack, size);
-}
-
-
-void
-addrmap_mutable::splay_obstack_free (void *obj, void *closure)
-{
-  struct addrmap_mutable *map = (struct addrmap_mutable *) closure;
-  splay_tree_node n = (splay_tree_node) obj;
-
-  /* We've asserted in the allocation function that we only allocate
-     nodes or larger things, so it should be safe to put whatever
-     we get passed back on the free list.  */
-  n->right = map->free_nodes;
-  map->free_nodes = n;
-}
-
-
 /* Compare keys as CORE_ADDR * values.  */
 static int
 splay_compare_CORE_ADDR_ptr (splay_tree_key ak, splay_tree_key bk)
@@ -378,15 +342,21 @@ splay_compare_CORE_ADDR_ptr (splay_tree_key ak, splay_tree_key bk)
 }
 
 
-addrmap_mutable::addrmap_mutable (struct obstack *obs)
-  : obstack (obs),
-    tree (splay_tree_new_with_allocator (splay_compare_CORE_ADDR_ptr,
-                                        NULL, /* no delete key */
-                                        NULL, /* no delete value */
-                                        splay_obstack_alloc,
-                                        splay_obstack_free,
-                                        this))
+static void
+xfree_wrapper (splay_tree_key key)
+{
+  xfree ((void *) key);
+}
+
+addrmap_mutable::addrmap_mutable ()
+  : tree (splay_tree_new (splay_compare_CORE_ADDR_ptr, xfree_wrapper,
+                         nullptr /* no delete value */))
+{
+}
+
+addrmap_mutable::~addrmap_mutable ()
 {
+  splay_tree_delete (tree);
 }
 
 
@@ -461,8 +431,7 @@ test_addrmap ()
   /* Create mutable addrmap.  */
   struct obstack temp_obstack;
   obstack_init (&temp_obstack);
-  struct addrmap_mutable *map
-    = new (&temp_obstack) addrmap_mutable (&temp_obstack);
+  struct addrmap_mutable *map = new (&temp_obstack) addrmap_mutable;
   SELF_CHECK (map != nullptr);
 
   /* Check initial state.  */
index a3b1d6ad4a8bd6721e01d9deba6e0a200d79bdec..bdf1199481f992b7da672e1741544c80ddbeab32 100644 (file)
@@ -32,7 +32,7 @@
    Address maps come in two flavors: fixed, and mutable.  Mutable
    address maps consume more memory, but can be changed and extended.
    A fixed address map, once constructed (from a mutable address map),
-   can't be edited.  Both kinds of map are allocated in obstacks.  */
+   can't be edited.  */
 
 /* The type of a function used to iterate over the map.
    OBJ is NULL for unmapped regions.  */
@@ -40,7 +40,7 @@ typedef gdb::function_view<int (CORE_ADDR start_addr, void *obj)>
      addrmap_foreach_fn;
 
 /* The base class for addrmaps.  */
-struct addrmap : public allocate_on_obstack
+struct addrmap
 {
   virtual ~addrmap () = default;
 
@@ -101,7 +101,8 @@ struct addrmap : public allocate_on_obstack
 struct addrmap_mutable;
 
 /* Fixed address maps.  */
-struct addrmap_fixed : public addrmap
+struct addrmap_fixed : public addrmap,
+                      public allocate_on_obstack
 {
 public:
 
@@ -142,7 +143,8 @@ struct addrmap_mutable : public addrmap
 {
 public:
 
-  explicit addrmap_mutable (struct obstack *obs);
+  addrmap_mutable ();
+  ~addrmap_mutable ();
   DISABLE_COPY_AND_ASSIGN (addrmap_mutable);
 
   void set_empty (CORE_ADDR start, CORE_ADDR end_inclusive,
@@ -153,16 +155,6 @@ public:
 
 private:
 
-  /* The obstack to use for allocations for this map.  */
-  struct obstack *obstack;
-
-  /* A freelist for splay tree nodes, allocated on obstack, and
-     chained together by their 'right' pointers.  */
-  /* splay_tree_new_with_allocator uses the provided allocation
-     function to allocate the main splay_tree structure itself, so our
-     free list has to be initialized before we create the tree.  */
-  splay_tree_node free_nodes = nullptr;
-
   /* A splay tree, with a node for each transition; there is a
      transition at address T if T-1 and T map to different objects.
 
@@ -190,9 +182,6 @@ private:
   splay_tree_node splay_tree_successor (CORE_ADDR addr);
   void splay_tree_remove (CORE_ADDR addr);
   void splay_tree_insert (CORE_ADDR key, void *value);
-
-  static void *splay_obstack_alloc (int size, void *closure);
-  static void splay_obstack_free (void *obj, void *closure);
 };
 
 
index 019c2055f601f8cefd11f3c9fd20b9555abe04ac..65c2ac5aff08c893ab8ed0cbf73a34c4e8db1fef 100644 (file)
@@ -33,7 +33,6 @@
 #include "block.h"
 #include "cp-support.h"
 #include "dictionary.h"
-#include "addrmap.h"
 #include <algorithm>
 
 /* For cleanup_undefined_stabs_types and finish_global_stabs (somewhat
@@ -418,12 +417,7 @@ buildsym_compunit::record_block_range (struct block *block,
       || end_inclusive + 1 != block->end ())
     m_pending_addrmap_interesting = true;
 
-  if (m_pending_addrmap == nullptr)
-    m_pending_addrmap
-      = (new (&m_pending_addrmap_obstack) addrmap_mutable
-        (&m_pending_addrmap_obstack));
-
-  m_pending_addrmap->set_empty (start, end_inclusive, block);
+  m_pending_addrmap.set_empty (start, end_inclusive, block);
 }
 
 struct blockvector *
@@ -458,10 +452,10 @@ buildsym_compunit::make_blockvector ()
 
   /* If we needed an address map for this symtab, record it in the
      blockvector.  */
-  if (m_pending_addrmap != nullptr && m_pending_addrmap_interesting)
+  if (m_pending_addrmap_interesting)
     blockvector->set_map
       (new (&m_objfile->objfile_obstack) addrmap_fixed
-       (&m_objfile->objfile_obstack, m_pending_addrmap));
+       (&m_objfile->objfile_obstack, &m_pending_addrmap));
   else
     blockvector->set_map (nullptr);
 
index c1cd5192a79e66e0c4dec7f45baa2c975a547265..2ad0033626973bbe06d037527f06d02b8e6b23b5 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "gdbsupport/gdb_obstack.h"
 #include "symtab.h"
+#include "addrmap.h"
 
 struct objfile;
 struct symbol;
@@ -385,12 +386,7 @@ private:
   /* The mutable address map for the compilation unit whose symbols
      we're currently reading.  The symtabs' shared blockvector will
      point to a fixed copy of this.  */
-  struct addrmap_mutable *m_pending_addrmap = nullptr;
-
-  /* The obstack on which we allocate pending_addrmap.
-     If pending_addrmap is NULL, this is uninitialized; otherwise, it is
-     initialized (and holds pending_addrmap).  */
-  auto_obstack m_pending_addrmap_obstack;
+  struct addrmap_mutable m_pending_addrmap;
 
   /* True if we recorded any ranges in the addrmap that are different
      from those in the blockvector already.  We set this to false when
index 96378c3a09fef21a205c40528d65d1df5e77cfdf..d3e6db4c10919073fe363859c432a231b0c462b2 100644 (file)
@@ -2267,12 +2267,9 @@ create_addrmap_from_index (dwarf2_per_objfile *per_objfile,
   dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
   struct gdbarch *gdbarch = objfile->arch ();
   const gdb_byte *iter, *end;
-  struct addrmap_mutable *mutable_map;
   CORE_ADDR baseaddr;
 
-  auto_obstack temp_obstack;
-
-  mutable_map = new (&temp_obstack) addrmap_mutable (&temp_obstack);
+  addrmap_mutable mutable_map;
 
   iter = index->address_table.data ();
   end = iter + index->address_table.size ();
@@ -2305,11 +2302,11 @@ create_addrmap_from_index (dwarf2_per_objfile *per_objfile,
 
       lo = gdbarch_adjust_dwarf2_addr (gdbarch, lo + baseaddr) - baseaddr;
       hi = gdbarch_adjust_dwarf2_addr (gdbarch, hi + baseaddr) - baseaddr;
-      mutable_map->set_empty (lo, hi - 1, per_bfd->get_cu (cu_index));
+      mutable_map.set_empty (lo, hi - 1, per_bfd->get_cu (cu_index));
     }
 
   per_bfd->index_addrmap
-    = new (&per_bfd->obstack) addrmap_fixed (&per_bfd->obstack, mutable_map);
+    = new (&per_bfd->obstack) addrmap_fixed (&per_bfd->obstack, &mutable_map);
 }
 
 /* Read the address map data from DWARF-5 .debug_aranges, and use it
@@ -2496,14 +2493,12 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
 {
   dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
 
-  auto_obstack temp_obstack;
-  addrmap_mutable *mutable_map
-    = new (&temp_obstack) addrmap_mutable (&temp_obstack);
+  addrmap_mutable mutable_map;
 
-  if (read_addrmap_from_aranges (per_objfile, section, mutable_map))
+  if (read_addrmap_from_aranges (per_objfile, section, &mutable_map))
     per_bfd->index_addrmap
       = new (&per_bfd->obstack) addrmap_fixed (&per_bfd->obstack,
-                                              mutable_map);
+                                              &mutable_map);
 }
 
 /* A helper function that reads the .gdb_index from BUFFER and fills
@@ -6554,9 +6549,7 @@ public:
                                        eq_cutu_reader,
                                        htab_delete_entry<cutu_reader>,
                                        xcalloc, xfree)),
-      m_index (new cooked_index),
-      m_addrmap_storage (),
-      m_addrmap (new (&m_addrmap_storage) addrmap_mutable (&m_addrmap_storage))
+      m_index (new cooked_index)
   {
   }
 
@@ -6606,14 +6599,14 @@ public:
      then transfer ownership of the index to the caller.  */
   std::unique_ptr<cooked_index> release ()
   {
-    m_index->install_addrmap (m_addrmap);
+    m_index->install_addrmap (&m_addrmap);
     return std::move (m_index);
   }
 
   /* Return the mutable addrmap that is currently being created.  */
   addrmap_mutable *get_addrmap ()
   {
-    return m_addrmap;
+    return &m_addrmap;
   }
 
 private:
@@ -6640,10 +6633,8 @@ private:
   /* The index that is being constructed.  */
   std::unique_ptr<cooked_index> m_index;
 
-  /* Storage for the writeable addrmap.  */
-  auto_obstack m_addrmap_storage;
   /* A writeable addrmap being constructed by this scanner.  */
-  addrmap_mutable *m_addrmap;
+  addrmap_mutable m_addrmap;
 };
 
 /* An instance of this is created to index a CU.  */
@@ -6657,9 +6648,7 @@ public:
                  enum language language)
     : m_index_storage (storage),
       m_per_cu (per_cu),
-      m_language (language),
-      m_obstack (),
-      m_die_range_map (new (&m_obstack) addrmap_mutable (&m_obstack))
+      m_language (language)
   {
   }
 
@@ -6744,12 +6733,10 @@ private:
   /* The language that we're assuming when reading.  */
   enum language m_language;
 
-  /* Temporary storage.  */
-  auto_obstack m_obstack;
   /* An addrmap that maps from section offsets (see the form_addr
      method) to newly-created entries.  See m_deferred_entries to
      understand this.  */
-  addrmap *m_die_range_map;
+  addrmap_mutable m_die_range_map;
 
   /* A single deferred entry.  */
   struct deferred_entry
@@ -18146,7 +18133,7 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
            {
              CORE_ADDR lookup = form_addr (origin_offset, origin_is_dwz);
              *parent_entry
-               = (cooked_index_entry *) m_die_range_map->find (lookup);
+               = (cooked_index_entry *) m_die_range_map.find (lookup);
            }
 
          unsigned int bytes_read;
@@ -18263,7 +18250,7 @@ cooked_indexer::recurse (cutu_reader *reader,
                                   reader->cu->per_cu->is_dwz);
       CORE_ADDR end = form_addr (sect_offset (info_ptr - 1 - reader->buffer),
                                 reader->cu->per_cu->is_dwz);
-      m_die_range_map->set_empty (start, end, (void *) parent_entry);
+      m_die_range_map.set_empty (start, end, (void *) parent_entry);
     }
 
   return info_ptr;
@@ -18436,7 +18423,7 @@ cooked_indexer::make_index (cutu_reader *reader)
     {
       CORE_ADDR key = form_addr (entry.die_offset, m_per_cu->is_dwz);
       cooked_index_entry *parent
-       = (cooked_index_entry *) m_die_range_map->find (key);
+       = (cooked_index_entry *) m_die_range_map.find (key);
       m_index_storage->add (entry.die_offset, entry.tag, entry.flags,
                            entry.name, parent, m_per_cu);
     }