Patchwork [RFA,3/6] Allocate dwarf2_cu with new

login
register
mail settings
Submitter Tom Tromey
Date Jan. 10, 2018, 4:28 p.m.
Message ID <87r2qxispc.fsf@tromey.com>
Download mbox | patch
Permalink /patch/25328/
State New
Headers show

Comments

Tom Tromey - Jan. 10, 2018, 4:28 p.m.
>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:

Tom> This is gone with Simon's changes; I'll update the ChangeLog and send
Tom> the updated patch.

Here it is.  This went through the buildbot the second time around.

Tom

commit bcaf61d8ff6a149785924223151df8ded30e8d7a
Author: Simon Marchi <simon.marchi@ericsson.com>
Date:   Sun Jan 7 11:41:09 2018 -0500

    Allocate dwarf2_cu with new
    
    This changes dwarf2_cu to be allocated with new, and fixes up the
    users.
    
    2018-01-05  Tom Tromey  <tom@tromey.com>
                Simon Marchi  <simon.marchi@ericsson.com>
    
            * dwarf2read.c (struct dwarf2_cu): Add constructor, destructor.
            (dwarf2_per_objfile::free_cached_comp_units)
            (init_tu_and_read_dwo_dies, init_cutu_and_read_dies)
            (init_cutu_and_read_dies_no_follow): Update.
            (dwarf2_cu::dwarf2_cu): Rename from init_one_comp_unit.
            (dwarf2_cu::~dwarf2_cu): New.
            (free_heap_comp_unit, free_stack_comp_unit): Remove.
            (age_cached_comp_units, free_one_cached_comp_unit): Update.
Simon Marchi - Jan. 16, 2018, 3:03 p.m.
On 2018-01-10 11:28 AM, Tom Tromey wrote:
>>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:
> 
> Tom> This is gone with Simon's changes; I'll update the ChangeLog and send
> Tom> the updated patch.
> 
> Here it is.  This went through the buildbot the second time around.
> 
> Tom
> 
> commit bcaf61d8ff6a149785924223151df8ded30e8d7a
> Author: Simon Marchi <simon.marchi@ericsson.com>
> Date:   Sun Jan 7 11:41:09 2018 -0500
> 
>     Allocate dwarf2_cu with new
>     
>     This changes dwarf2_cu to be allocated with new, and fixes up the
>     users.
>     
>     2018-01-05  Tom Tromey  <tom@tromey.com>
>                 Simon Marchi  <simon.marchi@ericsson.com>
>     
>             * dwarf2read.c (struct dwarf2_cu): Add constructor, destructor.
>             (dwarf2_per_objfile::free_cached_comp_units)
>             (init_tu_and_read_dwo_dies, init_cutu_and_read_dies)
>             (init_cutu_and_read_dies_no_follow): Update.
>             (dwarf2_cu::dwarf2_cu): Rename from init_one_comp_unit.
>             (dwarf2_cu::~dwarf2_cu): New.
>             (free_heap_comp_unit, free_stack_comp_unit): Remove.
>             (age_cached_comp_units, free_one_cached_comp_unit): Update.

Hi Tom,

This LGTM, I just noted two formatting nits.

> @@ -7932,7 +7904,6 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
>    if (info_ptr >= begin_info_ptr + this_cu->length
>        || peek_abbrev_code (abfd, info_ptr) == 0)
>      {
> -      do_cleanups (cleanups);
>        return;
>      }

You can remove the curly braces here.

> @@ -8090,7 +8047,6 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
>    if (info_ptr >= begin_info_ptr + this_cu->length
>        || peek_abbrev_code (abfd, info_ptr) == 0)
>      {
> -      do_cleanups (cleanups);
>        return;
>      }

Here too.

Simon
Tom Tromey - Jan. 17, 2018, 5:10 p.m.
>>>>> "Simon" == Simon Marchi <simon.marchi@ericsson.com> writes:

Simon> You can remove the curly braces here.
[...]
Simon> Here too.

I've made these changes locally.

Tom

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e129879148..8947f01024 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,6 +1,18 @@ 
 2018-01-05  Tom Tromey  <tom@tromey.com>
 	    Simon Marchi  <simon.marchi@ericsson.com>
 
+	* dwarf2read.c (struct dwarf2_cu): Add constructor, destructor.
+	(dwarf2_per_objfile::free_cached_comp_units)
+	(init_tu_and_read_dwo_dies, init_cutu_and_read_dies)
+	(init_cutu_and_read_dies_no_follow): Update.
+	(dwarf2_cu::dwarf2_cu): Rename from init_one_comp_unit.
+	(dwarf2_cu::~dwarf2_cu): New.
+	(free_heap_comp_unit, free_stack_comp_unit): Remove.
+	(age_cached_comp_units, free_one_cached_comp_unit): Update.
+
+2018-01-05  Tom Tromey  <tom@tromey.com>
+	    Simon Marchi  <simon.marchi@ericsson.com>
+
 	* dwarf2read.c (struct dwarf2_cu) <abbrev_table>: Remove.
 	(struct die_reader_specs) <abbrev_table>: New member.
 	(struct abbrev_table): Add constructor.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 292bba2aed..aa84691516 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -661,20 +661,25 @@  DEF_VEC_O (delayed_method_info);
 /* Internal state when decoding a particular compilation unit.  */
 struct dwarf2_cu
 {
+  explicit dwarf2_cu (struct dwarf2_per_cu_data *per_cu);
+  ~dwarf2_cu ();
+
+  DISABLE_COPY_AND_ASSIGN (dwarf2_cu);
+
   /* The header of the compilation unit.  */
-  struct comp_unit_head header;
+  struct comp_unit_head header {};
 
   /* Base address of this compilation unit.  */
-  CORE_ADDR base_address;
+  CORE_ADDR base_address = 0;
 
   /* Non-zero if base_address has been set.  */
-  int base_known;
+  int base_known = 0;
 
   /* The language we are debugging.  */
-  enum language language;
-  const struct language_defn *language_defn;
+  enum language language = language_unknown;
+  const struct language_defn *language_defn = nullptr;
 
-  const char *producer;
+  const char *producer = nullptr;
 
   /* The generic symbol table building routines have separate lists for
      file scope symbols and all all other scopes (local scopes).  So
@@ -685,55 +690,55 @@  struct dwarf2_cu
      first local scope, and all other local scopes as nested local
      scopes, and worked fine.  Check to see if we really need to
      distinguish these in buildsym.c.  */
-  struct pending **list_in_scope;
+  struct pending **list_in_scope = nullptr;
 
   /* Hash table holding all the loaded partial DIEs
      with partial_die->offset.SECT_OFF as hash.  */
-  htab_t partial_dies;
+  htab_t partial_dies = nullptr;
 
   /* Storage for things with the same lifetime as this read-in compilation
      unit, including partial DIEs.  */
-  struct obstack comp_unit_obstack;
+  auto_obstack comp_unit_obstack;
 
   /* When multiple dwarf2_cu structures are living in memory, this field
      chains them all together, so that they can be released efficiently.
      We will probably also want a generation counter so that most-recently-used
      compilation units are cached...  */
-  struct dwarf2_per_cu_data *read_in_chain;
+  struct dwarf2_per_cu_data *read_in_chain = nullptr;
 
   /* Backlink to our per_cu entry.  */
   struct dwarf2_per_cu_data *per_cu;
 
   /* How many compilation units ago was this CU last referenced?  */
-  int last_used;
+  int last_used = 0;
 
   /* A hash table of DIE cu_offset for following references with
      die_info->offset.sect_off as hash.  */
-  htab_t die_hash;
+  htab_t die_hash = nullptr;
 
   /* Full DIEs if read in.  */
-  struct die_info *dies;
+  struct die_info *dies = nullptr;
 
   /* A set of pointers to dwarf2_per_cu_data objects for compilation
      units referenced by this one.  Only set during full symbol processing;
      partial symbol tables do not have dependencies.  */
-  htab_t dependencies;
+  htab_t dependencies = nullptr;
 
   /* Header data from the line table, during full symbol processing.  */
-  struct line_header *line_header;
+  struct line_header *line_header = nullptr;
   /* Non-NULL if LINE_HEADER is owned by this DWARF_CU.  Otherwise,
      it's owned by dwarf2_per_objfile::line_header_hash.  If non-NULL,
      this is the DW_TAG_compile_unit die for this CU.  We'll hold on
      to the line header as long as this DIE is being processed.  See
      process_die_scope.  */
-  die_info *line_header_die_owner;
+  die_info *line_header_die_owner = nullptr;
 
   /* A list of methods which need to have physnames computed
      after all type information has been read.  */
-  VEC (delayed_method_info) *method_list;
+  VEC (delayed_method_info) *method_list = nullptr;
 
   /* To be copied to symtab->call_site_htab.  */
-  htab_t call_site_htab;
+  htab_t call_site_htab = nullptr;
 
   /* Non-NULL if this CU came from a DWO file.
      There is an invariant here that is important to remember:
@@ -744,12 +749,12 @@  struct dwarf2_cu
      is moot), or there is and either we're not going to read it (in which
      case this is NULL) or there is and we are reading it (in which case this
      is non-NULL).  */
-  struct dwo_unit *dwo_unit;
+  struct dwo_unit *dwo_unit = nullptr;
 
   /* The DW_AT_addr_base attribute if present, zero otherwise
      (zero is a valid value though).
      Note this value comes from the Fission stub CU/TU's DIE.  */
-  ULONGEST addr_base;
+  ULONGEST addr_base = 0;
 
   /* The DW_AT_ranges_base attribute if present, zero otherwise
      (zero is a valid value though).
@@ -761,7 +766,7 @@  struct dwarf2_cu
      DW_AT_ranges appeared in the DW_TAG_compile_unit of DWO DIEs: then
      DW_AT_ranges_base *would* have to be applied, and we'd have to care
      whether the DW_AT_ranges attribute came from the skeleton or DWO.  */
-  ULONGEST ranges_base;
+  ULONGEST ranges_base = 0;
 
   /* Mark used when releasing cached dies.  */
   unsigned int mark : 1;
@@ -2138,8 +2143,6 @@  static const gdb_byte *skip_one_die (const struct die_reader_specs *reader,
 				     const gdb_byte *info_ptr,
 				     struct abbrev_info *abbrev);
 
-static void free_stack_comp_unit (void *);
-
 static hashval_t partial_die_hash (const void *item);
 
 static int partial_die_eq (const void *item_lhs, const void *item_rhs);
@@ -2148,15 +2151,10 @@  static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
   (sect_offset sect_off, unsigned int offset_in_dwz,
    struct dwarf2_per_objfile *dwarf2_per_objfile);
 
-static void init_one_comp_unit (struct dwarf2_cu *cu,
-				struct dwarf2_per_cu_data *per_cu);
-
 static void prepare_one_comp_unit (struct dwarf2_cu *cu,
 				   struct die_info *comp_unit_die,
 				   enum language pretend_language);
 
-static void free_heap_comp_unit (void *);
-
 static void free_cached_comp_units (void *);
 
 static void age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile);
@@ -2449,7 +2447,7 @@  dwarf2_per_objfile::free_cached_comp_units ()
     {
       dwarf2_per_cu_data *next_cu = per_cu->cu->read_in_chain;
 
-      free_heap_comp_unit (per_cu->cu);
+      delete per_cu->cu;
       *last_chain = next_cu;
       per_cu = next_cu;
     }
@@ -7696,12 +7694,7 @@  lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
 
 /* Subroutine of init_cutu_and_read_dies to simplify it.
    See it for a description of the parameters.
-   Read a TU directly from a DWO file, bypassing the stub.
-
-   Note: This function could be a little bit simpler if we shared cleanups
-   with our caller, init_cutu_and_read_dies.  That's generally a fragile thing
-   to do, so we keep this function self-contained.  Or we could move this
-   into our caller, but it's complex enough already.  */
+   Read a TU directly from a DWO file, bypassing the stub.  */
 
 static void
 init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
@@ -7709,9 +7702,8 @@  init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
 			   die_reader_func_ftype *die_reader_func,
 			   void *data)
 {
-  struct dwarf2_cu *cu;
+  std::unique_ptr<dwarf2_cu> new_cu;
   struct signatured_type *sig_type;
-  struct cleanup *cleanups, *free_cu_cleanup = NULL;
   struct die_reader_specs reader;
   const gdb_byte *info_ptr;
   struct die_info *comp_unit_die;
@@ -7724,12 +7716,9 @@  init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
   sig_type = (struct signatured_type *) this_cu;
   gdb_assert (sig_type->dwo_unit != NULL);
 
-  cleanups = make_cleanup (null_cleanup, NULL);
-
   if (use_existing_cu && this_cu->cu != NULL)
     {
       gdb_assert (this_cu->cu->dwo_unit == sig_type->dwo_unit);
-      cu = this_cu->cu;
       /* There's no need to do the rereading_dwo_cu handling that
 	 init_cutu_and_read_dies does since we don't read the stub.  */
     }
@@ -7737,10 +7726,7 @@  init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
     {
       /* If !use_existing_cu, this_cu->cu must be NULL.  */
       gdb_assert (this_cu->cu == NULL);
-      cu = XNEW (struct dwarf2_cu);
-      init_one_comp_unit (cu, this_cu);
-      /* If an error occurs while loading, release our storage.  */
-      free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu);
+      new_cu.reset (new dwarf2_cu (this_cu));
     }
 
   /* A future optimization, if needed, would be to use an existing
@@ -7759,7 +7745,6 @@  init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
 			      &dwo_abbrev_table) == 0)
     {
       /* Dummy die.  */
-      do_cleanups (cleanups);
       return;
     }
 
@@ -7770,23 +7755,14 @@  init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
      but the alternative is making the latter more complex.
      This function is only for the special case of using DWO files directly:
      no point in overly complicating the general case just to handle this.  */
-  if (free_cu_cleanup != NULL)
+  if (new_cu != NULL && keep)
     {
-      if (keep)
-	{
-	  /* We've successfully allocated this compilation unit.  Let our
-	     caller clean it up when finished with it.  */
-	  discard_cleanups (free_cu_cleanup);
-
-	  /* Link this CU into read_in_chain.  */
-	  this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
-	  dwarf2_per_objfile->read_in_chain = this_cu;
-	}
-      else
-	do_cleanups (free_cu_cleanup);
+      /* Link this CU into read_in_chain.  */
+      this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+      dwarf2_per_objfile->read_in_chain = this_cu;
+      /* The chain owns it now.  */
+      new_cu.release ();
     }
-
-  do_cleanups (cleanups);
 }
 
 /* Initialize a CU (or TU) and read its DIEs.
@@ -7822,7 +7798,6 @@  init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
   struct die_info *comp_unit_die;
   int has_children;
   struct attribute *attr;
-  struct cleanup *cleanups, *free_cu_cleanup = NULL;
   struct signatured_type *sig_type = NULL;
   struct dwarf2_section_info *abbrev_section;
   /* Non-zero if CU currently points to a DWO file and we need to
@@ -7850,8 +7825,6 @@  init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
       return;
     }
 
-  cleanups = make_cleanup (null_cleanup, NULL);
-
   /* This is cheap if the section is already read in.  */
   dwarf2_read_section (objfile, section);
 
@@ -7859,6 +7832,7 @@  init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
 
   abbrev_section = get_abbrev_section_for_cu (this_cu);
 
+  std::unique_ptr<dwarf2_cu> new_cu;
   if (use_existing_cu && this_cu->cu != NULL)
     {
       cu = this_cu->cu;
@@ -7875,10 +7849,8 @@  init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
     {
       /* If !use_existing_cu, this_cu->cu must be NULL.  */
       gdb_assert (this_cu->cu == NULL);
-      cu = XNEW (struct dwarf2_cu);
-      init_one_comp_unit (cu, this_cu);
-      /* If an error occurs while loading, release our storage.  */
-      free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu);
+      new_cu.reset (new dwarf2_cu (this_cu));
+      cu = new_cu.get ();
     }
 
   /* Get the header.  */
@@ -7932,7 +7904,6 @@  init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
   if (info_ptr >= begin_info_ptr + this_cu->length
       || peek_abbrev_code (abfd, info_ptr) == 0)
     {
-      do_cleanups (cleanups);
       return;
     }
 
@@ -7986,7 +7957,6 @@  init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
 				      &dwo_abbrev_table) == 0)
 	    {
 	      /* Dummy die.  */
-	      do_cleanups (cleanups);
 	      return;
 	    }
 	  comp_unit_die = dwo_comp_unit_die;
@@ -8005,23 +7975,14 @@  init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
   die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
 
   /* Done, clean up.  */
-  if (free_cu_cleanup != NULL)
+  if (new_cu != NULL && keep)
     {
-      if (keep)
-	{
-	  /* We've successfully allocated this compilation unit.  Let our
-	     caller clean it up when finished with it.  */
-	  discard_cleanups (free_cu_cleanup);
-
-	  /* Link this CU into read_in_chain.  */
-	  this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
-	  dwarf2_per_objfile->read_in_chain = this_cu;
-	}
-      else
-	do_cleanups (free_cu_cleanup);
+      /* Link this CU into read_in_chain.  */
+      this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+      dwarf2_per_objfile->read_in_chain = this_cu;
+      /* The chain owns it now.  */
+      new_cu.release ();
     }
-
-  do_cleanups (cleanups);
 }
 
 /* Read CU/TU THIS_CU but do not follow DW_AT_GNU_dwo_name if present.
@@ -8051,10 +8012,8 @@  init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
   struct dwarf2_section_info *section = this_cu->section;
   bfd *abfd = get_section_bfd_owner (section);
   struct dwarf2_section_info *abbrev_section;
-  struct dwarf2_cu cu;
   const gdb_byte *begin_info_ptr, *info_ptr;
   struct die_reader_specs reader;
-  struct cleanup *cleanups;
   struct die_info *comp_unit_die;
   int has_children;
 
@@ -8072,9 +8031,7 @@  init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
   /* This is cheap if the section is already read in.  */
   dwarf2_read_section (objfile, section);
 
-  init_one_comp_unit (&cu, this_cu);
-
-  cleanups = make_cleanup (free_stack_comp_unit, &cu);
+  struct dwarf2_cu cu (this_cu);
 
   begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off);
   info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile,
@@ -8090,7 +8047,6 @@  init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
   if (info_ptr >= begin_info_ptr + this_cu->length
       || peek_abbrev_code (abfd, info_ptr) == 0)
     {
-      do_cleanups (cleanups);
       return;
     }
 
@@ -8102,8 +8058,6 @@  init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
   info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children);
 
   die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
-
-  do_cleanups (cleanups);
 }
 
 /* Read a CU/TU, except that this does not look for DW_AT_GNU_dwo_name and
@@ -25119,13 +25073,24 @@  dwarf2_find_containing_comp_unit (sect_offset sect_off,
 
 /* Initialize dwarf2_cu CU, owned by PER_CU.  */
 
-static void
-init_one_comp_unit (struct dwarf2_cu *cu, struct dwarf2_per_cu_data *per_cu)
+dwarf2_cu::dwarf2_cu (struct dwarf2_per_cu_data *per_cu_)
+  : per_cu (per_cu_),
+    mark (0),
+    has_loclist (0),
+    checked_producer (0),
+    producer_is_gxx_lt_4_6 (0),
+    producer_is_gcc_lt_4_3 (0),
+    producer_is_icc_lt_14 (0),
+    processing_has_namespace_info (0)
 {
-  memset (cu, 0, sizeof (*cu));
-  per_cu->cu = cu;
-  cu->per_cu = per_cu;
-  obstack_init (&cu->comp_unit_obstack);
+  per_cu->cu = this;
+}
+
+/* Destroy a dwarf2_cu.  */
+
+dwarf2_cu::~dwarf2_cu ()
+{
+  per_cu->cu = NULL;
 }
 
 /* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE.  */
@@ -25149,43 +25114,6 @@  prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
   cu->producer = dwarf2_string_attr (comp_unit_die, DW_AT_producer, cu);
 }
 
-/* Release one cached compilation unit, CU.  We unlink it from the tree
-   of compilation units, but we don't remove it from the read_in_chain;
-   the caller is responsible for that.
-   NOTE: DATA is a void * because this function is also used as a
-   cleanup routine.  */
-
-static void
-free_heap_comp_unit (void *data)
-{
-  struct dwarf2_cu *cu = (struct dwarf2_cu *) data;
-
-  gdb_assert (cu->per_cu != NULL);
-  cu->per_cu->cu = NULL;
-  cu->per_cu = NULL;
-
-  obstack_free (&cu->comp_unit_obstack, NULL);
-
-  xfree (cu);
-}
-
-/* This cleanup function is passed the address of a dwarf2_cu on the stack
-   when we're finished with it.  We can't free the pointer itself, but be
-   sure to unlink it from the cache.  Also release any associated storage.  */
-
-static void
-free_stack_comp_unit (void *data)
-{
-  struct dwarf2_cu *cu = (struct dwarf2_cu *) data;
-
-  gdb_assert (cu->per_cu != NULL);
-  cu->per_cu->cu = NULL;
-  cu->per_cu = NULL;
-
-  obstack_free (&cu->comp_unit_obstack, NULL);
-  cu->partial_dies = NULL;
-}
-
 /* Free all cached compilation units.  */
 
 static void
@@ -25225,7 +25153,7 @@  age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
       if (!per_cu->cu->mark)
 	{
-	  free_heap_comp_unit (per_cu->cu);
+	  delete per_cu->cu;
 	  *last_chain = next_cu;
 	}
       else
@@ -25254,7 +25182,7 @@  free_one_cached_comp_unit (struct dwarf2_per_cu_data *target_per_cu)
 
       if (per_cu == target_per_cu)
 	{
-	  free_heap_comp_unit (per_cu->cu);
+	  delete per_cu->cu;
 	  per_cu->cu = NULL;
 	  *last_chain = next_cu;
 	  break;